且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

指数前pression必须恒定 - WebGL的/ GLSL错误

更新时间:2022-12-30 18:23:07

作为背景 - GLSL看起来很像C,但是编译有点不同。东西都很展开,和条件可以并行执行,并在年底开机,诸如此类的事情。取决于硬件...

As background -- GLSL looks a lot like C, but compiles a bit different. Things are very unrolled, and conditionals may be executed in parallel and switched at the end, that sort of thing. Depends on the hardware...

您可以使用循环索引或常量索引到数组。在循环分配是好的,但tileID访问是没有的。

You can use loop indices or constants to index into arrays. The assignment in your loop is ok, but the access by tileID isn't.

WebGL的着色器语言与GLES,记录

WebGL Shader language is from GLES, documented

http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf

附录,第5节,讨论:

Indexing of Arrays, Vectors and Matrices
Definition:
constant-index-expressions are a superset of constant-expressions. Constant-index-expressions can include loop indices as defined in Appendix A section 4.
The following are constant-index-expressions:
• Constant expressions
• Loop indices as defined in section 4
• Expressions composed of both of the above
When used as an index, a constant-index-expression must have integral type.

希望帮助!

呵呵,作为固定它,在上面的例子确切......看起来你可以从tileID计算,而不是precompute和索引。

Oh, as for fixing it, in the exact example above... looks like you could compute from tileID rather than precompute and index.

或者,precompute任何数组你喜欢的,并在将它作为质感。纹理,当然的可以的被索引但是你喜欢的。

Or, precompute whatever array you like, and pass it in as a texture. A texture, of course, can be indexed however you like.

下面是一个JavaScript helper方法我用,传递花车下降到着色器:

Here's a javascript helper method I use, to pass floats down to the shaders:

function glSetupStuff() { ...
...
if(!gl.getExtension("OES_texture_float"))   // <<-- enables RGBA float values, handy!
    alert("cant pass in floats, use 8-bit values instead.");
... }

/*
 * Pass in an array of rgba floats,
 * for example: var data = new Float32Array([0.1,0.2,0.3,1,  .5,.5,1.0,1]);
 */
function textureFromFloats(gl,width,height,float32Array) 
{
var oldActive = gl.getParameter(gl.ACTIVE_TEXTURE);
gl.activeTexture(gl.TEXTURE15); // working register 31, thanks.

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

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 
                width, height, 0, 
                gl.RGBA, gl.FLOAT, float32Array);

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, null);

gl.activeTexture(oldActive);

return texture;
}

请注意使用gl.NEAREST的,因此它不模糊你的价值!然后你就可以在gl.drawXxx调用之前设置它,喜欢的东西。

Note the use of gl.NEAREST, so it doesn't "blur" your values! Then you can set it up before the gl.drawXxx call, with something like

textureUnit = 3;  // from 0 to 15 is ok
gl.activeTexture(gl.TEXTURE0 + textureUnit);
gl.bindTexture(gl.TEXTURE_2D, texture);

var z = gl.getUniformLocation(prog, "uSampler");
gl.uniform1i(z, textureUnit);

和着色器(我相信片段或顶点;一些早期的WebGL的不支持顶点纹理...)

And in the shader (I believe fragment or vertex; some earlier webgl's didn't support vertex textures...)

uniform sampler2D uSampler;
...
vec4 value = texture2D(uSampler, vec2(xValueBetween0And1,yValueBetween0And1));

所以,你要适当的索引为数组作为纹理大小,内0到1.尝试从范围内的每个值/像素的中间采样。就像,如果数组是2值宽,0.25和0.75指数。

So, you have to index appropriately for the array-as-texture size, within range of 0 to 1. Try to sample from the middle of each value/pixel. Like, if the array is 2 values wide, index by 0.25 and 0.75.

这就是它的要点!