Webgl着色整个几何?

时间:2014-06-18 11:53:28

标签: webgl

我使用三角形(使用顶点和面部位置)来绘制图形。我正在存储每个顶点的颜色信息并相应地应用颜色。但问题是我场景中的所有几何都是单色(比如锥=红,圆柱=蓝)。所以,为每个顶点存储颜色对我来说显然毫无用处。

除了在场景中存储每个顶点的颜色信息之外,还有其他任何可以在webgl中进行着色的方法。也许就像着色整个几何体(比如锥形)一样。

2 个答案:

答案 0 :(得分:1)

从你的问题中可以清楚地看出你可能不太了解WebGL了吗?您可能需要查看these tutorials

WebGL使用着色器,这些着色器使用您定义的任何输入并输出您告诉它们输出的任何内容。这意味着WebGL不需要顶点颜色。在编写着色器时,您决定使用顶点颜色。如果您不想使用顶点颜色,请不要编写引用顶点颜色的着色器。

那说如果你有一个使用顶点颜色的着色器,你可以很容易地为着色器提供恒定的颜色。让我们假设你有这样的着色器只使用顶点颜色。

顶点着色器:

attribute vec4 a_position; 
attribute vec4 a_color;     // vertex colors

varying vec4 v_color;       // so we can pass the colors to the fragment shader

uniform mat4 u_matrix;

void main() {
   gl_Position = u_matrix * a_position;
   v_color = a_color;
}

片段着色器:

precision mediump float;

varying vec4 v_color;

void main() {
  gl_FragColor = v_color;
}

现在,要使用常量颜色,您只需关闭a_color的属性,并使用gl.vertexAttrib4f设置一个常量值

// at init time
var a_colorLocation = gl.getAttribLocation(program, "a_color";

// at draw time
gl.disableVertexAttribArray(a_colorLocation);    // turn off the attribute
gl.vertexAttrib4f(a_colorLocation, r, g, b, a);  // supply a constant color

请注意,关闭属性0会降低桌面上的WebGL速度,因为如果OpenGL和OpenGL ES之间存在差异。可能a_colorLocation属性为0.要避免此问题,请在链接程序之前绑定属性位置。特别是因为你总是使用一个位置(在上面的例子中称为" a_position")只需将它绑定到位置0就像这样

..compile shaders..
..attach shaders to program..

// Must happen before you call linkProgram
gl.bindAttribLocation(program, 0, "a_position");

gl.linkProgram(program);

...check for errors, etc...

这将强制" a_position"属性为0,所以你总是启用它。

这是一个样本



function main() {
  var canvas = document.getElementById("c");
  var gl = canvas.getContext("webgl");
  if (!gl) {
      alert("no WebGL");
      return;
  }

  // NOTE:! This function binds attribute locations
  // based on the indices of the second array
  var program = twgl.createProgramFromScripts(
      gl, 
      ["vshader", "fshader"], 
      ["a_position", "a_color"]);  // a_position will get location 0
                                   // a_color will get location 1

  var a_positionLoc = 0;
  var a_colorLoc = 1;
  var u_matrixLoc = gl.getUniformLocation(program, "u_matrix");

  gl.useProgram(program);

  var verts = [
        1,  1,  
       -1,  1,  
       -1, -1, 
        1,  1, 
       -1, -1, 
        1, -1,  
  ];

  var colors = [
    255, 0, 0, 255,
    0, 255, 0, 255,
    0, 0, 255, 255,

    255, 255, 0, 255,
    0, 255, 255, 255,
    255, 0, 255, 255,
  ];    

  var positionBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
  gl.enableVertexAttribArray(a_positionLoc);
  gl.vertexAttribPointer(a_positionLoc, 2, gl.FLOAT, false, 0, 0);

  var colorBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(colors), gl.STATIC_DRAW);
  gl.enableVertexAttribArray(a_colorLoc);
  gl.vertexAttribPointer(a_colorLoc, 4, gl.UNSIGNED_BYTE, true, 0, 0);

  // Draw in the bottom right corner
  gl.uniformMatrix4fv(
      u_matrixLoc,
      false,
      [0.5, 0, 0, 0,
       0, 0.5, 0, 0,
       0, 0, 1, 0,
       -0.5, -0.5, 0, 1]);

  gl.drawArrays(gl.TRIANGLES, 0, 6);


  // Now turn off the a_color attribute and supply a solid color

  gl.disableVertexAttribArray(a_colorLoc);
  var r = 0.5;
  var g = 1;
  var b = 0.5;
  var a = 1;
  gl.vertexAttrib4f(a_colorLoc, r, g, b, a); // greenish

  // Draw in the top left corner
  gl.uniformMatrix4fv(
      u_matrixLoc,
      false,
      [0.5, 0, 0, 0,
       0, 0.5, 0, 0,
       0, 0, 1, 0,
       0.5, 0.5, 0, 1]);

  gl.drawArrays(gl.TRIANGLES, 0, 6);
};
main();

canvas { border: 1px solid black; }

<script src="https://twgljs.org/dist/3.x/twgl.min.js"></script>
<script id="vshader" type="whatever">
    attribute vec4 a_position;
    attribute vec4 a_color;
    
    varying vec4 v_color;
    
    uniform mat4 u_matrix;
    
    void main() {
        gl_Position = u_matrix * a_position;
        v_color = a_color;
    }    
</script>
<script id="fshader" type="whatever">
precision mediump float;
varying vec4 v_color;
void main() {
    gl_FragColor = v_color;
}
</script>
<canvas id="c" width="300" height="300"></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如果您的几何体具有每个对象的颜色,并且不会在几何体上发生变化,那么您应该将该颜色作为统一变量传递。

所以你只需要一个属性 - 顶点的位置,很少的矩阵制服 - 比如模型,视图,投影矩阵,顶点着色器,以及片段着色器的一个矢量统一变量,用于&#34;着色&# 34;对象。