gpt4 book ai didi

opengl - 如何在 OpenGL 中为 Phong 着色插值法线?

转载 作者:行者123 更新时间:2023-12-02 09:04:27 24 4
gpt4 key购买 nike

目前,我正在实现良好的旧 Phong 着色。总的来说,它看起来很正确,但法线中出现了一种我无法解释的模式。

如果不仔细观察,Stanford Bunny我认为看起来很正确。 enter image description here

但是例如在耳朵上有一个奇怪的图案: enter image description here

在这张图片中,我可视化了法线并提高了饱和度以使问题更加明显。 enter image description here

这是我的顶点着色器:

#version 330 core

layout (location = 0) in vec4 vPosition;
layout (location = 1) in vec3 vNormal;

out vec4 fWorldPosition;
smooth out vec3 fWorldNormalSmooth;

...

void main() {
fWorldNormalSmooth = normalize(NormalMatrix*vNormal);
fWorldPosition = WorldMatrix*vPosition;
gl_Position = ProjectionMatrix*ViewMatrix*WorldMatrix*vPosition;
}

这是我的片段着色器:

#version 330 core

smooth in vec3 fWorldNormalSmooth;
in vec4 fWorldPosition;

out vec4 color;

...

vec4 shadePointLight(Material material, PointLight pointLight, vec3 worldPosition, vec3 worldNormal) {
vec3 cameraPosition = wdiv(inverse(ViewMatrix)*vec4(0, 0, 0, 1));
vec3 cameraDirection = normalize(cameraPosition - worldPosition);
vec3 lightDirection = normalize(pointLight.position - worldPosition);
vec3 reflectionDirection = reflect(-lightDirection, worldNormal);

vec4 i_amb = material.ambientReflection*pointLight.ambientColor;
vec4 i_diff = max(0, dot(worldNormal, lightDirection))*material.diffuseReflection*pointLight.diffuseColor;
vec4 i_spec = pow(max(0, dot(reflectionDirection, cameraDirection)), material.shininess)*material.specularReflection*pointLight.specularColor;

float distance = length(pointLight.position - worldPosition);
float d = 1.0 / (pointLight.falloff.constant + pointLight.falloff.linear*distance + pointLight.falloff.quadratic*distance*distance);

return i_amb + d*(i_diff + i_spec);
}

void main() {
...

color = shadePointLight(material, pointLight, wdiv(fWorldPosition), normalize(fWorldNormalSmooth));
}

有人可以解释一下这种行为吗?

最佳答案

当在两个相同长度的向量之间进行线性插值时,就像在顶点和片段阶段之间发生的那样,所得向量的长度在两者之间会更短。在两个法线之间进行插值的数学上正确的方法是执行 spherical linear interpolation (SLERP),但是对于角度的微小变化,您可以简单地在片段着色器中标准化插值法向量(这是因为小角度近似值sin(x) ≈ x 对于小x)。 编辑:对于更大的角度,需要通过适当的 SLERP 插值。

关于opengl - 如何在 OpenGL 中为 Phong 着色插值法线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38070899/

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