我正在开发一个小型OpenGL引擎,目前仍然遇到以下GLSL问题:
我正在尝试为多个灯光实现一个着色器,它会生成正确的结果,但前提是我将漫反射光的计算放在一个(完全没用的)if语句中。始终正确渲染specultar light组件。
使用:
for( int i = 0; i < uNumLights; ++i ) {
//...
if( <anything> == <something> ) {
lDiffuseLight += vAmbientDiffuseMaterial * uLights[i].color * lIntensity;
}
}
不起作用:
for( int i = 0; i < uNumLights; ++i ) {
//...
lDiffuseLight += vAmbientDiffuseMaterial * uLights[i].color * lIntensity;
}
此外,如果我在循环条件中使用常量而不是均匀,则无效。
为什么代码与if工作而没有if?如何在没有愚蠢的陈述的情况下使我的着色器工作?
完整的着色器代码:
顶点着色器:
#version 330
const int MAX_LIGHTS = 4;
in vec3 iVertex;
in vec3 iNormals;
uniform mat4 uModelView;
uniform mat4 uMVP;
uniform mat3 uNormal;
smooth out vec3 vPosition;
smooth out vec3 vModelView;
smooth out vec3 vNormals;
// Colors...
smooth out vec3 vAmbientDiffuseMaterial; // Make some colors...
smooth out vec3 vAmbientLight;
smooth out vec3 vLightDirection[MAX_LIGHTS];
uniform vec3 uAmbientColor;
uniform int uNumLights;
uniform struct Light {
vec3 color;
vec3 position;
} uLights[MAX_LIGHTS];
void main(void) {
vAmbientDiffuseMaterial = clamp(iVertex, 0.0, 1.0);
vAmbientLight = vAmbientDiffuseMaterial * uAmbientColor;
gl_Position = uMVP * vec4( iVertex.xyz, 1.0 );
vPosition = gl_Position.xyz;
vNormals = normalize( uNormal * iNormals );
vModelView = ( uModelView * vec4( iVertex , 1 )).xyz;
for( int i = 0; i < uNumLights; ++i ) {
vLightDirection[i] = normalize( uLights[i].position - vModelView );
}
}
片段着色器:
#version 330
const int MAX_LIGHTS = 4;
uniform mat4 uModelView;
out vec4 oFinalColor;
smooth in vec3 vPosition;
smooth in vec3 vModelView;
smooth in vec3 vNormals;
smooth in vec3 vAmbientDiffuseMaterial;
smooth in vec3 vAmbientLight;
smooth in vec3 vLightDirection[MAX_LIGHTS];
// Light stuff
uniform int uNumLights;
uniform struct Light {
vec3 color;
vec3 position;
} uLights[MAX_LIGHTS];
const vec3 cSpecularMaterial = vec3( 0.9, 0.9, 0.9 );
const float cShininess = 30.0;
void main(void) {
vec3 lReflection, lSpecularLight = vec3( 0 ), lDiffuseLight = vec3( 0 );
float lIntensity;
// Specular Light
for( int i = 0; i < uNumLights; ++i ) {
lReflection = normalize( reflect( -vLightDirection[i], vNormals) );
lIntensity = max( 0.0, dot( -normalize(vModelView), lReflection ) );
lSpecularLight += cSpecularMaterial * uLights[i].color * pow( lIntensity, cShininess );
// Diffuse Light
lIntensity = max( 0, dot( vNormals, vLightDirection[i] ) );
// Here is the strange if part:
// Only with the if lDiffuseLight is what it is supposed to be.
if( uLights[i].color != vec3( 0, 0, 0 ) ) {
lDiffuseLight += vAmbientDiffuseMaterial * uLights[i].color * lIntensity;
}
}
oFinalColor = vec4( vAmbientLight + lDiffuseLight + lSpecularLight, 1 );
}
我测试了所有制服,并且它们在着色器中都设置正确。