求知若饥,虚心若愚
向规则的事物里添加一些“杂乱无章”的效果往往会有意想不到的效果。而这些“杂乱无章”的效果来源就是噪声。
消融效果
消融(dissolve) 效果常见于游戏中的角色死亡、地图烧毁等效果。在这些效果中,消融往往从不同的区域开始,并向看似随机的方向扩张,最后整个物体都消失不见。
原理:噪声纹理+透明度测试。对噪声纹理采样的结果和某个控制消融程度的阈值比较,如果小于阈值,就使用clip函数把它对应的像素裁剪掉,这部分就对应了“烧毁”的区域。而镂空区域边缘的烧焦效果则是将两种颜色混合,再用pow函数处理后,与原纹理颜色混合的结果。
1 | Shader "Unity Shaders Learn/Chapter15/Dissolve" |
箱子的消融效果
消融效果使用的噪声纹理
水波效果
在模拟实时水面的过程中,也会使用噪声纹理。此时噪声纹理会用作一个高度图,不断修改水面的法线方向。为了模拟水不断流动的效果,会使用和时间相关的变量来对噪声纹理进行采样,当得到法线信息后,再进行正常的反射+折射计算,得到最后的水面波动效果。
下面会使用一个由噪声纹理得到的法线贴图,实现一个包含菲涅尔反射的水面效果。
包含菲涅耳反射的水面波动效果。在左图中,视角方向和水面法线的夹角越大,反射效果越强。在右图中,视角方向和水面法线的夹角越大,折射效果越强
- 和使用反射和折射模拟透明玻璃效果类似。
- 使用立方体纹理(Cubemap)作为环境纹理,模拟反射。
- 用GrabPass获取当前屏幕的渲染纹理,使用切线空间下的法线方向对像素的屏幕坐标进行偏移,再使用该坐标对渲染纹理进行屏幕采样,模拟近似的折射效果。
- 但玻璃效果不一样的是使用噪声纹理来生成水波的法线,随着时间变化不断平移,模拟波光粼粼的效果。另外不使用定值来混合反射和折射颜色,而是用菲涅尔系数来动态决定混合系数:
其中v和n分别对应了视角方向和法线方向,它们之间的夹角越小,fresnel值越小,反射越弱,折射越强。
1 | Shader "Unity Shaders Learn/Chapter15/WaterWave" |
立方体纹理用之前的脚本生成。法线图可以从高度图生成(将贴图类型改为NormalMap,并勾选CreateFromGrayscale)。
水波效果使用的噪声纹理。左图:噪声纹理的灰度图。右图:由左图生成的法线纹理
再谈全局雾效
前面使用深度纹理实现了一种基于屏幕后处理的全局雾效,但它是基于高度的均匀雾效。有时我们希望可以模拟一种不均匀的雾效,同时让雾不断飘动,使雾看起来更加飘渺,这可以通过噪声纹理来实现。
1 | using UnityEngine; |
1 | Shader "Unity Shaders Learn/Chapter15/FogWithNoise" { |
左图:均匀雾效。右图:使用噪声纹理后的非均匀雾效
本节使用的噪声纹理
扩展阅读
噪声纹理可以被认为是一种程序纹理(Procedure Texture),它们都是由计算机利用某些算法生成的。Perlin噪声可以用于生成更自然的噪声纹理,Worley噪声通常用于模拟石头、水、纸张等多孔噪声。
- Perlin噪声:https://en.wikipedia.org/wiki/Perlin_noise
- Worley噪声:https://en.wikipedia.org/wiki/Worley_noise
- Understanding Perlin Noise:http://adrianb.io/2014/08/09/perlinnoise.html
- Worley1998年发表的论文中,有Worley噪声的算法和实现细节
- 很多程序噪声在Unity中的实现:http://scrawkblog.com/category/procedural-noise/ (博客貌似换地址?https://github.com/Scrawk/Procedural-Noise )