gpt4 book ai didi

c++ - GLSL 镜面光照

转载 作者:IT老高 更新时间:2023-10-28 23:14:11 27 4
gpt4 key购买 nike

当我使用我的着色器时,我得到以下结果: enter image description here

enter image description here

一个问题是镜面光有点变形,你可以看到球体三角形,另一个问题是,我可以看到我不应该看到的镜面光(第二张图片)。一个球光在顶点着色器中完成,另一个在片段中完成。

这是我的顶点光照着色器的样子:顶点:

// 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] 正如 Joakim 指出的那样,我没有在片段着色器中规范化 varEyeNormal。修复后,片段着色器的结果要好得多。我还在 uEyePos 上使用了 normalize 功能,因此镜面反射不再出现暗面。感谢大家的帮助。

enter image description here

最佳答案

简答:您需要在片段着色器中规范化 varEyeNormal,而不是在顶点着色器中。

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

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

要纠正这个问题,您需要在片段着色器而不是顶点着色器中标准化法线。

Normal 矩阵应该是 Modelview 矩阵的逆转置的上 3x3,如果 Modelview 仅包含旋转和平移(无缩放),则相当于 Modelview 矩阵的上 3x3

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

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

关于c++ - GLSL 镜面光照,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13288838/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com