使用着色器时,我得到以下结果:


一个问题是镜面反射光有些变形,您可以看到球面三角形,另一个问题是,我可以在不应反射的位置看到镜面反射(第二张图像)。一种顶点照明是在顶点着色器中完成的,另一种是在片段着色器中完成的。

这是我的顶点光着色器的外观:
顶点:

// 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;

}

我提供的代码数据有可能是错误的。
union 国是世界矩阵(不是倒立也不是转置的,即使这样做似乎并没有什么不同)。
UWVP-世界 View 投影矩阵。

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

[编辑]这是我在片段中完成的光照计算:
顶点着色器文件:
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]正如Joakim所指出的,我没有在片段着色器中规范化varEyeNormal。修复该问题之后,片段着色器的结果要好得多。我还在uEyePos上使用了归一化功能,因此镜面反射不再消失。感谢您的所有帮助。

最佳答案

简短的答案:您需要在片段着色器中而不是在顶点着色器中标准化varEyeNormal

更长的答案:
为了获得平滑的照明,您将需要计算每个像素而不是每个顶点的法线。在顶点着色器中计算的变量在传递到片段着色器之前会进行线性插值,在某些情况下,此方法可以用作快捷方式,而在某些情况下,则可以作为快捷方式使用。

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

若要更正此问题,您将需要在片段着色器而不是顶点着色器中对法线进行归一化。

法线矩阵应为Modelview矩阵逆矩阵的转置的高3x3,如果Modelview仅包含旋转和平移(无比例缩放),则它应等于Modelview矩阵的逆矩阵的高3x3

有关法线矩阵的更多信息,请参见:http://www.lighthouse3d.com/tutorials/glsl-tutorial/the-normal-matrix/

(根据下面的评论进行编辑,以确保正确性。)

10-04 20:03