学习教程来自:【技术美术百人计划】图形 3.3 曲面细分与几何着色器 大规模草渲染
Unity版本:Unity 2019.3.15f1
感谢老师的传道授业解惑,本篇用于总结复习和实践
1. 知识基础
TESS能做什么?
将曲面细分:直线逼近曲线、正方体细分成球体
增加凹凸感,与置换贴图结合使用
- 优化:根据既定规则(如,距离)控制细分面数
GS能做什么?
几何动画:爆炸破碎效果
草地生成
OpenGL中的着色顺序
2. TESS
pragma hull hullProgram
pragma domain ds
输入输出
输入Patch,将图元细分,输出细分后的顶点
流程
HULL Shader:设定参数;对输入进行变化(若需要)
Tessellation Primitive Generation:细分操作
Domain Shader:空间转换
vert函数(不是顶点着色器 )对顶点进行了变化 顶点替换的vert函数
使用切线空间矩阵将法线转换回世界空间
3. GS
pragma geometry geo
输入输出
均为图元,输出的图元需要按顺序逐顶点构建
几何着色器函数
4. TESS和GS结合使用
生成一个更加接近实际的模拟草地
几何着色器部分
生成一棵草
顶点从下往上添加,一共 SEGMENT * 2 + 1 个点 草的弯曲(bend)和朝向(wind+facing)
最下边的2个点只考虑朝向 草的密度调整
在HullShader部分基于距离调整参数 效果
5. 课后作业
基于草的效果,尝试实现物体在草地上运动时产生的交互。
思路
这里使用了一个圆形小球作为运动的物体,小球下方的草地会被压平(height降低),未被压平但在小球周围的物体,会收到挤压向周围弯曲(facing和bend),并且这些与小球产生接触的草,收到风的影响会降低(wind)。
因此需要在几何着色器中重新计算以上的变化矩阵,基于当前小球在世界空间下的位置。
height
disFactor 为世界空间下的顶点与小球的距离
underFactor 为判断是否草在正下方
disFactor = compileFactor(_TestLocation,vWorldPos);
underFactor = disFactor < 0.6 ? 0.2 * disFactor : 1;
height = height * disFactor * underFactor;
facing
计算一个朝向,使周围的小草都朝向小球(只考虑XZ平面,从-Z方向开始超箭头方向一周,return的值从0变化到2PI,用arccos可求得)
float compileFacingFactor(float3 xPos, float3 yPos){
float x = yPos.x-xPos.x;
float z = yPos.z-xPos.z;
float t = 0;
if(x < 0){
x = -x;
z = -z;
t = UNITY_PI;
}
return acos(dot(float3(0, 0, -1),normalize(float3(x, 0, z)))) + t;
}
facingFactor = compileFacingFactor(_TestLocation,vWorldPos);
facingRotationMatrixCus = AngleAxis3x3(facingFactor, float3(0, 0, 1));
bend
按距离增加了弯曲程度(不太严谨,应该离得越近越弯曲)
forwardFactor = 2;
bendRotationMatrixCus = AngleAxis3x3(forwardFactor * disFactor * _BendRotationRandom * UNITY_PI * 0.5, float3(-1, 0, 0));
wind
越近受到风的影响越小
windFactor = 0.5;
windRotationCus = AngleAxis3x3(UNITY_PI * windSample * windFactor * disFactor, wind);