[英]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.