簡體   English   中英

使用不同的 Webgl 將屬性傳遞給片段着色器

[英]Passing an attribute to fragment shader using varying 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); } var colors = []; for (var i = 0; i < nbTriangles; ++i) { var newColor = [Math.random() * 256, Math.random() * 256, Math.random() * 256, 1.0]; colors.push(...newColor); } // Creer un nouveau buffer vide. var posBuffer = gl.createBuffer(); var colorBuffer = gl.createBuffer(); // Ref sur l'attribut "pos" dans le vertex shader. var posLocation = gl.getAttribLocation(app.progObject, "pos"); var colorLocation = gl.getAttribLocation(app.progObject, "color"); // 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); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(colorLocation); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), 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; attribute vec4 color; varying vec4 fcolor; void main() { vec4 pt = vec4(pos, 0.0, 1.0); gl_Position = pt; fcolor=color; } </script> <script id="fs" type="x-shader/x-fragment"> precision mediump float; varying vec4 fcolor; void main() { vec4 color= fcolor; gl_FragColor = color; } </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>

color 屬性有一個浮點類型:

 attribute vec4 color;
 gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);

因此,必須在 [0.0, 1.0] 而不是 [0, 256] 范圍內指定顏色值:

var newColor = [Math.random() * 256, Math.random() * 256, Math.random() * 256, 1.0];

var newColor = [Math.random(), Math.random(), Math.random(), 1.0];

此外,每個三角形都有 3 個頂點(角)。 每個頂點坐標都必須與一個單獨的顏色屬性相關聯。 所以每個三角形也必須有 3 個顏色屬性:

var colors = [];
for (var i = 0; i < nbTriangles; ++i) {
        
    var newColor = [Math.random(), Math.random(), Math.random(), 1.0];
    colors.push(...newColor);
    colors.push(...newColor);
    colors.push(...newColor);
}

 // 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); } var colors = []; for (var i = 0; i < nbTriangles; ++i) { var newColor = [Math.random(), Math.random(), Math.random(), 1.0]; colors.push(...newColor); colors.push(...newColor); colors.push(...newColor); } // Creer un nouveau buffer vide. var posBuffer = gl.createBuffer(); var colorBuffer = gl.createBuffer(); // Ref sur l'attribut "pos" dans le vertex shader. var posLocation = gl.getAttribLocation(app.progObject, "pos"); var colorLocation = gl.getAttribLocation(app.progObject, "color"); // 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); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(colorLocation); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), 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; attribute vec4 color; varying vec4 fcolor; void main() { vec4 pt = vec4(pos, 0.0, 1.0); gl_Position = pt; fcolor=color; } </script> <script id="fs" type="x-shader/x-fragment"> precision mediump float; varying vec4 fcolor; void main() { vec4 color= fcolor; gl_FragColor = color; } </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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM