概述
很多时候,向规则的事物里添加一些“杂乱无章”的效果往往会有意想不到的效果。而这些“杂乱无章”的效果来源就是噪声。在本章中,我们将会学习如何使用噪声来模拟各种看似“神奇”的特效。
噪声应用
1.模拟火焰的消融效果
消融(dissolve)效果常见于游戏中的角色死亡、地图烧毁等效果。在这些效果中,消融往往从不同的区域开始,并向看似随机的方向扩张,最后整个物体都将消失不见。
要实现上图中的效果,原理非常简单,概括来说就是噪声纹理+透明度测试
。
- 使用对噪声纹理采样的结果和某个控制消融程度的阈值比较。
- 如果小于阈值,就使用clip函数把它对应的像素裁剪掉,这些部分就对应了图中被“烧毁”的区域。
- 而镂空区域边缘的烧焦效果则是将两种颜色混合,再用pow函数处理后,与原纹理颜色混合后的结果。
噪声纹理:
使用不同的噪声和纹理属性(即材质面板上纹理的Tiling和Offset值)都会得到不同的消融效果。因此,要想得到好的消融效果,也需要美术人员提供合适的噪声纹理来配合。
Shader关键代码:
Shader "ShaderBook/Chapter15/Dissolve" {
Properties {
//控制消融程度,当值为0时,物体为正常效果,当值为1时,物体会完全消融
_BurnAmount ("Burn Amount", Range(0.0, 1.0)) = 0.0
//控制模拟烧焦效果时的线宽,它的值越大,火焰边缘的蔓延范围越广
_LineWidth("Burn Line Width", Range(0.0, 0.2)) = 0.1
//火焰边缘的两种颜色值
_BurnFirstColor("Burn First Color", Color) = (1, 0, 0, 1)
_BurnSecondColor("Burn Second Color", Color) = (1, 0, 0, 1)
//噪声纹理
_BurnMap("Burn Map", 2D) = "white"{
}
......
}
SubShader {
Tags {
"RenderType"="Opaque" "Queue"="Geometry"}
Pass {
Tags {
"LightMode"="ForwardBase" }
Cull Off //消融会导致裸露模型内部的构造,如果只渲染正面会出现错误的结果
CGPROGRAM
......
fixed4 frag(v2f i) : SV_Target {
//对噪声纹理进行采样
fixed3 burn = tex2D(_BurnMap, i.uvBurnMap).rgb;
//并将采样结果和用于控制消融程度的属性_BurnAmount相减,传递给clip函数
clip(burn.r - _BurnAmount);//当结果小于0时,该像素将会被剔除,从而不会显示到屏幕上
//计算漫反射:略
//在宽度为_LineWidth的范围内模拟一个烧焦的颜色变化
//使用smoothstep函数来计算混合系数 t
//当 t值为1时,表明该像素位于消融的边界处
//当 t值为0时,表明该像素为正常的模型颜色,而中间的插值则表示需要模拟一个烧焦效果。
fixed t = 1 - smoothstep(0.0, _LineWidth, burn.r - _BurnAmount);
//根据混合系数计算烧焦颜色burnColor
fixed3 burnColor = lerp(_BurnFirstColor, _BurnSecondColor, t);
burnColor = pow(burnColor, 5);
......
//再次使用t来混合正常的光照颜色(环境光+漫反射)和烧焦颜色
//使用step函数来保证当_BurnAmount为0时,不显示任何消融效果
fixed3 finalColor = lerp(ambient + diffuse * atten, burnColor, t *