WebGL rotating F: Difference between revisions
Content added Content deleted
m (→{{header|J}}: eliminate a minor visual artifact experienced with some GPUs) |
m (→{{header|J}}: toss some unneeded labels) |
||
Line 22: | Line 22: | ||
wd {{)n |
wd {{)n |
||
pc webgl; cc w webview; |
pc webgl; cc w webview; |
||
pmove 0 0 |
pmove 0 0 518 518; |
||
pshow; |
pshow; |
||
set w html * |
set w html * |
||
Line 56: | Line 56: | ||
); |
); |
||
} |
} |
||
const int MAX_MARCHING_STEPS= 100; |
|||
const float MIN_DIST= 0.0; |
|||
const float MAX_DIST= 100.0; |
const float MAX_DIST= 100.0; |
||
float sdBox(vec3 position, vec3 box, vec3 offset) { |
float sdBox(vec3 position, vec3 box, vec3 offset) { |
||
Line 64: | Line 62: | ||
} |
} |
||
float sdScene(vec3 p) { // distance to closest object |
float sdScene(vec3 p) { // distance to closest object |
||
float dist= sdBox(p, vec3(1,4,1), vec3(0, 0. |
float dist= sdBox(p, vec3(1,4,1), vec3(0, -0.5, 0)); |
||
dist= min(dist, sdBox(p, vec3(1.5,1,1), vec3(0.75, 0. |
dist= min(dist, sdBox(p, vec3(1.5,1,1), vec3(0.75, -0.5, 0))); |
||
return min(dist, sdBox(p, vec3(2.5,1,1), vec3(0.75, |
return min(dist, sdBox(p, vec3(2.5,1,1), vec3(0.75, 1.5, 0))); |
||
} |
} |
||
float rayMarch(vec3 ro, vec3 rd, float |
float rayMarch(vec3 ro, vec3 rd, float depth, float end) { |
||
for (int i= 0; i< 100 /* MAX_MARCHING_STEPS */; i++) { |
|||
float depth= start; |
|||
if (depth < end) depth+= sdScene(ro + depth * rd); |
|||
if (depth < end) { |
|||
depth+= sdScene(ro + depth * rd); |
|||
} |
|||
} |
} |
||
return depth; |
return depth; |
||
Line 92: | Line 87: | ||
vec3 ro= vec3(0, 0, 7)*rot; // ray origin that represents camera position |
vec3 ro= vec3(0, 0, 7)*rot; // ray origin that represents camera position |
||
vec3 rd= normalize(vec3(uv, -1)*rot); // ray direction |
vec3 rd= normalize(vec3(uv, -1)*rot); // ray direction |
||
float sd= rayMarch(ro, rd, MIN_DIST, MAX_DIST); // closest object |
float sd= rayMarch(ro, rd, 0.0 /* MIN_DIST */, MAX_DIST); // closest object |
||
if (sd > MAX_DIST) { |
if (sd > MAX_DIST) { |
||
color= backgroundColor; // ray |
color= backgroundColor; // ray didn't hit anything |
||
} else { |
} else { |
||
vec3 p= ro + rd * sd; // point on cube we discovered from ray marching |
vec3 p= ro + rd * sd; // point on cube we discovered from ray marching |
||
Line 104: | Line 99: | ||
} |
} |
||
gl_FragColor= vec4(color, 1.0); |
gl_FragColor= vec4(color, 1.0); |
||
} |
} |
||
`); /* end of FRAGMENT_SHADER */ |
|||
gl.linkProgram(P); |
gl.linkProgram(P); |
||
posNdx= gl.getAttribLocation(P, "pos"); |
posNdx= gl.getAttribLocation(P, "pos"); |
||
resNdx= gl.getUniformLocation(P, "res"); |
|||
timeNdx= gl.getUniformLocation(P, "time"); |
timeNdx= gl.getUniformLocation(P, "time"); |
||
posBuffer= gl.createBuffer(); |
posBuffer= gl.createBuffer(); |
||
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); |
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); |
||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,-1, |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,-1, -1,1, 1,-1, 1,1]), gl.STATIC_DRAW); |
||
gl.viewport(0,0,c.width,c.height); |
gl.viewport(0,0,c.width,c.height); |
||
gl.clearColor(0,0,0,0); |
|||
gl.clear(gl.COLOR_BUFFER_BIT); |
|||
gl.useProgram(P); |
gl.useProgram(P); |
||
gl.enableVertexAttribArray(posNdx); |
gl.enableVertexAttribArray(posNdx); |
||
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); |
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); |
||
gl.vertexAttribPointer(posNdx, 2, gl.FLOAT, false, 0, 0); |
gl.vertexAttribPointer(posNdx, 2, gl.FLOAT, false, 0, 0); |
||
gl. |
gl.uniform2f(gl.getUniformLocation(P, "res"), c.width, c.height); |
||
requestAnimationFrame(paint); |
requestAnimationFrame(paint); |
||
} |
} |
||
</script> |
</script> |
||
</head><body onload="run()" style="margin: 0"> |
</head><body onload="run()" style="margin: 0"> |
||
<canvas id="c" width= |
<canvas id="c" width=500 height=500></canvas> |
||
</body></html> |
</body></html> |
||
⚫ | |||
}} |
|||
⚫ | |||
Tested in J9.03 and a J9.04 beta. |
Tested in J9.03 and a J9.04 beta. |