arrays - 索引表达式必须为常数-WebGL/GLSL错误

标签 arrays glsl webgl glsles

我在使用非恒定int作为索引的片段着色器中访问数组时遇到麻烦。我删除了该公式,因为无论如何在这里都没有多大意义,但是我的代码旨在根据当前像素计算tileID并使用它来确定颜色。

这是我的代码:

int tileID = <Insert formula here>;

vec3 colorTest;

int arrayTest[1024];
for (int x = 0; x < 1024; x++) {
    if (x == 1) arrayTest[x] = 1;
    else arrayTest[x] = 2;
}

if (arrayTest[tileID] == 1) colorTest = vec3(0.0, 1.0, 0.0);
else if (arrayTest[tileID] == 2) colorTest = vec3(1.0, 0.0, 0.0);
else colorTest = vec3(0.0, 0.0, 0.0);


显然GLSL不喜欢这样,我得到了错误:


'[]':索引表达式必须为常数


有谁知道我该怎么解决?谢谢。

最佳答案

作为背景-GLSL看起来很像C,但是编译有点不同。事情展开得很厉害,条件条件可以并行执行并在最后切换。取决于硬件...

您可以使用循环索引或常量来索引数组。循环中的分配是可以的,但是通过tileID进行的访问却不可行。

WebGL Shader语言来自GLES,已记录在案

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计算而不是预先计算和编制索引。

或者,预先计算您喜欢的任何数组,然后将其作为纹理传递。当然,可以根据需要对纹理进行索引。

这是我使用的javascript帮助程序方法,用于将浮点向下传递到着色器:

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调用之前进行设置,例如

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不支持顶点纹理...)

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


因此,您必须为数组作为纹理的大小正确索引,范围为0到1。尝试从每个值/像素的中间进行采样。就像,如果数组的宽度为2个值,则分别以0.25和0.75索引。

这就是要旨!

关于arrays - 索引表达式必须为常数-WebGL/GLSL错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19529690/

相关文章:

c - 为什么这个 pangram 程序不起作用?

opengl - 未明确指定绑定(bind)点索引的多个 UBO

opengl - glGenerateMipmap 需要哪个内存屏障?

javascript - 在 WebGL 与 WebGL 中模拟基于调色板的图形 Canvas 二维

php - 用php忽略隐藏文件

javascript - 按最常见的项目在 javascript 中排序数组

java - 搜索具有多种数据类型的ArrayList

c++ - OpenGL3.3 中的代码不在正交投影中渲染纹理

javascript - Three.js 阴影 - 如何改进?

html - 在 SVG 或 WebGL 中使用 Canvas 进行 3D 应用