简体   繁体   English

使用 Webgl 创建三角形的随机位置

[英]Creating random positions of triangles using Webgl

I've just started to learn webgl I've been trying to generate triangles with random size and positions just like in this picture using javascript.我刚刚开始学习 webgl 我一直在尝试使用 javascript 生成具有随机大小和位置的三角形,就像这张图片中的一样。

随机三角形

I know that I need to use a for loop inside the function initScene() but I am not sure how to put the new positions into the array.我知道我需要在函数 initScene() 中使用 for 循环,但我不确定如何将新位置放入数组中。 Please help.请帮忙。

 // Application info. var app = app || {}; var nbTriangles=20; function getContextGL(canvasElement) { var can = document.getElementById(canvasElement); if(can == null) { return [null, null]; } var gl = can.getContext("webgl"); return [can, gl]; } function createShaderFromElement(gl, id) { // Grab the script element. var scriptElt = document.getElementById(id); if (!scriptElt) { return null; } // Retrieve the source. var scriptSource = scriptElt.textContent; // Identify shader type based on element type. var shaderObj; if (scriptElt.type == "x-shader/x-fragment") { shaderObj = gl.createShader(gl.FRAGMENT_SHADER); } else if (scriptElt.type == "x-shader/x-vertex") { shaderObj = gl.createShader(gl.VERTEX_SHADER); } else { return null; } // Compile and check status. gl.shaderSource(shaderObj, scriptSource); gl.compileShader(shaderObj); var ok = gl.getShaderParameter(shaderObj, gl.COMPILE_STATUS); if (!ok) { var msgError = gl.getShaderInfoLog(shaderObj); alert(msgError); gl.deleteShader(shader); return null; } return shaderObj; } function buildProgram(gl, vertexShader, fragmentShader) { if (!vertexShader || !fragmentShader) { return null; } var progObject = gl.createProgram(); if(!progObject) { alert("Can't create program object."); return ; } gl.attachShader(progObject, vertexShader); gl.attachShader(progObject, fragmentShader); gl.linkProgram(progObject); var ok = gl.getProgramParameter(progObject, gl.LINK_STATUS); if(!ok) { var msgError = gl.getProgramInfoLog(progObject); alert(msgError); gl.deleteProgram(progObject); return null; } return progObject; } function initGL() { app.gl.viewport(0,0,app.can.width, app.can.height); app.gl.clearColor(0.,0.,0., 1.0); app.gl.clear(app.gl.COLOR_BUFFER_BIT); var vs = createShaderFromElement(app.gl, "vs"); var fs = createShaderFromElement(app.gl, "fs"); app.progObject = buildProgram(app.gl, vs, fs); app.gl.useProgram(app.progObject); } function initScene() { var gl = app.gl; // Creer le buffer de geometrie (vertex) // /* Drawing one triangle: var positions = [ // coordonnees normalisees. 0.0, 0.1, 0.1, -0.1,-0.1, -0.1 ];*/ for (var i=0; i<nbTriangles;++i) { var orig = [0.0, 1.0, 1.0, -1.0, -1.0, -1.0]; var scale = Math.random() * 0.2; var Trans = [Math.random() * 1.6, Math.random * 1.6]; P0 = orig[0] * scale + Trans[0]; P1 = orig[1] * scale + Trans[1]; P2 = orig[2] * scale + Trans[2]; var positions= new Positions (P0,P1,P2) TRIANGLES.push(newPositions); } // Creer un nouveau buffer vide. var posBuffer = gl.createBuffer(); // Ref sur l'attribut "pos" dans le vertex shader. var posLocation = gl.getAttribLocation(app.progObject, "pos"); // Activer le buffer. Toute operation sur buffer // sera appliquer a posBuffer (il est actif!). gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); gl.enableVertexAttribArray(posLocation); gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false /*no normalization*/, 0 /*stride*/, 0 /*offset*/); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); } function render() { var gl = app.gl; gl.clear( gl.COLOR_BUFFER_BIT) // Dessiner le buffer. gl.drawArrays(gl.TRIANGLES, 0, 3* nbTriangles); } function init() { [app.can, app.gl] = getContextGL('can'); if (app.can == null || app.gl == null) { alert("Can't init canvas or context"); return; } app.can.width = app.can.height * (app.can.clientWidth / app.can.clientHeight); var rect = app.can.getBoundingClientRect(); app.scaleX = app.can.width / rect.width; app.scaleY = app.can.height / rect.height; initGL(); initScene(); render(); }
 div { } #main-div { display:inline-block; } #viewport, #manager { float: left; margin: auto; } .color { width:100px; height:50px; } .blue{ background:#0f0; } #viewport { width: 600px; height:700px; } #can { width: 600px; height: 500px; border:1px solid orange; } #manager { width: 200px; height:300px; padding: 0 0 0 5px; } #obj-list { width: 200px; }
 <!DOCTYPE html> <html> <head> <title>Colored Quad</title> <link rel="stylesheet" type="text/css" href="style.css"> <script src="colored_quad.js"></script> <script id="vs" type="x-shader/x-vertex"> precision mediump float; attribute vec2 pos; void main() { vec4 pt = vec4(pos, 0.0, 1.0); gl_Position = pt; } </script> <script id="fs" type="x-shader/x-fragment"> precision mediump float; void main() { gl_FragColor = vec4(1,0,0,1); } </script> </head> <body onload="init();"> <div id="main-div"> <div id="viewport"> <canvas id="can" >Your browser doesn't seem to support canvas!</canvas> </div> </div> </body> </html>

When I run your code I get an error "positions is undefined"当我运行你的代码时,我收到一个错误“位置未定义”

Maybe you should try to fix those errors before posting your question?也许您应该在发布问题之前尝试修复这些错误? If you're just learning JavaScript maybe these lessons would help如果你只是在学习 JavaScript 也许这些课程会有所帮助

In any case, this code无论如何,这段代码


// Creer le buffer de geometrie (vertex)
//

   /* Drawing one triangle:


    var positions = [
        // coordonnees normalisees.
        0.0, 0.1, 0.1, -0.1,-0.1, -0.1
        
    
    ];*/

    for (var i=0; i<nbTriangles;++i)
    {
    
    
    var  orig = [0.0, 1.0, 1.0, -1.0, -1.0, -1.0];
    var scale = Math.random() * 0.2;
    var Trans = [Math.random() * 1.6, Math.random * 1.6];
    P0 = orig[0] * scale + Trans[0];
    P1 = orig[1] * scale + Trans[1];
    P2 = orig[2] * scale + Trans[2];


    var positions= new Positions (P0,P1,P2)

    TRIANGLES.push(newPositions); 
    }

has a lot of basic javascript issues.有很多基本的 javascript 问题。

Positions is not defined (the first error when running it). Positions未定义(运行时的第一个错误)。 Just looking at the code I can also see a reference to TRIANGLES that is not defined, newPositions that is not defined.仅查看代码,我还可以看到对未定义的TRIANGLES和未定义的newPositions的引用。 Also I see P0 , P1 , and P2 I'm assuming were supposed to be points but they are referencing only a single value in orig each instead of 2 values (x and y).我还看到P0P1P2我假设应该是点,但它们只引用orig的单个值,而不是 2 个值(x 和 y)。 And P2 is referencing Trans[2] which doesn't exist.P2正在引用不存在的Trans[2]

Here is one fix这是一个修复

      var positions = [];

      for (var i = 0; i < nbTriangles; ++i) {

        var orig = [0.0, 1.0, 1.0, -1.0, -1.0, -1.0];
        var scale = Math.random() * 0.2;
        var Trans = [Math.random() * 1.6, Math.random() * 1.6];
        var P0 = [
           orig[0] * scale + Trans[0],
           orig[1] * scale + Trans[1],
        ];
        var P1 = [
          orig[2] * scale + Trans[0],
          orig[3] * scale + Trans[1],
        ];
        var P2 = [
          orig[4] * scale + Trans[0],
          orig[5] * scale + Trans[1],
        ];
        positions.push(...P0, ...P1, ...P2);
      }

Another fix would be to loop over the points in orig另一个解决方法是遍历orig的点

      for (var i = 0; i < nbTriangles; ++i) {

        var orig = [0.0, 1.0, 1.0, -1.0, -1.0, -1.0];
        var scale = Math.random() * 0.2;
        var Trans = [Math.random() * 1.6, Math.random() * 1.6];
        for (var j = 0; j < orig.length; j += 2) {
          positions.push(
            orig[j    ] * scale + Trans[0],
            orig[j + 1] * scale + Trans[1],
          );
        }
      }

another would be to write functions to scale and add vectors另一种方法是编写函数来缩放和添加向量

      const addV = (v1, v2) => v1.map((v1Elem, i) => v1Elem + v2[i]);
      const scaleV = (v, scale) => v.map((elem) => elem * scale);

      for (var i = 0; i < nbTriangles; ++i) {

        var orig = [0.0, 1.0, 1.0, -1.0, -1.0, -1.0];
        var scale = Math.random() * 0.2;
        var Trans = [Math.random() * 1.6, Math.random() * 1.6];
        for (var j = 0; j < orig.length; j += 2) {
          // pull out 2 values from orig
          let p = orig.slice(j, j + 2);
          p = scaleV(p, scale);
          p = addV(p, Trans); 
          positions.push(...p);
        }
      }

As for adding a different color to each triangle I'd suggest you go read some other articles on WebGL至于为每个三角形添加不同的颜色,我建议您阅读有关 WebGL 的其他文章

 // Application info. var app = app || {}; var nbTriangles = 20; function getContextGL(canvasElement) { var can = document.getElementById(canvasElement); if (can == null) { return [null, null]; } var gl = can.getContext("webgl"); return [can, gl]; } function createShaderFromElement(gl, id) { // Grab the script element. var scriptElt = document.getElementById(id); if (!scriptElt) { return null; } // Retrieve the source. var scriptSource = scriptElt.textContent; // Identify shader type based on element type. var shaderObj; if (scriptElt.type == "x-shader/x-fragment") { shaderObj = gl.createShader(gl.FRAGMENT_SHADER); } else if (scriptElt.type == "x-shader/x-vertex") { shaderObj = gl.createShader(gl.VERTEX_SHADER); } else { return null; } // Compile and check status. gl.shaderSource(shaderObj, scriptSource); gl.compileShader(shaderObj); var ok = gl.getShaderParameter(shaderObj, gl.COMPILE_STATUS); if (!ok) { var msgError = gl.getShaderInfoLog(shaderObj); alert(msgError); gl.deleteShader(shader); return null; } return shaderObj; } function buildProgram(gl, vertexShader, fragmentShader) { if (!vertexShader || !fragmentShader) { return null; } var progObject = gl.createProgram(); if (!progObject) { alert("Can't create program object."); return; } gl.attachShader(progObject, vertexShader); gl.attachShader(progObject, fragmentShader); gl.linkProgram(progObject); var ok = gl.getProgramParameter(progObject, gl.LINK_STATUS); if (!ok) { var msgError = gl.getProgramInfoLog(progObject); alert(msgError); gl.deleteProgram(progObject); return null; } return progObject; } function initGL() { app.gl.viewport(0, 0, app.can.width, app.can.height); app.gl.clearColor(0., 0., 0., 1.0); app.gl.clear(app.gl.COLOR_BUFFER_BIT); var vs = createShaderFromElement(app.gl, "vs"); var fs = createShaderFromElement(app.gl, "fs"); app.progObject = buildProgram(app.gl, vs, fs); app.gl.useProgram(app.progObject); } function initScene() { var gl = app.gl; // Creer le buffer de geometrie (vertex) // var positions = []; for (var i = 0; i < nbTriangles; ++i) { var orig = [0.0, 1.0, 1.0, -1.0, -1.0, -1.0]; var scale = Math.random() * 0.2; var Trans = [Math.random() * 1.6, Math.random() * 1.6]; var P0 = [ orig[0] * scale + Trans[0], orig[1] * scale + Trans[1], ]; var P1 = [ orig[2] * scale + Trans[0], orig[3] * scale + Trans[1], ]; var P2 = [ orig[4] * scale + Trans[0], orig[5] * scale + Trans[1], ]; positions.push(...P0, ...P1, ...P2); } // Creer un nouveau buffer vide. var posBuffer = gl.createBuffer(); // Ref sur l'attribut "pos" dans le vertex shader. var posLocation = gl.getAttribLocation(app.progObject, "pos"); // Activer le buffer. Toute operation sur buffer // sera appliquer a posBuffer (il est actif!). gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); gl.enableVertexAttribArray(posLocation); gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false /*no normalization*/ , 0 /*stride*/ , 0 /*offset*/ ); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); } function render() { var gl = app.gl; gl.clear(gl.COLOR_BUFFER_BIT) // Dessiner le buffer. gl.drawArrays(gl.TRIANGLES, 0, 3 * nbTriangles); } function init() { [app.can, app.gl] = getContextGL('can'); if (app.can == null || app.gl == null) { alert("Can't init canvas or context"); return; } app.can.width = app.can.height * (app.can.clientWidth / app.can.clientHeight); var rect = app.can.getBoundingClientRect(); app.scaleX = app.can.width / rect.width; app.scaleY = app.can.height / rect.height; initGL(); initScene(); render(); } init();
 #main-div { display: inline-block; } #viewport, #manager { float: left; margin: auto; } .color { width: 100px; height: 50px; } .blue { background: #0f0; } #viewport { width: 600px; height: 700px; } #can { width: 600px; height: 500px; border: 1px solid orange; } #manager { width: 200px; height: 300px; padding: 0 0 0 5px; } #obj-list { width: 200px; }
 <div id="main-div"> <div id="viewport"> <canvas id="can" >Your browser doesn't seem to support canvas!</canvas> </div> </div> <script id="vs" type="x-shader/x-vertex"> precision mediump float; attribute vec2 pos; void main() { vec4 pt = vec4(pos, 0.0, 1.0); gl_Position = pt; } </script> <script id="fs" type="x-shader/x-fragment"> precision mediump float; void main() { gl_FragColor = vec4(1,0,0,1); } </script>

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

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