我们有以下GLSL代码:
#version 120
#define LIGHT_COUNT 2
...
varying vec3 v_light_tan[LIGHT_COUNT];
varying float v_attenuation[LIGHT_COUNT];
uniform vec3 light_position[LIGHT_COUNT];
void main(void) {
...
for ( int index = 0; index < LIGHT_COUNT; index++ )
{
float distance = length( light_position[index] - world_pos );
v_attenuation[index] = 1.0 / ( 1.0 + 0.05 * distance * distance);
vec3 light_loc = vec3(nv_m_model_inv * vec4 (light_position[index], 1.0) );
vec3 light_dir_loc = normalize( nv_position - light_loc );
v_light_tan[index] = vec3(
dot( nv_tangent.xyz, light_dir_loc ),
dot( bitangent, light_dir_loc ),
dot( nv_normal, light_dir_loc )
);
}
我已经阅读了很多关于循环问题的内容,所以我选择了一个硬编码循环。但即使这个简单的代码似乎也失败了。以上适用于LIGHT_COUNT = 1
,但对于2
,v_attenuation [0]的值已损坏。令人惊讶的是,将代码更改为:
for ( int index = 0; index < LIGHT_COUNT; index++ )
{
float distance = length( light_position[index] - world_pos );
v_attenuation[index] = 1.0 / ( 1.0 + 0.05 * distance * distance);
}
for ( int index = 0; index < LIGHT_COUNT; index++ )
{
vec3 light_loc = vec3(nv_m_model_inv * vec4 (light_position[index], 1.0) );
vec3 light_dir_loc = normalize( nv_position - light_loc );
v_light_tan[index] = vec3(
dot( nv_tangent.xyz, light_dir_loc ),
dot( bitangent, light_dir_loc ),
dot( nv_normal, light_dir_loc )
);
}
...两个独立的循环,工作。添加#pragma optionNV(unroll all)
也可以。
这两个看起来都很糟糕,因为这是一个如此简单的循环示例。 GLSL 是否已损坏,或者我是否错过了编写GLSL循环的规则或指南?
如果相关:
OpenGL Vendor : NVIDIA Corporation
OpenGL Renderer : GeForce GTX 690/PCIe/SSE2
OpenGL Version : 4.4.0
OpenGL GLSL Version : 4.40 NVIDIA via Cg compiler