前言
最近学长要求我实现一个斧头砍手的恐怖效果,在网上找血液特效的时候看到了一个很有意思的屏幕血液渐融的效果,点击这里,其中用到了“噪声”这个概念。乐乐女神的《Unity Shader入门精要》也用噪声实现了一些特效,但是书里对于噪声的使用只简单的停留在对现有噪声纹理进行采样,并没有详细讲解什么是噪声,噪声的分类,噪声贴图又是如何制作的。上面提到的血液渐融的博客就提到了Value Noise(连续噪声)的概念,我随后就查阅相关资料学习了一下,发现噪声真的是一个有趣而且神奇的东西。下面我主要记录一下我对Perlin Noise和Worley Noise这两个常见的噪声,并在Unity中实现了几个简单的效果。
Perlin Noise(柏林噪声)
柏林噪声是一种梯度噪声,对于白噪声,连续噪声,梯度噪声这些概念具体描述大家可以看看这篇文章。这里我就简单说一下,白噪声就是没有什么规律的噪声,每一点都是由伪随机数得出的,点与点之间没有什么关联。连续噪声就是点与点之间的噪声值是连续变化的,梯度噪声就是加入梯度概念的特殊的连续噪声,与传统的像是块状的连续噪声相比它渐变的更加自然和平滑。柏林噪声可以用来模拟一些连续的东西,比如说我之前提到的血液渐融效果的血液。我们可以通过柏林噪声算法得出的噪声值决定片元的剔除,这样就可以模拟出一个很简单的渐融效果,我在Unity中用一个Quad模拟了这个效果,效果图如下
但是可以发现,消融的血迹边角太过圆润,看起来像是缺少点细节,我们可以用分形布朗运动为噪声添加细节。最终效果图如下
shader代码如下
Shader "MyShader/PerlinNoise"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_Fade("Fade", Range(-1, 1)) = 1
_Density("Density", Float) = 6
}
SubShader
{
Tags {
"RenderType"="Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct a2v
{
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
fixed4 _Color;
fixed _Fade;
float _Density;
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord.xy;
return o;
}
fixed2 randVec(fixed2 value)
{
fixed2 vec = fixed2(dot(value, fixed2(127.1, 337.1)),