2013-05-10 61 views
2

我有一個相當簡單的片段着色器,用於處理多個燈光的情況(爲清晰起見,下面的代碼被修剪下來,只顯示兩個燈光)。vec4中片段着色器的GLSL性能問題添加

廣泛的想法是總結每個片段的各種照明貢獻,並且它工作正常,但是我發現它在我的硬件(Android HTX Desire X)上不穩定。

測量FPS,很明顯的,有這是造成FPS 10。

砸什麼引起這樣一個看似簡單的操作這樣的表現打出單vec4相加行?

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

分支導致這種情況。避免使用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; 

即使你不這樣做,不要擔心,如果你會計算一些數值需要它。由於着色器並行執行,所以不能比最慢的實例快得多。

此外,您應該儘可能多地將頂點着色器移動到頂點着色器中,因爲它只會針對每個頂點vs片段着色器中的每個像素執行一次;基本上就計算出(三)在頂點着色器內插以及一切並將其傳遞作爲varyings:

  • 位置和顏色的光
  • 載體L,V和H(在這個例子中至少)
+0

*「不要擔心,即使你不需要它也會計算一些值。由於着色器並行執行,所以不能比最慢的實例快得多。」 - 是的,在相同的就像分支版本會做的一樣。並不是分支就是邪惡,只是不必要的計算可能會完成,就像在無分支版本中一樣,除了基於分支的版本可能會阻止計算,如果整個分支沒有分支,而無分支版本將會始終做所有的操作。 – 2013-11-18 21:15:18

+0

這是非常有用的 - 將碎片着色器中的一些冗餘代碼移動到頂點着色器中,這是非常有用的。減去如果/然後調用。 – bevis 2013-11-20 14:55:57