code wiki / _hdl_build / nx_gpu_render.nx
nx_gpu_render.nx source
↩ module page · 50 lines · 7203 B
1// nx_gpu_render.nx -- SOVEREIGN SOTA-render R1: the WebGL2 BEACHHEAD. Emits a self-contained HTML that renders
2// a per-pixel-lit, high-DPI, tonemapped 3D sphere on the GPU via the browser's STANDARD WebGL2 API -- ZERO
3// 3rd-party libraries (our own mat4, our own sphere generator, our own GLSL). Runs on Chrome/Edge/Firefox/
4// Safari AND on the Nishi browser/OS; feature-detects WebGL2 and degrades to a message pointing at the
5// sovereign soft-raster surfaces. This proves GPU rendering is in play, sovereignly, cross-browser -- the
6// unlock the render census named. usage: nx_gpu_render <out.html>. license_tier: ORIGINAL
7import "nx_syscalls.nx"
8
9func hw(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
10
11func main(argc: i64, argv: *i64) -> i64 {
12 var outp: *u8 = "knowledge/gpulab.html\x00" as *u8
13 if argc >= 2 { outp = argv[1] as *u8 }
14 let fd: i64 = sys_openat_wr(outp, 0x1a4)
15 if fd < 0 { hw(2, "nx_gpu_render: open failed\n" as *u8); return 1 }
16
17 hw(fd, "<!doctype html><html><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'><title>Nishi GPU Lab -- sovereign WebGL2, no libraries</title><style>html,body{margin:0;height:100%;background:#0a0c12;overflow:hidden}canvas{width:100vw;height:100vh;display:block}#hud{position:fixed;top:8px;left:0;right:0;text-align:center;color:#8ef;font:13px sans-serif;text-shadow:0 1px 2px #000;pointer-events:none}</style></head><body><canvas id='c'></canvas><div id='hud'></div><script>\n" as *u8)
18 // diag + context (feature-detected)
19 hw(fd, "const cv=document.getElementById('c');function diag(m){document.getElementById('hud').textContent=m;}\n" as *u8)
20 hw(fd, "const gl=cv.getContext('webgl2',{antialias:true});\n" as *u8)
21 hw(fd, "if(!gl){diag('No WebGL2 here -- the SOVEREIGN Nishi soft-raster tier is the fallback: our own code, zero GPU, zero libs (see /charlab, /physlab). On NishiOS/Nishi-browser the sovereign GPU path takes this slot.');}else{\n" as *u8)
22 // DEVICE-ADAPTIVE QUALITY: pick the highest quality the device can carry (mobile vs desktop). This is the
23 // "highest graphics for the system/output available" selector for the browser-compat tier.
24 hw(fd, "const mob=/Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent||'');const QDPR=mob?1.5:2;const SEG=mob?48:80;\n" as *u8)
25 hw(fd, "const DPR=Math.min(window.devicePixelRatio||1,QDPR);function resize(){cv.width=Math.floor(innerWidth*DPR);cv.height=Math.floor(innerHeight*DPR);gl.viewport(0,0,cv.width,cv.height);}addEventListener('resize',resize);resize();\n" as *u8)
26 // our own mat4 (column-major) -- NO library
27 hw(fd, "function m4mul(a,b){const o=new Array(16);for(let c=0;c<4;c++)for(let r=0;r<4;r++){let s=0;for(let k=0;k<4;k++)s+=a[k*4+r]*b[c*4+k];o[c*4+r]=s;}return o;}\n" as *u8)
28 hw(fd, "function m4persp(f,a,n,fa){const t=1/Math.tan(f/2);return[t/a,0,0,0, 0,t,0,0, 0,0,(fa+n)/(n-fa),-1, 0,0,2*fa*n/(n-fa),0];}\n" as *u8)
29 hw(fd, "function m4roty(x){const c=Math.cos(x),s=Math.sin(x);return[c,0,-s,0, 0,1,0,0, s,0,c,0, 0,0,0,1];}\n" as *u8)
30 hw(fd, "function m4trans(x,y,z){return[1,0,0,0, 0,1,0,0, 0,0,1,0, x,y,z,1];}\n" as *u8)
31 // our own UV sphere -- NO library
32 hw(fd, "function sphere(seg){const P=[],N=[],I=[];for(let y=0;y<=seg;y++){const ph=(y/seg)*Math.PI;for(let x=0;x<=seg;x++){const th=(x/seg)*2*Math.PI;const nx=Math.sin(ph)*Math.cos(th),ny=Math.cos(ph),nz=Math.sin(ph)*Math.sin(th);P.push(nx,ny,nz);N.push(nx,ny,nz);}}for(let y=0;y<seg;y++)for(let x=0;x<seg;x++){const a=y*(seg+1)+x,b=a+seg+1;I.push(a,b,a+1,b,b+1,a+1);}return{P:new Float32Array(P),N:new Float32Array(N),I:new Uint16Array(I)};}\n" as *u8)
33 // our own GLSL shaders (per-pixel Phong + rim + curvature-AO + ACES-ish tonemap + gamma)
34 hw(fd, "const VS='#version 300 es\\nin vec3 p;in vec3 n;uniform mat4 mvp;uniform mat4 model;out vec3 wn;out vec3 wp;void main(){wn=mat3(model)*n;wp=(model*vec4(p,1.0)).xyz;gl_Position=mvp*vec4(p,1.0);}';\n" as *u8)
35 hw(fd, "const FS='#version 300 es\\nprecision highp float;in vec3 wn;in vec3 wp;out vec4 o;uniform vec3 cam;uniform vec3 base;void main(){vec3 N=normalize(wn);vec3 L=normalize(vec3(0.6,0.85,0.5));vec3 V=normalize(cam-wp);float diff=max(dot(N,L),0.0);vec3 H=normalize(L+V);float spec=pow(max(dot(N,H),0.0),42.0)*0.35;float rim=pow(1.0-max(dot(N,V),0.0),3.0)*0.35;float ao=0.55+0.45*N.y;vec3 col=base*(0.16+0.95*diff)*ao+vec3(1.0)*spec+vec3(0.4,0.6,1.0)*rim;col=col/(col+vec3(1.0));col=pow(col,vec3(1.0/2.2));o=vec4(col,1.0);}';\n" as *u8)
36 hw(fd, "function sh(ty,src){const o=gl.createShader(ty);gl.shaderSource(o,src);gl.compileShader(o);if(!gl.getShaderParameter(o,gl.COMPILE_STATUS)){diag('shader error: '+gl.getShaderInfoLog(o));}return o;}\n" as *u8)
37 hw(fd, "const pr=gl.createProgram();gl.attachShader(pr,sh(gl.VERTEX_SHADER,VS));gl.attachShader(pr,sh(gl.FRAGMENT_SHADER,FS));gl.linkProgram(pr);gl.useProgram(pr);\n" as *u8)
38 hw(fd, "const M=sphere(SEG);const vao=gl.createVertexArray();gl.bindVertexArray(vao);\n" as *u8)
39 hw(fd, "const pb=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,pb);gl.bufferData(gl.ARRAY_BUFFER,M.P,gl.STATIC_DRAW);const pl=gl.getAttribLocation(pr,'p');gl.enableVertexAttribArray(pl);gl.vertexAttribPointer(pl,3,gl.FLOAT,false,0,0);\n" as *u8)
40 hw(fd, "const nb=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,nb);gl.bufferData(gl.ARRAY_BUFFER,M.N,gl.STATIC_DRAW);const nl=gl.getAttribLocation(pr,'n');gl.enableVertexAttribArray(nl);gl.vertexAttribPointer(nl,3,gl.FLOAT,false,0,0);\n" as *u8)
41 hw(fd, "const ib=gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,ib);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,M.I,gl.STATIC_DRAW);gl.enable(gl.DEPTH_TEST);\n" as *u8)
42 hw(fd, "const uMvp=gl.getUniformLocation(pr,'mvp'),uModel=gl.getUniformLocation(pr,'model'),uCam=gl.getUniformLocation(pr,'cam'),uBase=gl.getUniformLocation(pr,'base');\n" as *u8)
43 hw(fd, "let t0=performance.now(),frames=0;\n" as *u8)
44 hw(fd, "function frame(){const t=(performance.now()-t0)/1000;gl.clearColor(0.04,0.05,0.07,1);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);const asp=cv.width/cv.height;const proj=m4persp(1.1,asp,0.1,50.0);const view=m4trans(0,0,-3.2);const model=m4roty(t*0.6);const mvp=m4mul(m4mul(proj,view),model);gl.uniformMatrix4fv(uMvp,false,new Float32Array(mvp));gl.uniformMatrix4fv(uModel,false,new Float32Array(model));gl.uniform3f(uCam,0,0,3.2);gl.uniform3f(uBase,0.86,0.56,0.44);gl.drawElements(gl.TRIANGLES,M.I.length,gl.UNSIGNED_SHORT,0);frames++;if(frames%120===1){diag('Nishi GPU Lab -- WebGL2 compat tier (our shaders+geometry, ZERO libs) on '+(mob?'MOBILE':'DESKTOP')+' -- '+Math.round(frames/((performance.now()-t0)/1000))+' fps @ '+cv.width+'x'+cv.height+'. Sovereign tiers: soft-raster (any device) + own-GPU-on-silicon (NishiOS/electronics).');}requestAnimationFrame(frame);}\n" as *u8)
45 hw(fd, "diag('Nishi GPU Lab -- initializing sovereign WebGL2 renderer (no libraries)...');frame();\n" as *u8)
46 hw(fd, "}\n</script></body></html>\n" as *u8)
47 sys_close(fd)
48 hw(1, "nx_gpu_render: wrote sovereign WebGL2 gpulab.html (no libs, feature-detected)\n" as *u8)
49 return 0
50}