2012-11-08 44 views
12

当我用我的着色器,我得到以下结果: enter image description hereGLSL镜面照明

enter image description here

的一个问题是,镜面光是有点变形,你可以看到球三角形,另一种是,我能请参阅我不应该看到的镜面反射(第二幅图像)。一个spehere light在顶点着色器中完成,另一个在片段中完成。

这里是我的顶点着色器的光看起来像: 顶点:

// Material data. 
uniform vec3 uAmbient; 
uniform vec3 uDiffuse; 
uniform vec3 uSpecular; 
uniform float uSpecIntensity; 
uniform float uTransparency; 

uniform mat4 uWVP; 
uniform mat3 uN; 
uniform vec3 uSunPos; 
uniform vec3 uEyePos; 
attribute vec4 attrPos; 
attribute vec3 attrNorm; 
varying vec4 varColor; 

void main(void) 
{ 
    vec3 N = uN * attrNorm; 
    vec3 L = normalize(uSunPos); 
    vec3 H = normalize(L + uEyePos); 
    float df = max(0.0, dot(N, L)); 
    float sf = max(0.0, dot(N, H)); 
    sf = pow(sf, uSpecIntensity); 

    vec3 col = uAmbient + uDiffuse * df + uSpecular * sf; 
    varColor = vec4(col, uTransparency); 
    gl_Position = uWVP * attrPos; 
} 

片段:

varying vec4 varColor; 

void main(void) 
{ 

    //vec4 col = texture2D(texture_0, varTexCoords); 
    //col.r += uLightDir.x; 
    //col.rgb = vec3(pow(gl_FragCoord.z, 64)); 
    gl_FragColor = varColor; 

} 

这是可能的,从我的代码提供的数据是错误的。uN是世界矩阵(不倒置,不转置,即使这样做似乎没有任何不同)。 UWVP - 世界观投影矩阵。

任何想法,至于问题可能在哪里,将不胜感激。

[编辑]这里是我的光计算在片段完成: 顶点着色器文件:

uniform mat4 uWVP; 
uniform mat3 uN; 
attribute vec4 attrPos; 
attribute vec3 attrNorm; 
varying vec3 varEyeNormal; 

void main(void) 
{ 
    varEyeNormal = uN * attrNorm; 
    gl_Position = uWVP * attrPos; 
} 

片段着色器文件:

// Material data. 
uniform vec3 uAmbient; 
uniform vec3 uDiffuse; 
uniform vec3 uSpecular; 
uniform float uSpecIntensity; 
uniform float uTransparency; 

uniform vec3 uSunPos; 
uniform vec3 uEyePos; 
varying vec3 varEyeNormal; 

void main(void) 
{ 
    vec3 N = varEyeNormal; 
    vec3 L = normalize(uSunPos); 
    vec3 H = normalize(L + uEyePos); 

    float df = max(0.0, dot(N, L)); 
    float sf = max(0.0, dot(N, H)); 
    sf = pow(sf, uSpecIntensity); 

    vec3 col = uAmbient + uDiffuse * df + uSpecular * sf; 

    gl_FragColor = vec4(col, uTransparency); 
} 

[EDIT2]随着乔金指出,我没”在片段着色器中规范化varEyeNormal。修复之后,片段着色器的结果会更好。我也在uEyePos上使用了标准化功能,所以镜面不再变黑。感谢所有的帮助。

enter image description here

+0

我相信你应该否定你的法线。(在黑暗一侧的亮点) –

+0

像这样:vec3 negNormal = vec3(-attrNorm.x,-attrNorm.y,-attrNorm.z); vec3 N = uN * negNormal; ?有了这个,我根本没有看到镜面反射。 – SMart

+0

我在谈论第二张照片,如果镜面反射也是正面的,漫反射光应该是正面的。你可以做一个jsfiddle吗? –

回答

19

简短的回答:您需要在片段着色器正常化varEyeNormal,而不是在顶点着色器。

较长的答案: 为了获得平滑的照明,您将需要计算每个像素的法线而不是每个顶点的法线。顶点着色器中计算的变化在传递给片段着色器之前进行线性插值,这在某些情况下可以作为捷径,但在其他情况下更糟。

您看到三角形边缘的原因是由于法线之间的插值导致顶点之间的所有像素中的短于1.0法线。

要纠正此问题,您需要规范片段着色器中的法线而不是顶点着色器中的法线。

的普通矩阵应该是模型视图矩阵,其相当于的模型变换矩阵的上3×3的逆的转置的上部的3x3如果模型变换仅包含旋转和平移(没有缩放)

欲了解更多有关标准列表,请参阅:http://www.lighthouse3d.com/tutorials/glsl-tutorial/the-normal-matrix/

(编辑根据下面评论的正确性。)

+5

你有关正常矩阵的观点是错误的。它是模型视图矩阵的上3x3的反**和**转置。因此,如果模型视图矩阵只有旋转和平移,它与模型视图矩阵的上3x3完全相同(因为反转和转置抵消了旋转,并且翻译仍然存在),这可能是为什么它没有做到这一点,对OP进行反转 - 转置不会有任何不同。 –

+2

你是对的,我编辑了我的答案 –