移动端可用的相关的插件有 Aurora Shader
Procedural Aurora 感觉原神的极光是参考这个做的
【Unity Shader】星夜极光 这个是天空盒shader 做成天空盒材质赋值给天空盒即可 移动端性能堪忧 适合3090显卡系列大作
分析 根据PC版这个视频 和 这个视频 的旋转视角的极光表现来看 极光是用面片做的 并且做的很大放在很高的地方去模拟极光,手机就更不用说
关注极光表现请看 这个视频
视频分析
- 随机弯曲: 多顶点Plane物体做顶点动画,顶点动画是sin的变种:对sin()函数的括号里面或者外面乘以0到1的小数来进行波动范围的缩小,在 函数图像绘制工具 里面参考 sin(x) * 0.5 或者 sin(0.5 * x) 的函数图像,然后再在此添加噪声值作为随机偏移
噪声值通过计算得出:相同公式的噪声值需要以模型坐标的z值为基础,这样z值相同的一列顶点才会有相同的随机偏移值 , 通过三角函数的方式得出是个对这种情况适合的方式 参考 sin(x * 0.5) + 2 * cos(x * 0.2) 的函数图像 噪声值通过图得出:噪声图需要是均匀黑白条纹图,保证同一U坐标或者V坐标的顶点读取的噪声图相同,或者是噪声点图,用模型坐标下x值作为U,常数值作为V去读取噪声。 没有加噪声的代码如下所示
posOS.y += sin(_Time.y * _Speed + posOS.z) * _Amp;
用三角函数的方式得到的噪声代码如下所示: 参考公式 sin(x * 0.5) + 2 * cos(x * 0.2) 得到的代码是
posOS.y += 0.1 * sin(_Time.y * _Speed + posOS.z * 5) * _Amp +
0.2 * cos(_Time.y * _Speed + posOS.z * 2) * _Amp;
这里要注意的是_Time.y * _Speed对于每个顶点是相同的 ,x对应的是posOS.z,这个才是每个顶点都不同的自变量
总共可用的公式如下: 2.2 * sin(x * 0.3) + 0.6 * cos(x * 0.7) sin(x * 0.5) + 2 * cos(x * 0.2) 1.2 * sin(x * 0.7) + 3 * cos(x * 0.2) 1.2 * sin(x * 0.7) + 2 * cos(x* 0.4 )
- 底部颜色充实,顶部颜色渐无,且有竖直状条纹:猜测是一张渐变图用了PS做了U或者V方向的类似涂抹的东西,后来给出了原神的极光使用的图
拆开看RGB 可见R是主图,波浪部分那么弯曲是因为面片在这个方向本身会拉伸很大的尺度,所以为了实际上看起来不那么直,图片需要弯曲一些
-
流动:UV流动 -
消失和出现:C#代码控制隐藏随机时间,显示随机时间 -
极光相对于后面的天空显得更加的亮,而不是普通的透明,应该用Blend One One,对于这种混合模式,RGB均为0时显示的是天空颜色,RGB均为1时显示的是天空颜色叠加极光颜色,原因是由混合模式的混合方式决定的,源颜色 * 1加缓冲颜色 * 1 当源颜色均为0时结果等于缓冲颜色 -
极光的上散部分有部分会随着底部主色一起流动,有部分 是不会随着UV流动的,反而会往反方向缓慢流动,通过G或者B去读取然后进行流动,这部分的透明度要小一些 ,上散部分重合后的变亮效果是通过颜色叠加完成 -
用面片模拟的话面片的边缘部分需要过渡否则太生硬 -
出现时是先出现下面的边缘再慢慢由下至上出现竖直长纹图,感觉是G通道和阈值共同控制透明度。消失时也是竖直长纹图先消失然后再下面的边缘消失 : 方法一,传入透明度时有个延迟 方法二,用模型坐标系的x值作为u的方式 读取噪声图 -
变色效果:在极光带随机位置出现,可能出现两处以上,正向或逆向随机延申一定长度, 正向或逆向随机移动一定位置,然后消失,并且变色只出现在极光的直线部分偏上: 读取噪声图的方式,为1的部分显示变色,变色部分是读取是图的G,噪声图的流动采用 -
不同极光隐藏后,他们的重现等待时间不一样,或者说不同极光的消失等待时间不一样,
遇见的问题
更换mesh问题
本来是一平米每条边有30个三角面的正方形面片,后来觉得换成一平米某对边只有一个三角形,另一对边有100个三角形的正方形面片。但是调节形状的时候出现了一些问题,通过在同一物体下快速更换这两个模型的mesh可以看到相同的形状函数,不同的mesh占据的x自变量的区域不同,比如原来的占据了红框这段,新的只占据了绿框这段。 可以猜出新的mesh的顶点的x跨度比原来的要小,乘以相同的系数后才会出现波动范围是原来的一部分的情况,这时需要做的是扩大三角函数中的自变量的取值范围,
float sinValue = _SinyAmplify *
sin(_Time.y * _Speed + posOS.x * _SinxAmplify + _SinStartDelta);
float cosValue = _CosyAmplify *
cos(_Time.y * _Speed + posOS.x * _CosxAmplify + _CosStartDelta );
posOS.y +=
(sinValue + cosValue) * _Amp;
在代码中,扩大自变量范围最明显的方式是_SinxAmplify 和_CosxAmplify 扩大。
范围值超出的问题
在另个URP项目中正常运行的极光,到了公司demo时,彩色极光的部分就出现问题了, 两个项目相同的shader代码相同的设置 后面将彩色极光的噪声Scale还原为1,不进行从(0,1)到(-1,1)的范围映射,再保留01部分的操作。 直接将读取的颜色值减去0.3, 然后输出的颜色值就差不多黑色了。 但是另个项目减去0.9都还有一些。 因为这个原因,公司demo中正常运行的效果,其他项目可能就还要调一下数值代码
代码
|