赞
踩
分形布朗运动(Fractal Brownian Motion)也就是fbm,它不是噪声,但是他可以让噪声有更多的细节。可以看成把不同比例位置的一张噪声合并在一起。
- // Properties
- const int octaves = 1;
- float lacunarity = 2.0;
- float gain = 0.5;
- //
- // Initial values
- float amplitude = 0.5;
- float frequency = 1.;
- //
- // Loop of octaves
- for (int i = 0; i < octaves; i++) {
- value += amplitude * noise(frequency*uv);
- frequency *= lacunarity;
- amplitude *= gain;
- }
这就是一种 fbm函数 前面讲了可以吧fbm看成多张噪声的叠加
amplitude表示每一次噪声叠加的权值,frequency 则是叠加噪声的比例
octaves是循环次数,可以看成叠加几张噪声
lacunarity和gain则是用于修改amplitude和frequency 的值,让每次叠加的噪声权值和大小都不同。
- Shader "Custom/FBMValueNoise" {
- Properties{
- _Scale("Scale",Range(4,20)) = 10
- [Header(properties)]
- _Octaves("Octaves",Int) = 1
- _Lacunarity("lacunarity",Float)=2
- _Gain("gain",Float)=0.5
- [Header(fbm init)]
- _Amplitude("amolitude",Float) = 0.5
- _Frequency("frequency",Float) = 1.0
- }
- SubShader{
- Pass{
- CGPROGRAM
- #include "UnityCG.cginc"
- #pragma vertex vert
- #pragma fragment frag
- float _Scale;
- int _Octaves;
- float _Lacunarity;
- float _Gain;
- float _Amplitude;
- float _Frequency;
- struct v2f {
- float4 pos:SV_POSITION;
- half2 uv:TEXCOORD0;
- };
- v2f vert(appdata_base v) {
- v2f o;
- o.pos = UnityObjectToClipPos(v.vertex);
- o.uv = v.texcoord;
- return o;
- }
- float rand(float2 st) {
- return frac(sin(dot(st.xy,
- float2(12.9898, 78.233)))
- * 43758.5453123);
- }
- float mix(float a, float b, float t) {
- return b*t + a*(1 - t);
- }
- float ValueNoise(float2 uv) {
- float2 i = floor(uv);
- float2 f = frac(uv);
- float a = rand(i);
- float b = rand(i + float2(1, 0));
- float c = rand(i + float2(0, 1));
- float d = rand(i + float2(1, 1));
- float2 u = f*f*(3.0 - 2.0*f);
- return mix(a, b, u.x) +
- (c - a)* u.y * (1.0 - u.x) +
- (d - b) * u.x * u.y;
- //return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
- }
- float fbm(float2 uv) {
- /*如果要多次使用,要把_Frequency和_Amplitude赋值给新的,不能直接用,因为这两个是全局的*/
- float v;
- for (int i = 0; i < _Octaves; i++) {
- v += _Amplitude*ValueNoise(_Frequency*uv);
- _Frequency *= _Lacunarity;
- _Amplitude *= _Gain;
- }
- return v;
- }
- fixed4 frag(v2f i) :SV_Target{
- half2 uv = i.uv * _Scale;
- float noise = fbm(uv);
- return fixed4(noise, noise, noise, 1);
- }
- ENDCG
- }
- }
- FallBack "Diffuse"
- }
上面其中一种FBM方法,你还可以用其他的FBM,会有不同的效果
- for (int i = 0; i < OCTAVES; i++) {
- value += amplitude * abs(snoise(st));
- st *= 2.;
- amplitude *= .5;
- }
这里多了个绝对值的运算
- n = abs(n); // create creases
- n = offset - n; // invert so creases are at top
- n = n * n; // sharpen creases
PS:湍流和山脊这两张图和我参考的文章生成的图差别很大,可能是生成噪声的方式不同,建议参考原文
我们还可以用噪声来扭曲纹理坐标,可以看Inigo Quiles的这篇文章
- Shader "Custom/Domain Warping" {
- Properties{
- _Scale("Scale",Float) = 10
- [Header(properties)]
- _Octaves("Octaves",Int) = 1
- _Lacunarity("lacunarity",Float) = 2
- _Gain("gain",Float) = 0.5
- [Header(fbm init)]
- _Amplitude("amolitude",Float) = 0.5
- _Frequency("frequency",Float) = 1.0
- [Header(Color)]
- _Color0("Color0",Color)= (0.101961, 0.619608, 0.666667)
- _Color1("Color1",Color) = (0.666667, 0.666667, 0.498039)
- _Color2("Color2",Color) = (0, 0, 0.164706)
- _Color3("Color3",Color) = (0.666667, 1, 1)
- }
- SubShader{
- Pass{
- CGPROGRAM
- #include "UnityCG.cginc"
- #pragma vertex vert
- #pragma fragment frag
- float _Scale;
- int _Octaves;
- float _Lacunarity;
- float _Gain;
- float _Amplitude;
- float _Frequency;
- float3 _Color0;
- float3 _Color1;
- float3 _Color2;
- float3 _Color3;
- struct v2f {
- float4 pos:SV_POSITION;
- half2 uv:TEXCOORD0;
- };
- inline float mix(float a, float b, float t) {
- return b*t + a*(1 - t);
- }
- inline float3 mix3(float3 a, float3 b, float t) {
- return float3(mix(a.x, b.x, t), mix(a.y, b.y, t), mix(a.z, b.z, t));
- }
- //from:https://www.shadertoy.com/view/XdXGW8
- float2 random(float2 x) {
- float2 k = float2(0.3183099, 0.3678794);
- x = x*k + k.yx;
- return -1.0 + 2.0*frac(16.0 * k*frac(x.x*x.y*(x.x + x.y)));
- }
- float perlinNoise(float2 uv) {
- float2 i = floor(uv);
- float2 f = frac(uv);
- //为了直观 单独计算四个值
- float value0 = dot(random(i + float2(0, 0)), f - float2(0, 0));
- float value1 = dot(random(i + float2(1, 0)), f - float2(1, 0));
- float value2 = dot(random(i + float2(0, 1)), f - float2(0, 1));
- float value3 = dot(random(i + float2(1, 1)), f - float2(1, 1));
-
- float2 u = f*f*(3.0 - 2.0*f);
- //插值
- return mix(mix(value0, value1,u.x), mix(value2, value3, u.x), u.y);
- }
- float fbm(in float2 uv) {
- float v;
- float frequency = _Frequency;
- float amplitude = _Amplitude;
- for (int i = 0; i < _Octaves; i++) {
- v += amplitude*perlinNoise(frequency*uv);
- frequency *= _Lacunarity;
- amplitude *= _Gain;
- }
- return v;
- }
- float3 dw(float2 uv) {
-
- //添加的向量只是单纯的偏移可以随便改
- //第一层扭曲
- float2 q = float2(fbm(uv + float2(0.0, 0.0)),
- fbm(uv + float2(5.2, 1.3)));
- //第二层扭曲
- float2 r = float2(fbm(uv + 4.0*q + float2(1.7, 9.2) + 0.23*_Time.y),
- fbm(uv + 4.0*q + float2(8.3, 2.8) + 0.53*_Time.y));
- //第三层扭曲
- float f= fbm(uv+4*r);
-
- //上色
- //第三层
- float3 color = mix3(_Color0,_Color1,
- clamp((f*f)*4.0, 0.0, 1.0));
- //第一层
- color = mix3(color, _Color2,
- clamp(length(q), 0.0, 1.0));
- //第二层
- color = mix3(color, _Color3,
- clamp(length(r.x), 0.0, 1.0));
-
- return color;
- }
- v2f vert(appdata_base v) {
- v2f o;
- o.pos = UnityObjectToClipPos(v.vertex);
- o.uv = v.texcoord;
- return o;
- }
- fixed4 frag(v2f i) :SV_Target{
- float3 color = dw(i.uv*_Scale);
- return fixed4(color, 1);
- }
- ENDCG
- }
- }
- FallBack "Diffuse"
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。