【问题标题】:WebGL: Access buffer from shaderWebGL:从着色器访问缓冲区
【发布时间】:2016-03-31 04:40:05
【问题描述】:

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

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

【问题讨论】:

  • 您是否尝试过将数组加载到纹理?使用 Sampler2D 对象,我希望您可以访问整个数组..
  • 你应该这样做吗?我认为 Sampler2D 是用于随机自定义二进制数据的图像和缓冲区。
  • 如何从数组创建 Sampler2D 对象?
  • 没关系,明白了:gl.texImage2D(gl.TEXTURE_2D,0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
  • 我们只创建了一个纹理对象。在向 glTexImage2D 提供数据时,传递您的数据而不是图像数据。在片段着色器中,使用采样器对象访问内容。

标签: webgl


【解决方案1】:

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

如果您有 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.

【讨论】:

    猜你喜欢
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多