我一直在研究像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)
当不使用“可变”类型时,如何在片段着色器中索引纹理? (即,我只想要一个或多个特定纹理像素的值-无插值[与顶点几乎没有关系]]
暂时我已经读了很多。这是一个不详尽的列表:
编辑
这真是困扰我。
提前感谢!
我一直在学习像webglfundamentals这样的WebGL教程,并且遇到了一个绊脚石-我相信我将需要使用我创建的纹理将信息直接传递给......>
vec2 pixelCoord = vec2(x, y);
vec2 textureDimension = vec2(textureWidth, textureHeight)
vec2 texcoord = (pixelCoord + 0.5) / textureDimensions;
vec4 pixelValue = texture2D(someSamplerUniform, texcoord);