数组和条件的奇怪GLSL行为

时间:2015-01-04 15:52:06

标签: opengl glsl shader fragment-shader vertex-shader

我正在开发一个小型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 );
}

我测试了所有制服,并且它们在着色器中都设置正确。

0 个答案:

没有答案