WebGL:从着色器访问缓冲区

WebGL: Access buffer from shader

我需要从我的着色器访问缓冲区。缓冲区是从数组创建的。 (在真实场景中,数组有 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);

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

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

如果您有 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 纹理和 add/multiply 通道以获得大范围的值。或者,如果你不想弄乱它,你可以使用浮点纹理。 .