vec4上的片段着色器中的GLSL性能问题

时间:2013-05-10 13:15:47

标签: android performance opengl-es fragment-shader

我有一个相当简单的片段着色器,用于处理多个灯光的情况(为了清晰起见,下面的代码被修剪下来,只显示了两个灯光。)

广泛的想法是总结每个片段的各种照明贡献,它工作正常,但我发现它在我的硬件(Android HTX Desire X)上是不稳定的。

测量FPS,很明显有一条vec4附加线导致FPS下降10。

在这样一个看似简单的操作中可能导致这种性能上升的原因是什么?

void main (void)
{
    vec4 v = u_ViewModelMatrix * vec4(v_Vertex, 1.0);
    vec3 nv = normalize(-v.xyz);
    vec3 normalVector = normalize((u_ViewModelTransposeMatrix * vec4(normalize(v_Normal), 0.0)).xyz);

    vec4 finalColour = vec4(0.0, 0.0, 0.0, 1.0);

    // LIGHT 0
    lightPosition = vec4(u_LightData[2], u_LightData[3], u_LightData[4], 1);
    lightColour = vec4(u_LightData[5], u_LightData[6], u_LightData[7], 1.0) * u_LightData[0];

    lightVector = normalize((u_ViewMatrix * lightPosition).xyz - v.xyz);
    halfwayVector = normalize(lightVector + nv);

    facing = dot(normalVector, lightVector);
    if (facing >= 0.0) {
        finalColour = finalColour + diffuseColour * facing * lightColour;
    }

    // LIGHT 1
    lightPosition = vec4(u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+2],
                         u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+3],
                         u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+4],
                         1);
    lightColour = vec4(u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+5],
                       u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+6],
                       u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+7],
                       1.0) * u_LightData[LIGHTS_FLOATS_PER_LIGHT*1];

    lightVector = normalize((u_ViewMatrix * lightPosition).xyz - v.xyz);
    halfwayVector = normalize(lightVector + nv);

    facing = dot(normalVector, lightVector);
    if (facing >= 0.01) {
        vec4 qwe = diffuseColour * facing * lightColour;
// HERE .............
        finalColour = finalColour + qwe;  // takes 10 fps
// HERE ^^^^^^^^^^^^^
    }

    gl_FragColor = finalColour;
}

1 个答案:

答案 0 :(得分:1)

分支导致这种情况。避免使用ifs和for循环。 取代

if (facing >= 0.0) {
    finalColour = finalColour + diffuseColour * facing * lightColour;
}

finalColour += max(0.0, facing) * diffuseColour * lightColour;

if (facing >= 0.01) {
    vec4 qwe = diffuseColour * facing * lightColour;
    // HERE .............
    finalColour = finalColour + qwe;  // takes 10 fps
    // HERE ^^^^^^^^^^^^^
}

finalColour += step(0.01, facing) * facing * diffuseColour * lightColour;

即使您不需要计算某些值,也不要担心。由于着色器是并行执行的,因此不能比最慢的实例快得多。

此外,您应该尽可能多地向顶点着色器移动,因为对于每个顶点和片段着色器中的每个像素,它只执行一次;基本上你计算(tri)在顶点着色器中插值并将其作为变化传递的所有内容:

  • 灯光的位置和颜色
  • 向量L,V和H(至少在该示例中)