因此,基本上我在3d程序中实现了法线贴图,并且遇到了一个问题,即法线贴图似乎只显示在负轴上,而当我接近它时,它偏移并且错了位置。
我尝试做很多事情,包括使用不同的方法,乘以光的方向和相机位置而不是法线贴图,使用转置和倒置的TBN矩阵,检查纹理加载过程并关闭所有可能会造成更多干扰。
这是我的顶点着色器中的主要方法:
gl_Position = ProjectionMatrix * EyeMatrix * ModelMatrix * vec4(Position, 1.0);
texCoords = TexCoords;
position = (ModelMatrix * vec4(Position, 1.0)).xyz;
vec3 n = normalize((ModelMatrix * vec4(Normal, 0.0))).xyz;
vec3 t = normalize((ModelMatrix * vec4(Tangent, 0.0))).xyz;
t = normalize(t - dot(t, n) * n);
vec3 b = cross(t, n);
tbnMatrix = mat3(t, b, n);
这是我计算照明的方式:
vec3 calculatePointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, float energyConservation)
{
vec3 lightDir = normalize(light.position - fragPos);
float diff = max(dot(normal, normalize(lightDir + viewDir)), 0.0);
float spec = energyConservation * pow(max(dot(normal, normalize(lightDir + viewDir)), material.specularIntensity), material.specularDampening);
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.attenuation.constant + light.attenuation.linear * distance +
light.attenuation.quadratic * pow(distance, 2.2));
vec3 ambient = light.baseLight.ambient * vec3(texture(material.texture_diffuse, texCoords));
vec3 diffuse = (light.baseLight.diffuse * light.baseLight.intensity) * diff * vec3(texture(material.texture_diffuse, texCoords));
vec3 specular = (light.baseLight.specular * light.baseLight.intensity) * spec * vec3(texture(material.texture_gloss, texCoords));
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return (ambient + diffuse + specular);
}
这是我的法线贴图的代码:
vec3 normal = normalize(tbnMatrix * (255.0/128.0 * texture(material.texture_normal, texCoords).xyz - 1));
切线如下所示:
使用TBN矩阵时,切线如下所示:
以下是加载的T组件(没有任何版本):
这是B组件(顶点着色器中的B组件):
这是加载的N组件(没有任何版本):
这是没有法线贴图(启用了mipmapping和各向异性过滤)的外观:
(请记住,我也有镜面贴图)
答案 0 :(得分:0)
所以几周后我发现了问题,这是一个非常简单的错误。在纹理加载过程中,我使用的是GL_SRGB
而不是普通的GL_RGB
,并且SRGB是纹理的经过伽马校正的版本,而不是实际的纯图像。因此,我必须选择一个选项来禁用和启用构造函数中的SRGB加载,以用于法线,光泽度和位移贴图,基本上所有屏幕上未显示的内容。