javascript - initiate a number of vertices/triangles for vertex shader to use -
i've been playing around vertexshaderart.com , i'd use learned on separate website. while have used shaders before, effects achieved on site depend on having access vertices/lines/triangles. while passing vertices easy enough (at least three.js, though kind of overkill simple shaders, in cases in need shader materials too), creating triangles seems bit more complex.
i can't figure out source, how triangles created there, when switch mode here?
i'd replicate behavior have no idea how approach it. create number of triangles through 3 many individual objects performance takes hit rapidly. triangles created here separate entities or part of 1 geometry?
vertexshaderart.com more of puzzle, toy, art box, creative coding experiment example of webgl. same true of shadertoy.com. example like this beautiful runs @ 20fps in it's tiny window , 1fps fullscreen on 2014 macbook pro , yet mbp can play beautiful games huge worlds rendered fullscreen @ 60fps. in other words, techniques more art/fun/play/mental exercise , fun of trying make things happen extreme limits techniques.
the point i'm trying make both vertexshaderart , shadertoy fun impractical.
the way vertexshaderart works provides count vertexid
counts vertices. 0 n n count setting top of ui. each count output gl_position
, v_color
(color).
so, if want draw need provide math generate vertex positions based on count. example let's using canvas 2d first
here's fake javascript vertex shader written in javascript given nothing vertexid
draw grid 1 unit high , n units long n = number of vertices (vertexcount
) / 6.
function ourpseudovertexshader(vertexid, time) { // let's compute infinite grid of points based off vertexid var x = math.floor(vertexid / 6) + (vertexid % 2); var y = (math.floor(vertexid / 2) + math.floor(vertexid / 3)) % 2; // color every other triangle red or green var triangleid = math.floor(vertexid / 3); var color = triangleid % 2 ? "#f00" : "#0f0"; return { x: x * 0.2, y: y * 0.2, color: color, }; }
we call loop supplying vertexid
(var count = 0; count < vertexcount; count += 3) { // 3 points var position0 = ourpseudovertexshader(count + 0, time); var position1 = ourpseudovertexshader(count + 1, time); var position2 = ourpseudovertexshader(count + 2, time); // draw triangle ctx.beginpath(); ctx.moveto(position0.x, position0.y); ctx.lineto(position1.x, position1.y); ctx.lineto(position2.x, position2.y); ctx.fillstyle = position0.color; ctx.fill(); }
if run here you'll see grid 1 unit high , n units long. i've set canvas origin 0,0 in center webgl , canvas addressed +1 -1 across , +1 -1 down
var vertexcount = 100; function ourpseudovertexshader(vertexid, time) { // let's compute infinite grid of points based off vertexid var x = math.floor(vertexid / 6) + (vertexid % 2); var y = (math.floor(vertexid / 2) + math.floor(vertexid / 3)) % 2; // color every other triangle red or green var triangleid = math.floor(vertexid / 3); var color = triangleid % 2 ? "#f00" : "#0f0"; return { x: x * 0.2, y: y * 0.2, color: color, }; } var ctx = document.queryselector("canvas").getcontext("2d"); requestanimationframe(render); function render(time) { time *= 0.001; ctx.clearrect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.save(); ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2); ctx.scale(ctx.canvas.width / 2, -ctx.canvas.height / 2); // lets assume triangles (var count = 0; count < vertexcount; count += 3) { // 3 points var position0 = ourpseudovertexshader(count + 0, time); var position1 = ourpseudovertexshader(count + 1, time); var position2 = ourpseudovertexshader(count + 2, time); // draw triangle ctx.beginpath(); ctx.moveto(position0.x, position0.y); ctx.lineto(position1.x, position1.y); ctx.lineto(position2.x, position2.y); ctx.fillstyle = position0.color; ctx.fill(); } ctx.restore(); requestanimationframe(render); }
canvas { border: 1px solid black; }
<canvas width="500" height="200"></canvas>
doing same thing in webgl means making buffer count
var count = []; (var = 0; < vertexcount; ++i) { count.push(i); }
then putting count in buffer , using attribute shader.
here's equivalent shader fake shader above
attribute float vertexid; uniform float time; varying vec4 v_color; void main() { // let's compute infinite grid of points based off vertexid float x = floor(vertexid / 6.) + mod(vertexid, 2.); float y = mod(floor(vertexid / 2.) + floor(vertexid / 3.), 2.); // color every other triangle red or green float triangleid = floor(vertexid / 3.); v_color = mix(vec4(0, 1, 0, 1), vec4(1, 0, 0, 1), mod(triangleid, 2.)); gl_position = vec4(x * 0.2, y * 0.2, 0, 1); }
if run we'll same result
var vs = ` attribute float vertexid; uniform float vertexcount; uniform float time; varying vec4 v_color; void main() { // let's compute infinite grid of points based off vertexid float x = floor(vertexid / 6.) + mod(vertexid, 2.); float y = mod(floor(vertexid / 2.) + floor(vertexid / 3.), 2.); // color every other triangle red or green float triangleid = floor(vertexid / 3.); v_color = mix(vec4(0, 1, 0, 1), vec4(1, 0, 0, 1), mod(triangleid, 2.)); gl_position = vec4(x * 0.2, y * 0.2, 0, 1); } `; var fs = ` precision mediump float; varying vec4 v_color; void main() { gl_fragcolor = v_color; } `; var vertexcount = 100; var gl = document.queryselector("canvas").getcontext("webgl"); var count = []; (var = 0; < vertexcount; ++i) { count.push(i); } var bufferinfo = twgl.createbufferinfofromarrays(gl, { vertexid: { numcomponents: 1, data: count, }, }); var programinfo = twgl.createprograminfo(gl, [vs, fs]); var uniforms = { time: 0, vertexcount: vertexcount, }; requestanimationframe(render); function render(time) { uniforms.time = time * 0.001; gl.useprogram(programinfo.program); twgl.setbuffersandattributes(gl, programinfo, bufferinfo); twgl.setuniforms(programinfo, uniforms); twgl.drawbufferinfo(gl, gl.triangles, bufferinfo); requestanimationframe(render); }
canvas { border: 1px solid black; }
<script src="https://twgljs.org/dist/twgl.min.js"></script> <canvas width="500" height="200"></canvas>
everything else on vertexshartart creative math make interesting patterns. can use time
animation. texture sound data provided.
so, in answer question, when switch modes (triangles/lines/points) on vertexshaderart.com change what's passed gl.drawarrays
(gl.points
, gl.lines
, gl.triangles
). points generated in vertex shader example above.
so leaves question, specific effect trying achieve. can know suggest achieve it. might want ask new question (so answer still matches question above)
Comments
Post a Comment