我正在为游戏引擎编写以下片段着色器:
#version 330 core
layout (location = 0) out vec4 color;
uniform vec4 colour;
uniform vec2 light_pos;
in DATA
{
vec4 position;
vec2 uv;
float tid;
vec4 color;
} fs_in;
uniform sampler2D textures[32];
void main()
{
float intensity = 1.0 / length(fs_in.position.xy - light_pos);
vec4 texColor = fs_in.color;
if(fs_in.tid > 0.0){
int tid = int(fs_in.tid + 0.5);
texColor = texture(textures[tid], fs_in.uv);
}
color = texColor * intensity;
}
texColor = texture(textures[tid], fs_in.uv);
行导致在编译着色器时出现“GLSL 1.30及更高版本中禁止使用非常数表达式索引的采样器数组”表达式。
顶点着色器(如果需要)为:
#version 330 core
layout (location = 0) in vec4 position;
layout (location = 1) in vec2 uv;
layout (location = 2) in float tid;
layout (location = 3) in vec4 color;
uniform mat4 pr_matrix;
uniform mat4 vw_matrix = mat4(1.0);
uniform mat4 ml_matrix = mat4(1.0);
out DATA
{
vec4 position;
vec2 uv;
float tid;
vec4 color;
} vs_out;
void main()
{
gl_Position = pr_matrix * vw_matrix * ml_matrix * position;
vs_out.position = ml_matrix * position;
vs_out.uv = uv;
vs_out.tid = tid;
vs_out.color = color;
}
4条答案
按热度按时间v8wbuo2f1#
在GLSL 3.3中,采样器阵列的索引仅允许通过整数常量表达式(参见GLSL 3.3 Spec, Section 4.1.7)。
在更现代的版本中,从GLSL 4.0开始,允许通过动态统一表达式索引采样器阵列(参见GLSL 4.0 Spec, Section 4.1.7)
你实际上尝试的是通过一个变量来索引数组,这是不可能的。如果这是绝对不可避免的,你可以把2D纹理打包成一个2D数组纹理或一个3D纹理,并使用索引来寻址纹理的层(或第三维)。
ohtdti5x2#
我通过使用一点代码生成克服了这个问题:
在Javascript中,它看起来像这样:
注意:我们使用'来启动和停止JS中的多行字符串,使用${some_value}来为模板提供值
fkvaft9z3#
我也遇到过类似的问题。换到一个较新的版本(准确地说是#460)在我的情况下起作用了。
sbtkgmzw4#
问题在于,在行
texColor = texture(textures[tid], fs_in.uv)
中,采样器阵列texturues
被给予非恒定索引。简单的解决方法是使用一个大的switch语句来替换
texColor = texture(textures[tid], fs_in.uv)
行,这样纹理数组就可以用一个常数来评估。例如,你可以这样写: