diff --git a/README.md b/README.md index d72ad87..af87cb5 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ https://art.mekanoe.com ## Artworks - [./001-platform-provenance](https://art.mekanoe.com/001-platform-provenance) -- [./002-webgpu-instead](https://art.mekanoe.com/002-webgpu-instead) +- [./002-webgl-engine](https://art.mekanoe.com/002-webgl-engine) ## Development diff --git a/bun.lockb b/bun.lockb index d673135..dfa1ae7 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/hack/build.ts b/hack/build.ts index b34486d..309f048 100644 --- a/hack/build.ts +++ b/hack/build.ts @@ -13,19 +13,28 @@ const works = globSync("src/*/main.ts"); console.log(chalk.green`>> Building ...`); console.log(chalk.yellow(` Found ${works.length} works.`)); +console.log(chalk.yellow(` Running Bun.build()`)); -await Bun.build({ +const results = await Bun.build({ entrypoints: works, outdir: "html", splitting: true, loader: { ".glsl": "text", ".wgsl": "text", + ".vert": "text", + ".frag": "text", }, - minify: true, + minify: process.env.MINIFY === "false" ? false : true, plugins: [glslPlugin], }); +if (!results.success) { + console.error(chalk.red("XX Bun.build() Failed.")); + console.error(chalk.red(JSON.stringify(results.logs, null, 2))); + process.exit(1); +} + console.log(chalk.green`>> Generating HTML and Markdown ...`); await generate(works); diff --git a/hack/convert-meshes.ts b/hack/convert-meshes.ts index 17af076..69c90c6 100644 --- a/hack/convert-meshes.ts +++ b/hack/convert-meshes.ts @@ -9,6 +9,16 @@ export const convertMeshes = async () => { const [header, body] = ply.split("end_header"); const colorSize = header.includes("red") ? 4 : 0; + const headerLines = header.split("\n"); + const vertexCount = Number( + headerLines + .find((header) => header.startsWith("element vertex")) + ?.replace("element vertex ", "") + ); + + if (!vertexCount) { + throw new Error("couldn't get vertex count..."); + } const values: number[] = []; @@ -43,13 +53,16 @@ export const convertMeshes = async () => { import { Mesh } from "../renderer/mesh"; // prettier-ignore -const mesh = new Float32Array(${JSON.stringify(values, null, 2)}); +const mesh = new Float32Array(${JSON.stringify(values)}); export default new Mesh({ mesh, - positionSize: 4 * 4, - colorSize: ${colorSize} * 4, - uvSize: 2 * 4, + positionSize: 4, + colorSize: ${colorSize}, + uvSize: 2, + vertexCount: ${vertexCount}, + stride: ${4 + colorSize + 2}, + name: ${JSON.stringify(file)} }); `; diff --git a/hack/glsl-plugin.ts b/hack/glsl-plugin.ts index 133ff84..8e0ed76 100644 --- a/hack/glsl-plugin.ts +++ b/hack/glsl-plugin.ts @@ -1,5 +1,5 @@ import glsl from "esbuild-plugin-glsl"; export default glsl({ - minify: true, + minify: process.env.MINIFY === "false" ? false : true, }); diff --git a/hack/templates/work.html.txt b/hack/templates/work.html.txt index 876b6e9..19ee715 100644 --- a/hack/templates/work.html.txt +++ b/hack/templates/work.html.txt @@ -22,10 +22,4 @@
XX.X FPS (XX.X ms)
- diff --git a/html/001-platform-provenance/index.html b/html/001-platform-provenance/index.html index 3887477..a2be8f8 100644 --- a/html/001-platform-provenance/index.html +++ b/html/001-platform-provenance/index.html @@ -22,10 +22,4 @@
XX.X FPS (XX.X ms)
- diff --git a/html/001-platform-provenance/main.js b/html/001-platform-provenance/main.js index bef0278..77d392a 100644 --- a/html/001-platform-provenance/main.js +++ b/html/001-platform-provenance/main.js @@ -1 +1 @@ -import{b as Y} from"../chunk-818093f0cbbefec3.js";class k{constructor(v){this.gl=v.gl,this.app=v,this.program=this.gl.createProgram()}attach(v,R){console.log("attaching shader",{type:v,source:R});const _=this.gl.createShader(v);if(this.gl.shaderSource(_,R),this.gl.compileShader(_),!this.gl.getShaderParameter(_,this.gl.COMPILE_STATUS))throw new Error("An error occurred compiling the shaders: "+this.gl.getShaderInfoLog(_));return this.gl.attachShader(this.program,_),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(v){if(v[0]==="a")return this.gl.getAttribLocation(this.program,v);else if(v[0]==="u")return this.gl.getUniformLocation(this.program,v)}updateTime(){const v=this.app.now(),R=Math.sin(v),_=Math.cos(v);this.gl.uniform1f(this.location("uTime"),v),this.gl.uniform1f(this.location("uSinTime"),R),this.gl.uniform1f(this.location("uCosTime"),_)}activate(v,R){this.gl.useProgram(this.program),this.gl.uniformMatrix4fv(this.location("uProjectionMatrix"),!1,v),this.gl.uniformMatrix4fv(this.location("uModelViewMatrix"),!1,R),this.updateTime()}}class q{constructor(v){this.gl=v.gl,this.app=v,this.vertexPositions=new Float32Array([]),this.positionBuffer=null,this.textureBuffer=null}initBuffer(v,R=this.gl.STATIC_DRAW){const _=this.gl.createBuffer();return this.gl.bindBuffer(this.gl.ARRAY_BUFFER,_),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(v),R),_}attachShader(v){return this.shader=v,this.vertexPosition=v.location("aVertexPosition"),this.textureCoord=v.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 C extends q{constructor(v){super(v);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 K{constructor(v={fov:45}){if(this._now=0,this.registry={onStart:[],onUpdate:[],onBeforeUpdate:[],onAfterUpdate:[]},this.config=v,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="
your browser didn't let me set up webgl
",new Error("Unable to initialize WebGL. Your browser or machine may not support it.");const R=this.gl,_=this.config.fov*Math.PI/180,H=R.canvas.clientWidth/R.canvas.clientHeight,J=0.1,L=100,X=glMatrix.mat4.create();glMatrix.mat4.perspective(X,_,H,J,L);const I=glMatrix.mat4.create();glMatrix.mat4.translate(I,I,[-0,0,-6]),this.projectionMatrix=X,this.modelViewMatrix=I,this.clear(),this.onBeforeUpdate(()=>this.clear()),this.telemetry=new Y(this)}clear(){const v=this.gl;v.clearColor(0,0,0,1),v.clearDepth(1),v.enable(v.DEPTH_TEST),v.depthFunc(v.LEQUAL),v.clear(v.COLOR_BUFFER_BIT|v.DEPTH_BUFFER_BIT)}onStart(v){this.registry.onStart.push(v)}onUpdate(v){this.registry.onUpdate.push(v)}onBeforeUpdate(v){this.registry.onBeforeUpdate.push(v)}onAfterUpdate(v){this.registry.onAfterUpdate.push(v)}start(){this.registry.onStart.forEach((v)=>v(this))}update(){this.registry.onBeforeUpdate.forEach((v)=>v(this)),this.registry.onUpdate.forEach((v)=>v(this)),this.registry.onAfterUpdate.forEach((v)=>v(this))}oneShot(){requestAnimationFrame((v)=>{this._now=v,this.start(),this.update()})}loop(){const v=(R)=>{this._now=R,this.update(),requestAnimationFrame(v)};requestAnimationFrame(v)}now(){return this._now}}var B="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);}";var E="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;}";var D=new K({fov:20}),G=D.gl,Q=new k(D).attach(G.VERTEX_SHADER,E).attach(G.FRAGMENT_SHADER,B).link(),U=new C(D);U.attachShader(Q);D.loop(); +import{b as X,c as R} from"../chunk-1da54319833c650d.js";class I{constructor(v){this.gl=v.gl,this.app=v,this.program=this.gl.createProgram()}attach(v,_){console.log("attaching shader",{type:v,source:_});const D=this.gl.createShader(v);if(this.gl.shaderSource(D,_),this.gl.compileShader(D),!this.gl.getShaderParameter(D,this.gl.COMPILE_STATUS))throw new Error("An error occurred compiling the shaders: "+this.gl.getShaderInfoLog(D));return this.gl.attachShader(this.program,D),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(v){if(v[0]==="a")return this.gl.getAttribLocation(this.program,v);else if(v[0]==="u")return this.gl.getUniformLocation(this.program,v)}updateTime(){const v=this.app.now(),_=Math.sin(v),D=Math.cos(v);this.gl.uniform1f(this.location("uTime"),v),this.gl.uniform1f(this.location("uSinTime"),_),this.gl.uniform1f(this.location("uCosTime"),D)}activate(v,_){this.gl.useProgram(this.program),this.gl.uniformMatrix4fv(this.location("uProjectionMatrix"),!1,v),this.gl.uniformMatrix4fv(this.location("uModelViewMatrix"),!1,_),this.updateTime()}}class K{constructor(v){this.gl=v.gl,this.app=v,this.vertexPositions=new Float32Array([]),this.positionBuffer=null,this.textureBuffer=null}initBuffer(v,_=this.gl.STATIC_DRAW){const D=this.gl.createBuffer();return this.gl.bindBuffer(this.gl.ARRAY_BUFFER,D),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(v),_),D}attachShader(v){return this.shader=v,this.vertexPosition=v.location("aVertexPosition"),this.textureCoord=v.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 L extends K{constructor(v){super(v);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 P{constructor(v={fov:45}){if(this._now=0,this.registry={onStart:[],onUpdate:[],onBeforeUpdate:[],onAfterUpdate:[]},this.config=v,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="
your browser didn't let me set up webgl
",new Error("Unable to initialize WebGL. Your browser or machine may not support it.");const _=this.gl,D=this.config.fov*Math.PI/180,E=_.canvas.clientWidth/_.canvas.clientHeight,G=0.1,H=100,U=R.create();R.perspective(U,D,E,G,H);const C=R.create();R.translate(C,C,[-0,0,-6]),this.projectionMatrix=U,this.modelViewMatrix=C,this.clear(),this.onBeforeUpdate(()=>this.clear()),this.telemetry=new X(this)}clear(){const v=this.gl;v.clearColor(0,0,0,1),v.clearDepth(1),v.enable(v.DEPTH_TEST),v.depthFunc(v.LEQUAL),v.clear(v.COLOR_BUFFER_BIT|v.DEPTH_BUFFER_BIT)}onStart(v){this.registry.onStart.push(v)}onUpdate(v){this.registry.onUpdate.push(v)}onBeforeUpdate(v){this.registry.onBeforeUpdate.push(v)}onAfterUpdate(v){this.registry.onAfterUpdate.push(v)}start(){this.registry.onStart.forEach((v)=>v(this))}update(){this.registry.onBeforeUpdate.forEach((v)=>v(this)),this.registry.onUpdate.forEach((v)=>v(this)),this.registry.onAfterUpdate.forEach((v)=>v(this))}oneShot(){requestAnimationFrame((v)=>{this._now=v,this.start(),this.update()})}loop(){const v=(_)=>{this._now=_,this.update(),requestAnimationFrame(v)};requestAnimationFrame(v)}now(){return this._now}}var Y="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);}";var q="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;}";var k=new P({fov:20}),B=k.gl,W=new I(k).attach(B.VERTEX_SHADER,q).attach(B.FRAGMENT_SHADER,Y).link(),Z=new L(k);Z.attachShader(W);k.loop(); diff --git a/html/002-webgpu-instead/index.html b/html/002-webgl-engine/index.html similarity index 53% rename from html/002-webgpu-instead/index.html rename to html/002-webgl-engine/index.html index da5bf5d..8c1c287 100644 --- a/html/002-webgpu-instead/index.html +++ b/html/002-webgl-engine/index.html @@ -1,6 +1,6 @@ -com.mekanoe.art // 002-webgpu-instead +com.mekanoe.art // 002-webgl-engine