WebGL rotating F: Difference between revisions

m
m (→‎{{header|J}}: ... use javascript syntax highlight here)
m (→‎{{header|Wren}}: Minor tidy)
 
(6 intermediate revisions by one other user not shown)
Line 22:
wd {{)n
pc webgl; cc w webview;
pmove 0 0 300518 300518;
pshow;
set w html *
Line 40:
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) console.log(gl.getShaderInfoLog(shader));
gl.attachShader(P, shader);
}
Line 57 ⟶ 56:
);
}
const int MAX_MARCHING_STEPS= 100;
const float MIN_DIST= 0.0;
const float MAX_DIST= 100.0;
float sdBox(vec3 position, vec3 box, vec3 offset) {
Line 65 ⟶ 62:
}
float sdScene(vec3 p) { // distance to closest object
float dist= sdBox(p, vec3(1,4,1), vec3(0, -0.35, 0));
dist= min(dist, sdBox(p, vec3(1.5,1,1), vec3(10.75, -0.35, 0)));
return min(dist, sdBox(p, vec3(2.5,1,1), vec3(0.75, 21.35, 0)));
}
float rayMarch(vec3 ro, vec3 rd, float startdepth, float end) {
for (int i= 0; i< 100 /* MAX_MARCHING_STEPS */; i++) {
float depth= start;
for (int i=if 0;(depth i< MAX_MARCHING_STEPS;end) idepth+= sdScene(ro +) {depth * rd);
if (depth < end) {
depth+= sdScene(ro + depth * rd);
}
}
return depth;
Line 93 ⟶ 87:
vec3 ro= vec3(0, 0, 7)*rot; // ray origin that represents camera position
vec3 rd= normalize(vec3(uv, -1)*rot); // ray direction
float sd= rayMarch(ro, rd, 0.0 /* MIN_DIST */, MAX_DIST); // closest object
if (sd > MAX_DIST) {
color= backgroundColor; // ray did notdidn't hit anything
} else {
vec3 p= ro + rd * sd; // point on cube we discovered from ray marching
Line 105 ⟶ 99:
}
gl_FragColor= vec4(color, 1.0);
}`);
`); /* end of FRAGMENT_SHADER */
gl.linkProgram(P);
posNdx= gl.getAttribLocation(P, "pos");
resNdx= gl.getUniformLocation(P, "res");
timeNdx= gl.getUniformLocation(P, "time");
posBuffer= gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer);
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.clearColor(0,0,0,0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(P);
gl.enableVertexAttribArray(posNdx);
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer);
gl.vertexAttribPointer(posNdx, 2, gl.FLOAT, false, 0, 0);
gl.uniform2fvuniform2f(resNdxgl.getUniformLocation(P, "res"), [c.width, c.height]);
requestAnimationFrame(paint);
}
</script>
</head><body onload="run()" style="margin: 0">
<canvas id="c" width=300500 height=300500></canvas>
</body></html>
}}</syntaxhighlight>
}}
 
</syntaxhighlight>
In other words, we construct the letter F using three rectangular blocks near the origin of our coordinate system. And we construct a rectangle covering the screen using triangle strip. Finally, for each pixel on the screen we project a vector representing a potential pixel from our camera position towards the blocks.
 
In ray marching we find the minimum distance from an origin point to any point in the geometric structure, move in the ray direction that distance and repeat (in this case we repeat this operation 100 time for each pixel). After these iterations we have either shot past the geometry or we're within some small epsilon distance from the surface of the object. We can inspect the distance the array has progressed to determine whether we should use background color or surface color. And we can check distances with some minor variations on this ray to determine the orientation of the surface at that point.
 
Finally, to achieve the "rotating" effect, we spin our camera (and light source) so that it rotates around the blocks which form our letter "F", with the camera always facing towards the origin.
 
Tested in J9.03 and a J9.04 beta.
 
See also: https://tinyurl.com/rotatingF for a j-playground variation of this implementation (hit <code>Run</code> in the upper right corner).
 
=={{header|Julia}}==
Line 554 ⟶ 553:
 
As with any Open GL aplication, the Wren code needs to be embedded in a host application which can communicate directly with the relevant libraries and which I've written here in C.
<syntaxhighlight lang="ecmascriptwren">/* webgl_rotating_FWebGL_rotating_F.wren */
 
import "./math" for Math
Line 1,251 ⟶ 1,250:
<br>
We now embed the above code in the following C program, compile and run.
<syntaxhighlight lang="c">/* gcc webgl_rotating_FWebGL_rotating_F.c -o webgl_rotating_FWebGL_rotating_F -lglut -lGLESv2 -lm -lwren */
 
#include <stdlib.h>
Line 1,557 ⟶ 1,556:
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "webgl_rotating_FWebGL_rotating_F.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
9,476

edits