法线贴图工作不正确,奇怪的半光效果
Normal mapping working incorrectly, weird half-light effect
我们正尝试在我们的 2D 游戏引擎中实现法线贴图并获得奇怪的效果。
如果像那样手动设置正常
vec3 Normal = vec3(0.0, 0.0, 1.0)
光照正常工作,但我们没有得到我们想要通过法线贴图实现的 "deep" 效果:
但是如果我们使用法线贴图纹理获得法线:vec3 Normal = texture(NormalMap, TexCoord).rgb
它根本不起作用。不该照的照亮,反之亦然(如砖块之间的缝隙)。除此之外,纹理的底部(或顶部,取决于光的位置)一侧有一个暗区。
虽然法线贴图本身的纹理看起来不错:
这是我们的片段着色器:
#version 330 core
layout (location = 0) out vec4 FragColor;
in vec2 TexCoord;
in vec2 FragPos;
uniform sampler2D OurTexture;
uniform sampler2D NormalMap;
struct point_light
{
vec3 Position;
vec3 Color;
};
uniform point_light Light;
void main()
{
vec4 Color = texture(OurTexture, TexCoord);
vec3 Normal = texture(NormalMap, TexCoord).rgb;
if (Color.a < 0.1)
discard;
vec3 LightDir = vec3(Light.Position.xy - FragPos, Light.Position.z);
float D = length(LightDir);
vec3 L = normalize(LightDir);
Normal = normalize(Normal * 2.0 - 1.0);
vec3 Diffuse = Light.Color * max(dot(Normal, L), 0);
vec3 Ambient = vec3(0.3, 0.3, 0.3);
vec3 Falloff = vec3(1, 0, 0);
float Attenuation = 1.0 /(Falloff.x + Falloff.y*D + Falloff.z*D*D);
vec3 Intensity = (Ambient + Diffuse) * Attenuation;
FragColor = Color * vec4(Intensity, 1);
}
还有顶点:
#version 330 core
layout (location = 0) in vec2 aPosition;
layout (location = 1) in vec2 aTexCoord;
uniform mat4 Transform;
uniform mat4 ViewProjection;
out vec2 FragPos;
out vec2 TexCoord;
void main()
{
gl_Position = ViewProjection * Transform * vec4(aPosition, 0.0, 1.0);
TexCoord = aTexCoord;
FragPos = vec2(Transform * vec4(aPosition, 0.0, 1.0));
}
我 google 对此进行了讨论,发现一些人得到了相同的结果,但他们的问题仍未得到解答。
知道是什么原因吗?
法线贴图使用什么纹理格式? SRGB、SNORM 等?这可能是问题所在。试试 UNORM。
此外,由于您没有使用切线 space,请确保平面的 Z 轴与法线的 Z 轴对齐。此外,OGL 以相反的方向读取 Y,因此您需要翻转从法线贴图读取的法线的 Y 坐标。或者,您可以使用反转的 Y 法线贴图(绿色指向下方)。
我们正尝试在我们的 2D 游戏引擎中实现法线贴图并获得奇怪的效果。
如果像那样手动设置正常
vec3 Normal = vec3(0.0, 0.0, 1.0)
光照正常工作,但我们没有得到我们想要通过法线贴图实现的 "deep" 效果:
vec3 Normal = texture(NormalMap, TexCoord).rgb
它根本不起作用。不该照的照亮,反之亦然(如砖块之间的缝隙)。除此之外,纹理的底部(或顶部,取决于光的位置)一侧有一个暗区。
#version 330 core
layout (location = 0) out vec4 FragColor;
in vec2 TexCoord;
in vec2 FragPos;
uniform sampler2D OurTexture;
uniform sampler2D NormalMap;
struct point_light
{
vec3 Position;
vec3 Color;
};
uniform point_light Light;
void main()
{
vec4 Color = texture(OurTexture, TexCoord);
vec3 Normal = texture(NormalMap, TexCoord).rgb;
if (Color.a < 0.1)
discard;
vec3 LightDir = vec3(Light.Position.xy - FragPos, Light.Position.z);
float D = length(LightDir);
vec3 L = normalize(LightDir);
Normal = normalize(Normal * 2.0 - 1.0);
vec3 Diffuse = Light.Color * max(dot(Normal, L), 0);
vec3 Ambient = vec3(0.3, 0.3, 0.3);
vec3 Falloff = vec3(1, 0, 0);
float Attenuation = 1.0 /(Falloff.x + Falloff.y*D + Falloff.z*D*D);
vec3 Intensity = (Ambient + Diffuse) * Attenuation;
FragColor = Color * vec4(Intensity, 1);
}
还有顶点:
#version 330 core
layout (location = 0) in vec2 aPosition;
layout (location = 1) in vec2 aTexCoord;
uniform mat4 Transform;
uniform mat4 ViewProjection;
out vec2 FragPos;
out vec2 TexCoord;
void main()
{
gl_Position = ViewProjection * Transform * vec4(aPosition, 0.0, 1.0);
TexCoord = aTexCoord;
FragPos = vec2(Transform * vec4(aPosition, 0.0, 1.0));
}
我 google 对此进行了讨论,发现一些人得到了相同的结果,但他们的问题仍未得到解答。 知道是什么原因吗?
法线贴图使用什么纹理格式? SRGB、SNORM 等?这可能是问题所在。试试 UNORM。
此外,由于您没有使用切线 space,请确保平面的 Z 轴与法线的 Z 轴对齐。此外,OGL 以相反的方向读取 Y,因此您需要翻转从法线贴图读取的法线的 Y 坐标。或者,您可以使用反转的 Y 法线贴图(绿色指向下方)。