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.RGBA
、gl.UNSIGNED_BYTE
纹理和 add/multiply 通道以获得大范围的值。或者,如果你不想弄乱它,你可以使用浮点纹理。 .
我需要从我的着色器访问缓冲区。缓冲区是从数组创建的。 (在真实场景中,数组有 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.RGBA
、gl.UNSIGNED_BYTE
纹理和 add/multiply 通道以获得大范围的值。或者,如果你不想弄乱它,你可以使用浮点纹理。