seems good
This commit is contained in:
parent
a9cb149999
commit
d1e95047fc
14 changed files with 110 additions and 402 deletions
|
@ -9,7 +9,7 @@ https://art.mekanoe.com
|
||||||
## Artworks
|
## Artworks
|
||||||
|
|
||||||
- [./001-platform-provenance](https://art.mekanoe.com/001-platform-provenance)
|
- [./001-platform-provenance](https://art.mekanoe.com/001-platform-provenance)
|
||||||
- [./002-enter-the-third](https://art.mekanoe.com/002-enter-the-third)
|
- [./002-webgpu-instead](https://art.mekanoe.com/002-webgpu-instead)
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
|
5
build.ts
5
build.ts
|
@ -16,6 +16,11 @@ await Bun.build({
|
||||||
entrypoints: works,
|
entrypoints: works,
|
||||||
outdir: "html",
|
outdir: "html",
|
||||||
splitting: true,
|
splitting: true,
|
||||||
|
loader: {
|
||||||
|
".glsl": "text",
|
||||||
|
".wgsl": "text",
|
||||||
|
},
|
||||||
|
minify: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(chalk.green`>> Generating HTML and Markdown ...`);
|
console.log(chalk.green`>> Generating HTML and Markdown ...`);
|
||||||
|
|
|
@ -1,62 +1,49 @@
|
||||||
import {
|
class Y{constructor(C){this.gl=C.gl,this.app=C,this.program=this.gl.createProgram()}attach(C,R){console.log("attaching shader",{type:C,source:R});const q=this.gl.createShader(C);if(this.gl.shaderSource(q,R),this.gl.compileShader(q),!this.gl.getShaderParameter(q,this.gl.COMPILE_STATUS))throw new Error("An error occurred compiling the shaders: "+this.gl.getShaderInfoLog(q));return this.gl.attachShader(this.program,q),this}link(){if(this.gl.linkProgram(this.program),!this.gl.getProgramParameter(this.program,this.gl.LINK_STATUS))throw new Error("Unable to initialize the shader program: "+this.gl.getProgramInfoLog(this.program));return console.log("shader linked"),this}location(C){if(C[0]==="a")return this.gl.getAttribLocation(this.program,C);else if(C[0]==="u")return this.gl.getUniformLocation(this.program,C)}updateTime(){const C=this.app.now(),R=Math.sin(C),q=Math.cos(C);this.gl.uniform1f(this.location("uTime"),C),this.gl.uniform1f(this.location("uSinTime"),R),this.gl.uniform1f(this.location("uCosTime"),q)}activate(C,R){this.gl.useProgram(this.program),this.gl.uniformMatrix4fv(this.location("uProjectionMatrix"),!1,C),this.gl.uniformMatrix4fv(this.location("uModelViewMatrix"),!1,R),this.updateTime()}}class _{constructor(C){this.gl=C.gl,this.app=C,this.vertexPositions=new Float32Array([]),this.positionBuffer=null,this.textureBuffer=null}initBuffer(C,R=this.gl.STATIC_DRAW){const q=this.gl.createBuffer();return this.gl.bindBuffer(this.gl.ARRAY_BUFFER,q),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(C),R),q}attachShader(C){return this.shader=C,this.vertexPosition=C.location("aVertexPosition"),this.textureCoord=C.location("aTextureCoord"),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.gl.vertexAttribPointer(this.vertexPosition,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.vertexPosition),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.textureBuffer),this.gl.vertexAttribPointer(this.textureCoord,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.textureCoord),this}draw2D(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.shader.activate(this.app.projectionMatrix,this.app.modelViewMatrix),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,this.vertexPositions.length/2)}draw3D(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.shader.activate(this.app.projectionMatrix,this.app.modelViewMatrix),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,this.vertexPositions.length/3)}}class k extends _{constructor(C){super(C);this.vertexPositions=new Float32Array([-1,-1,1,-1,-1,1,1,1]),this.positionBuffer=this.initBuffer(this.vertexPositions),this.textureBuffer=this.initBuffer(new Float32Array([0,0,1,0,0,1,1,1])),this.app.onUpdate(()=>this.draw2D())}}class B{constructor(C,R="#telemetry"){if(this.app=C,this.el=document.querySelector(R),this.el&&location.search.includes("telemetry"))this.el.style.display="block",this.app.onAfterUpdate(()=>this.onAfterUpdate());this.frameTimes=[],this.maxFrameTimes=100,this.lastFrameTime=0}insertTime(C){if(this.frameTimes.push(C),this.frameTimes.length>this.maxFrameTimes)this.frameTimes.shift()}onAfterUpdate(){const C=this.app.now()-this.lastFrameTime;this.insertTime(C);const R=this.frameTimes.reduce((I,K)=>I+K,0)/this.frameTimes.length,q=1000/R;this.el.innerHTML=`
|
||||||
App,
|
${q.toFixed(1)} FPS (${R.toFixed(3)} ms)<br />
|
||||||
BasicPlane,
|
bU: ${this.app.registry.onBeforeUpdate.length} | U: ${this.app.registry.onUpdate.length} | aU: ${this.app.registry.onAfterUpdate.length}
|
||||||
Shader
|
`,this.lastFrameTime=this.app.now()}}class E{constructor(C={fov:45}){if(this._now=0,this.registry={onStart:[],onUpdate:[],onBeforeUpdate:[],onAfterUpdate:[]},this.config=C,this.canvas=document.querySelector("canvas"),this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight,this.gl=this.canvas.getContext("webgl2"),this.gl===null)throw document.querySelector("main").innerHTML="<div><i>your browser didn't let me set up webgl</i></div>",new Error("Unable to initialize WebGL. Your browser or machine may not support it.");const R=this.gl,q=this.config.fov*Math.PI/180,I=R.canvas.clientWidth/R.canvas.clientHeight,K=0.1,P=100,G=glMatrix.mat4.create();glMatrix.mat4.perspective(G,q,I,K,P);const U=glMatrix.mat4.create();glMatrix.mat4.translate(U,U,[-0,0,-6]),this.projectionMatrix=G,this.modelViewMatrix=U,this.clear(),this.onBeforeUpdate(()=>this.clear()),this.telemetry=new B(this)}clear(){const C=this.gl;C.clearColor(0,0,0,1),C.clearDepth(1),C.enable(C.DEPTH_TEST),C.depthFunc(C.LEQUAL),C.clear(C.COLOR_BUFFER_BIT|C.DEPTH_BUFFER_BIT)}onStart(C){this.registry.onStart.push(C)}onUpdate(C){this.registry.onUpdate.push(C)}onBeforeUpdate(C){this.registry.onBeforeUpdate.push(C)}onAfterUpdate(C){this.registry.onAfterUpdate.push(C)}start(){this.registry.onStart.forEach((C)=>C(this))}update(){this.registry.onBeforeUpdate.forEach((C)=>C(this)),this.registry.onUpdate.forEach((C)=>C(this)),this.registry.onAfterUpdate.forEach((C)=>C(this))}oneShot(){requestAnimationFrame((C)=>{this._now=C,this.start(),this.update()})}loop(){const C=(R)=>{this._now=R,this.update(),requestAnimationFrame(C)};requestAnimationFrame(C)}now(){return this._now}}var H=`precision highp float;
|
||||||
} from "../chunk-2775206da9dea9ea.js";
|
|
||||||
|
|
||||||
// src/001-platform-provenance/main.ts
|
uniform float uTime;
|
||||||
var app2 = new App({ fov: 20 });
|
uniform float uSinTime;
|
||||||
var gl = app2.gl;
|
uniform float uCosTime;
|
||||||
var shader2 = new Shader(app2).attach(gl.VERTEX_SHADER, `
|
|
||||||
attribute vec4 aVertexPosition;
|
|
||||||
attribute vec2 aTextureCoord;
|
|
||||||
|
|
||||||
uniform mat4 uModelViewMatrix;
|
|
||||||
uniform mat4 uProjectionMatrix;
|
|
||||||
|
|
||||||
varying highp vec2 vTextureCoord;
|
varying highp vec2 vTextureCoord;
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
|
|
||||||
vTextureCoord = aTextureCoord;
|
|
||||||
}
|
|
||||||
`).attach(gl.FRAGMENT_SHADER, `
|
|
||||||
precision highp float;
|
|
||||||
|
|
||||||
uniform float uTime;
|
vec3 rgb2hsv(vec3 c) {
|
||||||
uniform float uSinTime;
|
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||||
uniform float uCosTime;
|
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||||
|
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||||
|
|
||||||
varying highp vec2 vTextureCoord;
|
float d = q.x - min(q.w, q.y);
|
||||||
|
float e = 1.0e-10;
|
||||||
|
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||||
|
}
|
||||||
|
|
||||||
vec3 rgb2hsv(vec3 c) {
|
vec3 hsv2rgb(vec3 c) {
|
||||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||||
|
}
|
||||||
|
|
||||||
float d = q.x - min(q.w, q.y);
|
void main() {
|
||||||
float e = 1.0e-10;
|
float zComponent = uSinTime * 0.001 * 0.5 + 0.5;
|
||||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
vec3 hsv = rgb2hsv(vec3(vTextureCoord, zComponent));
|
||||||
}
|
hsv.x += uTime * 0.0001;
|
||||||
|
hsv.y = 1.0;
|
||||||
|
hsv.z = 1.0;
|
||||||
|
vec3 rgb = hsv2rgb(hsv);
|
||||||
|
|
||||||
vec3 hsv2rgb(vec3 c) {
|
gl_FragColor = vec4(rgb, 1.0);
|
||||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
gl_FragColor = clamp(gl_FragColor, 0.0, 1.0);
|
||||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
}`;var J=`attribute vec4 aVertexPosition;
|
||||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
attribute vec2 aTextureCoord;
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
uniform mat4 uModelViewMatrix;
|
||||||
float zComponent = uSinTime * 0.001 * 0.5 + 0.5;
|
uniform mat4 uProjectionMatrix;
|
||||||
vec3 hsv = rgb2hsv(vec3(vTextureCoord, zComponent));
|
|
||||||
hsv.x += uTime * 0.0001;
|
|
||||||
hsv.y = 1.0;
|
|
||||||
hsv.z = 1.0;
|
|
||||||
vec3 rgb = hsv2rgb(hsv);
|
|
||||||
|
|
||||||
gl_FragColor = vec4(rgb, 1.0);
|
varying highp vec2 vTextureCoord;
|
||||||
gl_FragColor = clamp(gl_FragColor, 0.0, 1.0);
|
|
||||||
}
|
void main() {
|
||||||
`).link();
|
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
|
||||||
var plane = new BasicPlane(app2);
|
vTextureCoord = aTextureCoord;
|
||||||
plane.attachShader(shader2);
|
}`;var D=new E({fov:20}),L=D.gl,X=new Y(D).attach(L.VERTEX_SHADER,J).attach(L.FRAGMENT_SHADER,H).link(),Z=new k(D);Z.attachShader(X);D.loop();
|
||||||
app2.loop();
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
import {
|
|
||||||
App,
|
|
||||||
BasicPlane,
|
|
||||||
Shader
|
|
||||||
} from "../chunk-2775206da9dea9ea.js";
|
|
||||||
|
|
||||||
// src/002-enter-the-third/main.ts
|
|
||||||
var app2 = new App({ fov: 20 });
|
|
||||||
var gl = app2.gl;
|
|
||||||
var shader2 = new Shader(app2).attach(gl.VERTEX_SHADER, `
|
|
||||||
attribute vec4 aVertexPosition;
|
|
||||||
attribute vec2 aTextureCoord;
|
|
||||||
|
|
||||||
uniform mat4 uModelViewMatrix;
|
|
||||||
uniform mat4 uProjectionMatrix;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
|
|
||||||
}
|
|
||||||
`).attach(gl.FRAGMENT_SHADER, `
|
|
||||||
void main() {
|
|
||||||
gl_FragColor = vec4(1.0);
|
|
||||||
}
|
|
||||||
`).link();
|
|
||||||
var plane = new BasicPlane(app2);
|
|
||||||
plane.attachShader(shader2);
|
|
||||||
app2.loop();
|
|
|
@ -1,6 +1,6 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>com.mekanoe.art // 002-enter-the-third</title>
|
<title>com.mekanoe.art // 002-webgpu-instead</title>
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
|
@ -28,4 +28,4 @@
|
||||||
crossorigin="anonymous"
|
crossorigin="anonymous"
|
||||||
referrerpolicy="no-referrer"
|
referrerpolicy="no-referrer"
|
||||||
></script>
|
></script>
|
||||||
<script src="/002-enter-the-third/main.js" type="module"></script>
|
<script src="/002-webgpu-instead/main.js" type="module"></script>
|
1
html/002-webgpu-instead/main.js
Normal file
1
html/002-webgpu-instead/main.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
var c=void 0;export{c as default};
|
|
@ -1,225 +0,0 @@
|
||||||
// src/shader.js
|
|
||||||
class Shader {
|
|
||||||
constructor(app) {
|
|
||||||
this.gl = app.gl;
|
|
||||||
this.app = app;
|
|
||||||
this.program = this.gl.createProgram();
|
|
||||||
}
|
|
||||||
attach(type, source) {
|
|
||||||
console.log("attaching shader", { type, source });
|
|
||||||
const shader = this.gl.createShader(type);
|
|
||||||
this.gl.shaderSource(shader, source);
|
|
||||||
this.gl.compileShader(shader);
|
|
||||||
if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
|
|
||||||
throw new Error("An error occurred compiling the shaders: " + this.gl.getShaderInfoLog(shader));
|
|
||||||
}
|
|
||||||
this.gl.attachShader(this.program, shader);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
link() {
|
|
||||||
this.gl.linkProgram(this.program);
|
|
||||||
if (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {
|
|
||||||
throw new Error("Unable to initialize the shader program: " + this.gl.getProgramInfoLog(this.program));
|
|
||||||
}
|
|
||||||
console.log("shader linked");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
location(name) {
|
|
||||||
if (name[0] === "a") {
|
|
||||||
return this.gl.getAttribLocation(this.program, name);
|
|
||||||
} else if (name[0] === "u") {
|
|
||||||
return this.gl.getUniformLocation(this.program, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateTime() {
|
|
||||||
const time = this.app.now();
|
|
||||||
const sinTime = Math.sin(time);
|
|
||||||
const cosTime = Math.cos(time);
|
|
||||||
this.gl.uniform1f(this.location("uTime"), time);
|
|
||||||
this.gl.uniform1f(this.location("uSinTime"), sinTime);
|
|
||||||
this.gl.uniform1f(this.location("uCosTime"), cosTime);
|
|
||||||
}
|
|
||||||
activate(projectionMatrix, modelViewMatrix) {
|
|
||||||
this.gl.useProgram(this.program);
|
|
||||||
this.gl.uniformMatrix4fv(this.location("uProjectionMatrix"), false, projectionMatrix);
|
|
||||||
this.gl.uniformMatrix4fv(this.location("uModelViewMatrix"), false, modelViewMatrix);
|
|
||||||
this.updateTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/object.js
|
|
||||||
class Object {
|
|
||||||
constructor(app) {
|
|
||||||
this.gl = app.gl;
|
|
||||||
this.app = app;
|
|
||||||
this.vertexPositions = new Float32Array([]);
|
|
||||||
this.positionBuffer = null;
|
|
||||||
this.textureBuffer = null;
|
|
||||||
}
|
|
||||||
initBuffer(data, draw = this.gl.STATIC_DRAW) {
|
|
||||||
const buffer = this.gl.createBuffer();
|
|
||||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
|
|
||||||
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(data), draw);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
attachShader(shader) {
|
|
||||||
this.shader = shader;
|
|
||||||
this.vertexPosition = shader.location("aVertexPosition");
|
|
||||||
this.textureCoord = shader.location("aTextureCoord");
|
|
||||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
|
|
||||||
this.gl.vertexAttribPointer(this.vertexPosition, 2, this.gl.FLOAT, false, 0, 0);
|
|
||||||
this.gl.enableVertexAttribArray(this.vertexPosition);
|
|
||||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.textureBuffer);
|
|
||||||
this.gl.vertexAttribPointer(this.textureCoord, 2, this.gl.FLOAT, false, 0, 0);
|
|
||||||
this.gl.enableVertexAttribArray(this.textureCoord);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
draw2D() {
|
|
||||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
|
|
||||||
this.shader.activate(this.app.projectionMatrix, this.app.modelViewMatrix);
|
|
||||||
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, this.vertexPositions.length / 2);
|
|
||||||
}
|
|
||||||
draw3D() {
|
|
||||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
|
|
||||||
this.shader.activate(this.app.projectionMatrix, this.app.modelViewMatrix);
|
|
||||||
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, this.vertexPositions.length / 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/basic-plane.js
|
|
||||||
class BasicPlane extends Object {
|
|
||||||
constructor(app) {
|
|
||||||
super(app);
|
|
||||||
this.vertexPositions = new Float32Array([
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
1,
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1
|
|
||||||
]);
|
|
||||||
this.positionBuffer = this.initBuffer(this.vertexPositions);
|
|
||||||
this.textureBuffer = this.initBuffer(new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]));
|
|
||||||
this.app.onUpdate(() => this.draw2D());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/telemetry.js
|
|
||||||
class Telemetry {
|
|
||||||
constructor(app, selector = "#telemetry") {
|
|
||||||
this.app = app;
|
|
||||||
this.el = document.querySelector(selector);
|
|
||||||
if (this.el && location.search.includes("telemetry")) {
|
|
||||||
this.el.style.display = "block";
|
|
||||||
this.app.onAfterUpdate(() => this.onAfterUpdate());
|
|
||||||
}
|
|
||||||
this.frameTimes = [];
|
|
||||||
this.maxFrameTimes = 100;
|
|
||||||
this.lastFrameTime = 0;
|
|
||||||
}
|
|
||||||
insertTime(time) {
|
|
||||||
this.frameTimes.push(time);
|
|
||||||
if (this.frameTimes.length > this.maxFrameTimes) {
|
|
||||||
this.frameTimes.shift();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onAfterUpdate() {
|
|
||||||
const frameTime = this.app.now() - this.lastFrameTime;
|
|
||||||
this.insertTime(frameTime);
|
|
||||||
const averageFrameTime = this.frameTimes.reduce((a, b) => a + b, 0) / this.frameTimes.length;
|
|
||||||
const framesPerSecond = 1000 / averageFrameTime;
|
|
||||||
this.el.innerHTML = `
|
|
||||||
${framesPerSecond.toFixed(1)} FPS (${averageFrameTime.toFixed(3)} ms)<br />
|
|
||||||
bU: ${this.app.registry.onBeforeUpdate.length} | U: ${this.app.registry.onUpdate.length} | aU: ${this.app.registry.onAfterUpdate.length}
|
|
||||||
`;
|
|
||||||
this.lastFrameTime = this.app.now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/app.js
|
|
||||||
class App {
|
|
||||||
constructor(config = {
|
|
||||||
fov: 45
|
|
||||||
}) {
|
|
||||||
this._now = 0;
|
|
||||||
this.registry = {
|
|
||||||
onStart: [],
|
|
||||||
onUpdate: [],
|
|
||||||
onBeforeUpdate: [],
|
|
||||||
onAfterUpdate: []
|
|
||||||
};
|
|
||||||
this.config = config;
|
|
||||||
this.canvas = document.querySelector("canvas");
|
|
||||||
this.canvas.width = window.innerWidth;
|
|
||||||
this.canvas.height = window.innerHeight;
|
|
||||||
this.gl = this.canvas.getContext("webgl2");
|
|
||||||
if (this.gl === null) {
|
|
||||||
document.querySelector("main").innerHTML = `<div><i>your browser didn't let me set up webgl</i></div>`;
|
|
||||||
throw new Error("Unable to initialize WebGL. Your browser or machine may not support it.");
|
|
||||||
}
|
|
||||||
const gl = this.gl;
|
|
||||||
const fieldOfView = this.config.fov * Math.PI / 180;
|
|
||||||
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
|
|
||||||
const zNear = 0.1;
|
|
||||||
const zFar = 100;
|
|
||||||
const projectionMatrix = glMatrix.mat4.create();
|
|
||||||
glMatrix.mat4.perspective(projectionMatrix, fieldOfView, aspect, zNear, zFar);
|
|
||||||
const modelViewMatrix = glMatrix.mat4.create();
|
|
||||||
glMatrix.mat4.translate(modelViewMatrix, modelViewMatrix, [-0, 0, -6]);
|
|
||||||
this.projectionMatrix = projectionMatrix;
|
|
||||||
this.modelViewMatrix = modelViewMatrix;
|
|
||||||
this.clear();
|
|
||||||
this.onBeforeUpdate(() => this.clear());
|
|
||||||
this.telemetry = new Telemetry(this);
|
|
||||||
}
|
|
||||||
clear() {
|
|
||||||
const gl = this.gl;
|
|
||||||
gl.clearColor(0, 0, 0, 1);
|
|
||||||
gl.clearDepth(1);
|
|
||||||
gl.enable(gl.DEPTH_TEST);
|
|
||||||
gl.depthFunc(gl.LEQUAL);
|
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
||||||
}
|
|
||||||
onStart(fn) {
|
|
||||||
this.registry.onStart.push(fn);
|
|
||||||
}
|
|
||||||
onUpdate(fn) {
|
|
||||||
this.registry.onUpdate.push(fn);
|
|
||||||
}
|
|
||||||
onBeforeUpdate(fn) {
|
|
||||||
this.registry.onBeforeUpdate.push(fn);
|
|
||||||
}
|
|
||||||
onAfterUpdate(fn) {
|
|
||||||
this.registry.onAfterUpdate.push(fn);
|
|
||||||
}
|
|
||||||
start() {
|
|
||||||
this.registry.onStart.forEach((fn) => fn(this));
|
|
||||||
}
|
|
||||||
update() {
|
|
||||||
this.registry.onBeforeUpdate.forEach((fn) => fn(this));
|
|
||||||
this.registry.onUpdate.forEach((fn) => fn(this));
|
|
||||||
this.registry.onAfterUpdate.forEach((fn) => fn(this));
|
|
||||||
}
|
|
||||||
oneShot() {
|
|
||||||
requestAnimationFrame((now) => {
|
|
||||||
this._now = now;
|
|
||||||
this.start();
|
|
||||||
this.update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
loop() {
|
|
||||||
const run = (now) => {
|
|
||||||
this._now = now;
|
|
||||||
this.update();
|
|
||||||
requestAnimationFrame(run);
|
|
||||||
};
|
|
||||||
requestAnimationFrame(run);
|
|
||||||
}
|
|
||||||
now() {
|
|
||||||
return this._now;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { Shader, BasicPlane, App };
|
|
|
@ -31,7 +31,7 @@
|
||||||
</header>
|
</header>
|
||||||
<section id="works">
|
<section id="works">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/002-enter-the-third">./002-enter-the-third</a></li>
|
<li><a href="/002-webgpu-instead">./002-webgpu-instead</a></li>
|
||||||
<li><a href="/001-platform-provenance">./001-platform-provenance</a></li>
|
<li><a href="/001-platform-provenance">./001-platform-provenance</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
35
src/001-platform-provenance/fragment.glsl
Normal file
35
src/001-platform-provenance/fragment.glsl
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform float uTime;
|
||||||
|
uniform float uSinTime;
|
||||||
|
uniform float uCosTime;
|
||||||
|
|
||||||
|
varying highp vec2 vTextureCoord;
|
||||||
|
|
||||||
|
vec3 rgb2hsv(vec3 c) {
|
||||||
|
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||||
|
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||||
|
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||||
|
|
||||||
|
float d = q.x - min(q.w, q.y);
|
||||||
|
float e = 1.0e-10;
|
||||||
|
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 hsv2rgb(vec3 c) {
|
||||||
|
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||||
|
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||||
|
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float zComponent = uSinTime * 0.001 * 0.5 + 0.5;
|
||||||
|
vec3 hsv = rgb2hsv(vec3(vTextureCoord, zComponent));
|
||||||
|
hsv.x += uTime * 0.0001;
|
||||||
|
hsv.y = 1.0;
|
||||||
|
hsv.z = 1.0;
|
||||||
|
vec3 rgb = hsv2rgb(hsv);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(rgb, 1.0);
|
||||||
|
gl_FragColor = clamp(gl_FragColor, 0.0, 1.0);
|
||||||
|
}
|
|
@ -1,68 +1,15 @@
|
||||||
import { Shader } from "../shader";
|
import { Shader } from "../shader";
|
||||||
import { BasicPlane } from "../basic-plane";
|
import { BasicPlane } from "../basic-plane";
|
||||||
import { App } from "../app";
|
import { App } from "../app";
|
||||||
|
import fragment from "./fragment.glsl";
|
||||||
|
import vertex from "./vertex.glsl";
|
||||||
|
|
||||||
const app = new App({ fov: 20 });
|
const app = new App({ fov: 20 });
|
||||||
const gl = app.gl;
|
const gl = app.gl;
|
||||||
|
|
||||||
const shader = new Shader(app)
|
const shader = new Shader(app)
|
||||||
.attach(
|
.attach(gl.VERTEX_SHADER, vertex)
|
||||||
gl.VERTEX_SHADER,
|
.attach(gl.FRAGMENT_SHADER, fragment)
|
||||||
`
|
|
||||||
attribute vec4 aVertexPosition;
|
|
||||||
attribute vec2 aTextureCoord;
|
|
||||||
|
|
||||||
uniform mat4 uModelViewMatrix;
|
|
||||||
uniform mat4 uProjectionMatrix;
|
|
||||||
|
|
||||||
varying highp vec2 vTextureCoord;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
|
|
||||||
vTextureCoord = aTextureCoord;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
)
|
|
||||||
.attach(
|
|
||||||
gl.FRAGMENT_SHADER,
|
|
||||||
`
|
|
||||||
precision highp float;
|
|
||||||
|
|
||||||
uniform float uTime;
|
|
||||||
uniform float uSinTime;
|
|
||||||
uniform float uCosTime;
|
|
||||||
|
|
||||||
varying highp vec2 vTextureCoord;
|
|
||||||
|
|
||||||
vec3 rgb2hsv(vec3 c) {
|
|
||||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
|
||||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
|
||||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
|
||||||
|
|
||||||
float d = q.x - min(q.w, q.y);
|
|
||||||
float e = 1.0e-10;
|
|
||||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 hsv2rgb(vec3 c) {
|
|
||||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
||||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
||||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
float zComponent = uSinTime * 0.001 * 0.5 + 0.5;
|
|
||||||
vec3 hsv = rgb2hsv(vec3(vTextureCoord, zComponent));
|
|
||||||
hsv.x += uTime * 0.0001;
|
|
||||||
hsv.y = 1.0;
|
|
||||||
hsv.z = 1.0;
|
|
||||||
vec3 rgb = hsv2rgb(hsv);
|
|
||||||
|
|
||||||
gl_FragColor = vec4(rgb, 1.0);
|
|
||||||
gl_FragColor = clamp(gl_FragColor, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
`
|
|
||||||
)
|
|
||||||
.link();
|
.link();
|
||||||
|
|
||||||
const plane = new BasicPlane(app);
|
const plane = new BasicPlane(app);
|
||||||
|
|
12
src/001-platform-provenance/vertex.glsl
Normal file
12
src/001-platform-provenance/vertex.glsl
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
attribute vec4 aVertexPosition;
|
||||||
|
attribute vec2 aTextureCoord;
|
||||||
|
|
||||||
|
uniform mat4 uModelViewMatrix;
|
||||||
|
uniform mat4 uProjectionMatrix;
|
||||||
|
|
||||||
|
varying highp vec2 vTextureCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
|
||||||
|
vTextureCoord = aTextureCoord;
|
||||||
|
}
|
|
@ -1,36 +0,0 @@
|
||||||
import { Shader } from "../shader";
|
|
||||||
import { BasicPlane } from "../basic-plane";
|
|
||||||
import { App } from "../app";
|
|
||||||
|
|
||||||
const app = new App({ fov: 20 });
|
|
||||||
const gl = app.gl;
|
|
||||||
|
|
||||||
const shader = new Shader(app)
|
|
||||||
.attach(
|
|
||||||
gl.VERTEX_SHADER,
|
|
||||||
`
|
|
||||||
attribute vec4 aVertexPosition;
|
|
||||||
attribute vec2 aTextureCoord;
|
|
||||||
|
|
||||||
uniform mat4 uModelViewMatrix;
|
|
||||||
uniform mat4 uProjectionMatrix;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
)
|
|
||||||
.attach(
|
|
||||||
gl.FRAGMENT_SHADER,
|
|
||||||
`
|
|
||||||
void main() {
|
|
||||||
gl_FragColor = vec4(1.0);
|
|
||||||
}
|
|
||||||
`
|
|
||||||
)
|
|
||||||
.link();
|
|
||||||
|
|
||||||
const plane = new BasicPlane(app);
|
|
||||||
plane.attachShader(shader);
|
|
||||||
|
|
||||||
app.loop();
|
|
0
src/002-webgpu-instead/main.ts
Normal file
0
src/002-webgpu-instead/main.ts
Normal file
9
stuff.d.ts
vendored
Normal file
9
stuff.d.ts
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
declare module "*.glsl" {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "*.wgsl" {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue