用于每片段照明的GLSL阵列和多个光源

时间:2015-11-06 12:53:27

标签: opengl glsl

我已经运行了这个简单的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着色器中的数组如此慢,以及使用多个光源而不会受到这种减速影响的解决方法是什么?

0 个答案:

没有答案