计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(一)过程式凹凸贴图
1. 增强表面细节
我们想要展现不规则表面的物体,例如橘子凹凸的表面、葡萄干褶皱的表面或月球的陨石坑表面。
有以下办法:
- 该物体模型本身就具有凹凸的表面,这种方式最直接,但这样的模型会非常复杂,而且可能无法制作,同时由于顶点数目太多,可能无法在GPU上渲染。
- 用一个纹理贴图来表示表面的凹凸,这种方式最简单,但由于纹理贴图是静态的,所以无法表现动态的物体。同时由于光照变化的,也会给人不真实的感觉。
- 采用过程式凹凸贴图、法线贴图等方式,这种方式比较合适,顶点数并没有额外增加,同时又能适应光照变化。即如果 我们想让一个物体看起来好像有凹凸(或皱纹、坑洼等),通过计算表面确实凹凸不平时其上的法向量。当场景被照亮时,光照会让人产生我们所期望的“幻觉”。
1.1. 过程式凹凸贴图
过程式凹凸贴图是一种在3D图形渲染中用于增强表面细节的技术,它通过数学函数或算法来动态计算表面法线的扰动,从而在不增加几何复杂度的情况下创造出表面凹凸的视觉效果。
1.1.1. 主要特点:
-
动态计算
- 不需要预先制作纹理图
- 可以实时生成表面细节
- 能够创造出动态变化的效果
-
资源效率
- 不增加模型的多边形数量
- 内存占用小
- GPU负载相对较低
-
灵活性
- 可以通过修改算法参数来调整效果
- 适合生成规则的纹理模式
- 可以与其他贴图技术结合使用
1.1.2. 工作原理:
- 在着色器中通过数学函数计算法线偏移
- 修改原始法线方向
- 使用修改后的法线进行光照计算
- 产生凹凸的视觉效果
1.1.3. 常见应用:
- 水面波纹效果
- 规则的网格纹理
- 程序化生成的地形细节
- 动态的表面扰动
与传统的凹凸贴图相比,过程式凹凸贴图更适合表现动态变化的表面效果,并且不受贴图分辨率的限制。
1.1.4. 顶点着色器
originalVertPos = vertPos; // 保存原始顶点位置
1.1.5. 片段着色器
核心代码是计算新的法线向量,一种方式是取该顶点的原始模型顶点坐标(即新的变量x,y,z)与经过插值后的法线向量进行运算,另一种方式是将x,y,z设置成其它值 。
void main(void)
{ // 标准化光照计算所需的向量vec3 L = normalize(varyingLightDir); // 光源方向向量//vec3 N = normalize(varyingNormal); // 表面法线向量float x=originalVertPos.x;float y=originalVertPos.y; float z=originalVertPos.z;// float x=varyingNormal.x;// float y=varyingNormal.y; // float z=varyingNormal.z;float a=0.25f;float b=100;vec3 N=normalize(varyingNormal+vec3(a*sin(b*x),a*sin(b*y),a*sin(b*z)));//...
}
下图是采用如下代码:
float x=originalVertPos.x;float y=originalVertPos.y; float z=originalVertPos.z;
[外链图片转存中…(img-y4Vo0ykS-1747196284759)]
下图是采用如下代码:
float x=varyingNormal.x;float y=varyingNormal.y; float z=varyingNormal.z;
[外链图片转存中…(img-OTprK0HM-1747196284759)]
1.2. 参考
- 学习笔记完整代码下载
- OpenGL shader开发实战学习笔记:第十章 法线贴图_法线贴图是什么意思-CSDN博客