我已经运行了这个简单的GLSL着色器,它为模型提供了每片段照明。一切正常,但当我尝试为我的场景使用多个光源时会出现问题。为了使用许多光源进行每片段照明,必须循环通过光源阵列,计算每个Ambient,Diffuse和Specular颜色的贡献并将这些值相加。现在,当我将灯光属性的变量改为数组时,性能急剧下降。
查看以下片段着色器:
#version 130
#define MAX_LIGHT_COUNT 8
int lSourcesCount;
float lIntensity[MAX_LIGHT_COUNT];
vec3 lPosition[MAX_LIGHT_COUNT];
vec3 lDirection[MAX_LIGHT_COUNT];
vec3 lAmbient[MAX_LIGHT_COUNT];
vec3 lDiffuse[MAX_LIGHT_COUNT];
vec3 lSpecular[MAX_LIGHT_COUNT];
float mShininess;
vec3 mAmbient;
vec3 mDiffuse;
vec3 mSpecular;
#if __VERSION__ > 130
in vec4 InterPosition;
in vec3 InterNormal;
in vec4 InterColor;
out vec3 gl_FragColor;
#else
varying vec4 InterPosition;
varying vec4 InterColor;
varying vec3 InterNormal;
#endif
void set_temp_light_values()
{
lSourcesCount = 1;
lPosition[0] = vec3(0.0, 2.0, -2.0);
lAmbient[0] = vec3(0.3, 0.3, 0.3);
lDiffuse[0] = vec3(0.5, 0.5, 0.5);
lSpecular[0] = vec3(0.8, 0.8, 0.8);
mShininess = 16;
mAmbient = vec3(0.1, 0.1, 0.1);
mDiffuse = vec3(0.5, 0.5, 0.5);
mSpecular = vec3(0.8, 0.8, 0.8);
}
void main()
{
set_temp_light_values();
vec3 normal = normalize(InterNormal);
int i = 0;
vec3 surfaceToLight = normalize(lPosition[i] - InterPosition.xyz);
vec3 cameraToSurface = normalize(-lPosition[i].xyz);
float diffuseCont = max(dot(normal, surfaceToLight), 0);
vec3 reflection = -reflect(surfaceToLight, normal);
float specularCont = max(dot(reflection, cameraToSurface), 0);
specularCont = pow(specularCont, mShininess);
vec3 ambient = lAmbient[i] * mAmbient;
vec3 diffuse = (lDiffuse[i] * mDiffuse) * diffuseCont;
vec3 specular = (lSpecular[i] * mSpecular) * specularCont;
gl_FragColor = vec4(ambient + diffuse + specular, 1.0);
}
这一行特别是int i = 1;
是我的光源的索引,我将在for循环中使用循环。使用const int i = 1;
显然会导致编译器优化数组,而只是改变变量。如果没有const
,程序FPS会从100以上下降到20。
为什么GLSL着色器中的数组如此慢,以及使用多个光源而不会受到这种减速影响的解决方法是什么?