2019年初米哈游官方在B站放出一部八重樱的次世代卡通渲染视频,效果可以说是非常惊艳,当我看到八重樱从头发开始溶解,然后变成方块并向上消失的时候不禁发出了:卧槽。八重樱转场效果
后来在github上找到了k神的各种Mesh变换的炫酷效果,想着自己也来实现一下。k神开源项目
实现原理
首先用一张图来回顾一下渲染管线的各个阶段,目前为止我们接触的着色器有顶点着色器和像素着色器,而接触到的渲染管线阶段有:输入装配阶段、顶点着色阶段、光栅化阶段、像素着色阶段、输出合并阶段.:
可以看到,几何着色器是我们在将顶点送入光栅化阶段之前,可以操作顶点的最后一个阶段。它同样也允许我们编写自己的着色器代码。几何着色器可以做如下事情:
1. 让程序自动决定如何在渲染管线中插入/移除几何体;
2. 通过流输出阶段将顶点信息再次传递到顶点缓冲区;
3. 改变图元类型(如输入点图元,输出三角形图元);
也就是说我们可以在几何着色器阶段产生比顶点着色器输入更多的基础图元,从而可以实现各种炫酷的效果。
实现步骤
首先需要用一个脚本来获取模型的MeshRenderer,同时计算产生特效的向量并传给shader。
if (_sheet == null) _sheet = new MaterialPropertyBlock();
var fwd = transform.forward / transform.localScale.z;
var dist = Vector3.Dot(fwd, transform.position);
var vector = new Vector4(fwd.x, fwd.y, fwd.z, dist);
_sheet.SetVector("_EffectVector", vector);
if (_linkedRenderers != null)
foreach (var r in _linkedRenderers) r.SetPropertyBlock(_sheet);
第一步是对模型Mesh上随机选取一些三角面进行重新绘制并进行拉伸操作,其余三角面进行随机的旋转位移和缩小操作。
计算顶点坐标、法线、uv
float3 p0 = input[0].position.xyz;
float3 p1 = input[1].position.xyz;
float3 p2 = input[2].position.xyz;
float3 n0 = input[0].normal;
float3 n1 = input[1].normal;
float3 n2 = input[2].normal;
float2 uv0 = input[0].texcoord;
float2 uv1 = input[1].texcoord;
float2 uv2 = input[2].texcoord;
float3 center = (p0