简体   繁体   English

WebGL重置顶点位置

[英]WebGL Resetting vertex positions

I am creating a simple webgl program that puts 3 random vertices on the canvas and connects them into a triangle. 我正在创建一个简单的webgl程序,该程序将3个随机顶点放在画布上,并将它们连接成三角形。 I tried to add translation to move the triangle to the right (increase the X value of each vertex), but of course if it goes forever, the triangle will go out of the canvas. 我尝试添加平移以将三角形向右移动(增加每个顶点的X值),但是当然,如​​果永远消失,三角形将从画布中消失。 Does anyone know how to detect if the vertex has an x value above 1 and if yes, reset the position of the given vertex because my solution doesnt seem to do anything, its like it doesnt even trigger 有谁知道如何检测顶点的x值是否大于1,如果是,请重置给定顶点的位置,因为我的解决方案似乎什么也没做,就像它甚至不会触发一样

 var canvas = document.getElementById("canvas"); var gl = canvas.getContext("webgl"); gl.clearColor(0.1, 0.2, 0.2, 1.0); gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT); var indices = [0, 0, 0, 0, 0, 0]; for (var points = 0; points < 6; points++) { indices[points] = (Math.random() * 2) - 1; //indices[points + 1] = Math.random() < 0.5 ? -1 : 1; } var buf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(indices), gl.STATIC_DRAW); var vert = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vert, ` precision mediump float; attribute vec2 position; uniform vec2 translation; void main(){ gl_Position = vec4(position + translation, 0.0, 1.0); } `); gl.compileShader(vert); var success1 = gl.getShaderParameter(vert, gl.COMPILE_STATUS); if (!success1) { // Something went wrong during compilation; get the error throw gl.getShaderInfoLog(vert); } var frag = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(frag, ` precision mediump float; void main(){ gl_FragColor = vec4(0.3, 0.6, 0.4, 1.0); } `); gl.compileShader(frag); var success2 = gl.getShaderParameter(frag, gl.COMPILE_STATUS); if (!success2) { // Something went wrong during compilation; get the error throw gl.getShaderInfoLog(frag); } var program = gl.createProgram(); gl.attachShader(program, vert); gl.attachShader(program, frag); gl.linkProgram(program); var vertLoc = gl.getAttribLocation(program, "position"); gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, gl.FALSE, 0, 0); gl.enableVertexAttribArray(vertLoc); gl.useProgram(program); var trans = gl.getUniformLocation(program, "translation"); var translation = [0.0, 0.0]; gl.uniform2fv(trans, translation); gl.drawArrays(gl.TRIANGLES, 0, 3); function loop() { gl.clearColor(0.1, 0.2, 0.2, 1.0); gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT); translation[0] += 0.01; gl.uniform2fv(trans, translation); gl.drawArrays(gl.TRIANGLES, 0, 3); for (var points = 0; points < 6; points++) { if (indices[points] % 2 == 0) { if (indices[points] + translation[0] > 1) { indices[points] = (Math.random() * 2) - 1; } } //indices[points + 1] = Math.random() < 0.5 ? -1 : 1; } requestAnimationFrame(loop); } loop(); 
 <canvas id="canvas"></canvas> 

To achieve this, consider making the following changes to your code: 为此,请考虑对代码进行以下更改:

  • remove placement of vertices by translation in your vertex shader to give you "per-vertex" control over placement of the geometry (the translation effectivly means "object-level" placement which isn't what your want here) 通过在顶点着色器中进行translation来删除顶点的放置,以使您可以“逐顶点”控制几何的放置( translation实际上意味着“对象级”放置,这不是您想要的)

  • when you iterate over the points in your loop() , you checking modulo over the vertex coordinate. 当遍历loop()points时,将检查顶点坐标的模。 You should be performing that check on the iteration index like this: if (points % 2 == 0) 您应该像这样对迭代索引执行检查: if (points % 2 == 0)

  • now that the translation concept is gone, update the position of the vertex coordinate, rather the translation array after the modulo check: indices[points] += 0.01; 现在translation概念消失了,更新模坐标后的顶点坐标的位置,而不是translation数组: indices[points] += 0.01;

  • finally, seeing you're updating the indices vertex data, you'll need to update the webgl buf to ensure your changes are reflected when the next frame is rendered: 最后,看到您正在更新indices顶点数据,您将需要更新webgl buf以确保在渲染下一帧时反映出您的更改:

     gl.bindBuffer(gl.ARRAY_BUFFER, buf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(indices), gl.STATIC_DRAW); 

Here's the updated script in full: 这是完整的更新脚本:

 var canvas = document.getElementById("canvas"); var gl = canvas.getContext("webgl"); gl.clearColor(0.1, 0.2, 0.2, 1.0); gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT); var indices = [0, 0, 0, 0, 0, 0]; for (var points = 0; points < 6; points++) { indices[points] = (Math.random() * 2) - 1; } var buf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(indices), gl.STATIC_DRAW); var vert = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vert, ` precision mediump float; attribute vec2 position; void main(){ gl_Position = vec4(position, 0.0, 1.0); } `); gl.compileShader(vert); var success1 = gl.getShaderParameter(vert, gl.COMPILE_STATUS); if (!success1) { throw gl.getShaderInfoLog(vert); } var frag = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(frag, ` precision mediump float; void main(){ gl_FragColor = vec4(0.3, 0.6, 0.4, 1.0); } `); gl.compileShader(frag); var success2 = gl.getShaderParameter(frag, gl.COMPILE_STATUS); if (!success2) { throw gl.getShaderInfoLog(frag); } var program = gl.createProgram(); gl.attachShader(program, vert); gl.attachShader(program, frag); gl.linkProgram(program); var vertLoc = gl.getAttribLocation(program, "position"); gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, gl.FALSE, 0, 0); gl.enableVertexAttribArray(vertLoc); gl.useProgram(program); gl.drawArrays(gl.TRIANGLES, 0, 3); function loop() { gl.clearColor(0.1, 0.2, 0.2, 1.0); gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES, 0, 3); // Update the vertex data, causing the vertex x coordinate to increase per-frame for (var points = 0; points < 6; points++) { // Only process x coordinate if (points % 2 == 0) { // Increase x coordinate per-frame indices[points] += 0.01; // If x position > 1 reset it to a new random value if (indices[points] > 1) { indices[points] = (Math.random() * 2) - 1; } } } // Update webgl vertex buffer so that updated indices data is rendered gl.bindBuffer(gl.ARRAY_BUFFER, buf); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(indices), gl.STATIC_DRAW); requestAnimationFrame(loop); } loop(); 
 <canvas id="canvas"><canvas> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM