Opengl-法线贴图(用来细化表面的表现表现的凹凸)

Posted lijianming180

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Opengl-法线贴图(用来细化表面的表现表现的凹凸)相关的知识,希望对你有一定的参考价值。

技术图片

我们通过这张图可以看出来,使用了法线贴图的物体表面更有细节更逼真,其实这就是发现贴图的作用,没什么钻牛角尖的。

技术图片

其实表面没有凹凸的情况是因为我们把表面一直按照平整来做的,要想突出这个表面的凹凸就要用到法线贴图

到这里,我们暂停想一下,前面说的几种贴图,漫反射贴图,镜面光贴图,然后再到这个法线贴图。明白了什么?其实很简单,就是我们法线虚拟的和现实的差距就会通过这种贴图的形式来着重表现某一方面的效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#version 330 core
out vec4 FragColor;

in VS_OUT {
vec3 FragPos;
vec2 TexCoords;
vec3 TangentLightPos;
vec3 TangentViewPos;
vec3 TangentFragPos;
} fs_in;

uniform sampler2D diffuseMap;
uniform sampler2D normalMap;

uniform vec3 lightPos;
uniform vec3 viewPos;

void main()
{
// obtain normal from normal m 大专栏  Opengl-法线贴图(用来细化表面的表现表现的凹凸)ap in range [0,1]
vec3 normal = texture(normalMap, fs_in.TexCoords).rgb;
// transform normal vector to range [-1,1]
normal = normalize(normal * 2.0 - 1.0); // this normal is in tangent space

// get diffuse color
vec3 color = texture(diffuseMap, fs_in.TexCoords).rgb;
// ambient
vec3 ambient = 0.1 * color;
// diffuse
vec3 lightDir = normalize(fs_in.TangentLightPos - fs_in.TangentFragPos);
float diff = max(dot(lightDir, normal), 0.0);
vec3 diffuse = diff * color;
// specular
vec3 viewDir = normalize(fs_in.TangentViewPos - fs_in.TangentFragPos);
vec3 reflectDir = reflect(-lightDir, normal);
vec3 halfwayDir = normalize(lightDir + viewDir);
float spec = pow(max(dot(normal, halfwayDir), 0.0), 32.0);

vec3 specular = vec3(0.2) * spec;
FragColor = vec4(ambient + diffuse + specular, 1.0);
}

这是一个法线贴图的片段着色器,我们可以看到几个关键的部分。

  1. vec3 normal = texture(normalMap, fs_in.TexCoords).rgb; 我们从法线贴图的纹理中取样像素
  2. 我们从 diffuseMap 中取样 物体纹理图片的原本像素
  3. 然后我们把normal的普通的做了综合得出了最终的FragColor

这里面还有TagnetFragPos什么的不理解没关系,它们是切线空间的一些概念


###切线空间

法线贴图中的法线向量在切线空间中,法线永远指着正z方向。切线空间是位于三角形表面之上的空间:法线相对于单个三角形的本地参考框架。它就像法线贴图向量的本地空间;它们都被定义为指向正z方向,无论最终变换到什么方向。使用一个特定的矩阵我们就能将本地/切线空寂中的法线向量转成世界或视图坐标,使它们转向到最终的贴图表面的方向。
切线空间中的T(tangent),B(Bitangent)与贴图U,V方向一致。 保存方式(T,B,N)


Normal
技术图片


T(tangent)
技术图片


B(Bitangent) = N*T
技术图片


最终效果

技术图片

以上是关于Opengl-法线贴图(用来细化表面的表现表现的凹凸)的主要内容,如果未能解决你的问题,请参考以下文章

✠OpenGL-10-增强表面细节

计算机图形学(OPENGL):法线贴图

一步步学OpenGL 26-《法线贴图》

Unity Shader使用法线贴图(Normal Map)的Shader

WebGL学习之法线贴图

深入理解法线贴图原理