如何在WebGL中使用数据纹理

问题描述 投票:0回答:1

我一直在研究像webglfundamentals这样的WebGL教程,并且遇到了一个绊脚石-我相信我将需要使用我创建的纹理将信息直接传递给片段着色器,但是我似乎无法正确索引纹理。

目标是传递有关光源(位置和颜色)的信息,这些信息将被计入片段颜色。理想情况下,此信息的值和长度都是动态的。

复制

我在此小提琴中创建了问题的简化版本:WebGL - Data Texture Testing

这里是一些代码。

一次性设置中,我们创建一个纹理,用数据填充它,然后在该纹理上应用似乎最防呆的设置(没有mips,没有字节打包问题[?])] >

  // lookup uniforms
  var textureLocation = gl.getUniformLocation(program, "u_texture");

  // Create a texture.
  var texture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, texture);

  // fill texture with 1x3 pixels
  const level = 0;
  const internalFormat = gl.RGBA; // I've also tried to work with gl.LUMINANCE
  //   but it feels harder to debug
  const width = 1;
  const height = 3;
  const border = 0;
  const type = gl.UNSIGNED_BYTE;
  const data = new Uint8Array([
    // R,   G,   B, A (unused)    // : 'texel' index (?)
    64, 0, 0, 0, // : 0
    0, 128, 0, 0, // : 1
    0, 0, 255, 0, // : 2
  ]);
  const alignment = 1; // should be uneccessary for this texture, but 
  gl.pixelStorei(gl.UNPACK_ALIGNMENT, alignment); //   I don't think this is hurting
  gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, width, height, border,
    internalFormat, type, data);

  // set the filtering so we don't need mips and it's not filtered
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

draw

序列中(它只会发生一次,但可以想象会重复),我们强调程序应该使用纹理
    // Tell the shader to use texture unit 0 for u_texture
    gl.activeTexture(gl.TEXTURE0);                  // added this and following line to be extra sure which texture is being used...
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.uniform1i(textureLocation, 0);

最后,在片段着色器中,我们试图仅可靠地使用一个'texel'作为传达信息的手段。我似乎无法确定如何可靠地检索存储在纹理中的值。

precision mediump float;

// The texture.
uniform sampler2D u_texture;

void main() {

    vec4 sample_00 = texture2D(u_texture, vec2(0, 0)); 
    // This sample generally appears to be correct. 
    // Changing the provided data for the B channel of texel
    //   index 0 seems to add blue as expected

    vec4 sample_01 = texture2D(u_texture, vec2(0, 1));
    vec4 sample_02 = texture2D(u_texture, vec2(0, 2));
    // These samples are how I expected this to work since 
    //   the width of the texture is set to 1
    // For some reason 01 and 02 both show the same color

    vec4 sample_10 = texture2D(u_texture, vec2(1, 0));
    vec4 sample_20 = texture2D(u_texture, vec2(2, 0));
    // These samples are just there for testing - I don't think
    //   that they should work

    // choose which sample to display
    vec4 sample = sample_00;
    gl_FragColor = vec4(sample.x, sample.y, sample.z, 1);
}

问题

使用纹理是执行此操作的最佳方法吗?我听说过也可以传递矢量数组,但是纹理似乎更常见。

您应该如何创建纹理? (特别是当我指定“ width”和“ height”时,我应该指的是生成的纹理像素尺寸或将用于构造纹理的gl.UNSIGNED_BYTE元素的数量?texImage2D documentation

当不使用“可变”类型时,如何在片段着色器中索引纹理? (即,我只想要一个或多个特定纹理像素的值-无插值[与顶点几乎没有关系]]

其他资源

暂时我已经读了很多。这是一个不详尽的列表:

这是我刚刚找到的另一个资源:Hassles with array access in WebGL, and a couple of workarounds。使我充满希望。

这真是困扰我。

提前感谢!

我一直在学习像webglfundamentals这样的WebGL教程,并且遇到了一个绊脚石-我相信我将需要使用我创建的纹理将信息直接传递给......>

opengl-es shader webgl textures
1个回答
0
投票
在WebGL1中处理纹理中的单个像素使用此公式

vec2 pixelCoord = vec2(x, y); vec2 textureDimension = vec2(textureWidth, textureHeight) vec2 texcoord = (pixelCoord + 0.5) / textureDimensions; vec4 pixelValue = texture2D(someSamplerUniform, texcoord);

© www.soinside.com 2019 - 2024. All rights reserved.