WebGL:来自着色器的访问缓冲区

时间:2016-03-31 04:40:06

标签: webgl

我需要从着色器访问缓冲区。缓冲区是从数组创建的。 (在实际情况中,数组有10k +(变量)数字。)

var myBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, myBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([1,2,3,4,5,6,7]), gl.STATIC_DRAW);

如何发送它以便着色器可以使用它?

precision mediump float;
uniform uint[] myBuffer;//???

void main() {
    gl_FragColor = vec4(myBuffer[0],myBuffer[1],0,1);
}

通常情况下,如果是属性,则为

gl.vertexAttribPointer(myBuffer, 2, gl.UNSIGNED_BYTE, false, 4, 0);

但我需要能够从任何着色器像素访问整个数组,因此它不是顶点属性。

1 个答案:

答案 0 :(得分:4)

如果要随机访问着色器中的大量数据,请使用纹理。

如果您有10000个值,则可能会生成100x100像素的纹理。然后,您可以使用

之类的内容从纹理中获取每个值
uniform sampler2D u_texture;

vec2 textureSize = vec2(100.0, 100.0);

vec4 getValueFromTexture(float index) {
   float column = mod(index, textureSize.x);
   float row    = floor(index / textureSize.x);
   vec2 uv = vec2(
      (column + 0.5) / textureSize.x,
      (row    + 0.5) / textureSize.y);
   return texture2D(u_texture, uv);
}

确保纹理过滤设置为gl.NEAREST

当然,如果你制作textureSize制服,你可以传递纹理的大小。

至于为什么+ 0.5部分see this answer

您可以使用普通gl.RGBAgl.UNSIGNED_BYTE纹理并将通道相加/相乘以获得大范围的值。或者,如果你不想弄乱它,你可以使用浮点纹理。 You need to enable floating point textures