目前,我正在实施良好的旧Phong着色。总的来说,这看起来很正确,但是法线正在出现一种模式,我无法解释。我想,如果不仔细看,Stanford Bunny看起来很正确。但是例如在耳朵上有一个奇怪的模式:在这张照片中,我可视化了法线并提高了饱和度以使问题更明显。这是我的顶点着色器:#version 330 corelayout (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 coresmooth 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)。编辑:对于较大的角度,需要通过适当的SLERP插值。关于opengl - 如何在OpenGL中为Phong着色法线插值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38070899/ 10-09 13:19