我遇到了一個問題,我認爲這個問題與優化PowerVR GPU的GLSL編譯有關。在Adreno和Tegra GPU上,片段着色器工作得很好,但是在PowerVR(Motorola Droid)上,它在條件語句中產生了不正確的結果。 我通過更改片段着色器代碼中的條件語句解決了問題。我已經添加了else
塊,而不是在塊if
的塊中調用return
塊,現在它在PowerVR上正常工作。PowerVR GPU上的着色器執行流問題
兩種着色器的邏輯都是完全相同的,在兩種情況下都設置爲gl_FragColor
。 請解釋PowerVR OpenGL驅動程序的這種行爲,以便將來避免出現問題。爲什麼它以這種方式處理條件語句?
這裏是舊片段着色器,其工作方式不正確有關的PowerVR圖形芯片:
precision mediump float;
varying vec3 vNormal;
varying vec3 vViewVec;
varying vec2 vTextureCoord;
uniform sampler2D sTexturePumpkin;
void main(void)
{
const float sheen = 0.68;
const float noiseScale = 0.05;
const float furriness = 10.0;
const vec4 lightDir = vec4(0.267260, 0.267260, -0.925820, 0.0);
vec4 color = texture2D(sTexturePumpkin, vTextureCoord/*vec2(0.0,0.0)*/);
if(vTextureCoord.y > 0.7) { // in this case PowerVR displays incorrect color
gl_FragColor = color;
return;
}
float diffuse = 0.5 * (1.0 + dot(vNormal, vec3(lightDir.x, lightDir.y, -lightDir.z)));
float cosView = clamp(dot(normalize(vViewVec), vNormal), 0.0, 1.0);
float shine = pow(1.0 - cosView * cosView, furriness);
gl_FragColor = (color + sheen * shine) * diffuse; // in this case PowerVR works correctly
}
新片段着色器的代碼,這對雙方的Adreno以及PowerVR GPU正常工作:
precision mediump float;
varying vec3 vNormal;
varying vec3 vViewVec;
varying vec2 vTextureCoord;
uniform sampler2D sTexturePumpkin;
void main(void)
{
const float sheen = 0.68;
const float noiseScale = 0.05;
const float furriness = 10.0;
const vec4 lightDir = vec4(0.267260, 0.267260, -0.925820, 0.0);
vec4 color = texture2D(sTexturePumpkin, vTextureCoord/*vec2(0.0,0.0)*/);
if(vTextureCoord.y > 0.7) {
gl_FragColor = color;
}
else {
float diffuse = 0.5 * (1.0 + dot(vNormal, vec3(lightDir.x, lightDir.y, -lightDir.z)));
float cosView = clamp(dot(normalize(vViewVec), vNormal), 0.0, 1.0);
float shine = pow(1.0 - cosView * cosView, furriness);
gl_FragColor = (color + sheen * shine) * diffuse;
}
}
它看起來像一個驅動程序錯誤。驅動程序錯誤,作爲錯誤,並不是真的可以「解釋」的東西。他們只是發生,而你處理它們。 –
您可以使用vec3(lightDir.xy,-lightDir.z)。 – Jessy
@NicolBolas我相信這不是GLSL編譯器中的錯誤,而是基於PowerVR GPU瓦片渲染和片段着色器執行的特殊性。我想在下面回答一些批評者。 – keaukraine