当前位置:   article > 正文

噪声笔记#6 分形布朗运动_fbm噪声

fbm噪声

分形布朗运动(Fractal Brownian Motion)也就是fbm,它不是噪声,但是他可以让噪声有更多的细节。可以看成把不同比例位置的一张噪声合并在一起。

  1. // Properties
  2. const int octaves = 1;
  3. float lacunarity = 2.0;
  4. float gain = 0.5;
  5. //
  6. // Initial values
  7. float amplitude = 0.5;
  8. float frequency = 1.;
  9. //
  10. // Loop of octaves
  11. for (int i = 0; i < octaves; i++) {
  12. value += amplitude * noise(frequency*uv);
  13. frequency *= lacunarity;
  14. amplitude *= gain;
  15. }

这就是一种 fbm函数  前面讲了可以吧fbm看成多张噪声的叠加

amplitude表示每一次噪声叠加的权值,frequency 则是叠加噪声的比例 

octaves是循环次数,可以看成叠加几张噪声

lacunarity和gain则是用于修改amplitude和frequency 的值,让每次叠加的噪声权值和大小都不同。

fbm噪声

值噪声+fbm

  1. Shader "Custom/FBMValueNoise" {
  2. Properties{
  3. _Scale("Scale",Range(4,20)) = 10
  4. [Header(properties)]
  5. _Octaves("Octaves",Int) = 1
  6. _Lacunarity("lacunarity",Float)=2
  7. _Gain("gain",Float)=0.5
  8. [Header(fbm init)]
  9. _Amplitude("amolitude",Float) = 0.5
  10. _Frequency("frequency",Float) = 1.0
  11. }
  12. SubShader{
  13. Pass{
  14. CGPROGRAM
  15. #include "UnityCG.cginc"
  16. #pragma vertex vert
  17. #pragma fragment frag
  18. float _Scale;
  19. int _Octaves;
  20. float _Lacunarity;
  21. float _Gain;
  22. float _Amplitude;
  23. float _Frequency;
  24. struct v2f {
  25. float4 pos:SV_POSITION;
  26. half2 uv:TEXCOORD0;
  27. };
  28. v2f vert(appdata_base v) {
  29. v2f o;
  30. o.pos = UnityObjectToClipPos(v.vertex);
  31. o.uv = v.texcoord;
  32. return o;
  33. }
  34. float rand(float2 st) {
  35. return frac(sin(dot(st.xy,
  36. float2(12.9898, 78.233)))
  37. * 43758.5453123);
  38. }
  39. float mix(float a, float b, float t) {
  40. return b*t + a*(1 - t);
  41. }
  42. float ValueNoise(float2 uv) {
  43. float2 i = floor(uv);
  44. float2 f = frac(uv);
  45. float a = rand(i);
  46. float b = rand(i + float2(1, 0));
  47. float c = rand(i + float2(0, 1));
  48. float d = rand(i + float2(1, 1));
  49. float2 u = f*f*(3.0 - 2.0*f);
  50. return mix(a, b, u.x) +
  51. (c - a)* u.y * (1.0 - u.x) +
  52. (d - b) * u.x * u.y;
  53. //return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
  54. }
  55. float fbm(float2 uv) {
  56. /*如果要多次使用,要把_Frequency和_Amplitude赋值给新的,不能直接用,因为这两个是全局的*/
  57. float v;
  58. for (int i = 0; i < _Octaves; i++) {
  59. v += _Amplitude*ValueNoise(_Frequency*uv);
  60. _Frequency *= _Lacunarity;
  61. _Amplitude *= _Gain;
  62. }
  63. return v;
  64. }
  65. fixed4 frag(v2f i) :SV_Target{
  66. half2 uv = i.uv * _Scale;
  67. float noise = fbm(uv);
  68. return fixed4(noise, noise, noise, 1);
  69. }
  70. ENDCG
  71. }
  72. }
  73. FallBack "Diffuse"
  74. }

perlin噪声+fbm

simplex噪声+fbm

其他的FBM函数

上面其中一种FBM方法,你还可以用其他的FBM,会有不同的效果 

湍流

  1. for (int i = 0; i < OCTAVES; i++) {
  2. value += amplitude * abs(snoise(st));
  3. st *= 2.;
  4. amplitude *= .5;
  5. }

这里多了个绝对值的运算

山脊

  1. n = abs(n); // create creases
  2. n = offset - n; // invert so creases are at top
  3. n = n * n; // sharpen creases


PS:湍流山脊这两张图和我参考的文章生成的图差别很大,可能是生成噪声的方式不同,建议参考原文


域翘曲(Domain Warping)

我们还可以用噪声来扭曲纹理坐标,可以看Inigo Quiles的这篇文章

  1. Shader "Custom/Domain Warping" {
  2. Properties{
  3. _Scale("Scale",Float) = 10
  4. [Header(properties)]
  5. _Octaves("Octaves",Int) = 1
  6. _Lacunarity("lacunarity",Float) = 2
  7. _Gain("gain",Float) = 0.5
  8. [Header(fbm init)]
  9. _Amplitude("amolitude",Float) = 0.5
  10. _Frequency("frequency",Float) = 1.0
  11. [Header(Color)]
  12. _Color0("Color0",Color)= (0.101961, 0.619608, 0.666667)
  13. _Color1("Color1",Color) = (0.666667, 0.666667, 0.498039)
  14. _Color2("Color2",Color) = (0, 0, 0.164706)
  15. _Color3("Color3",Color) = (0.666667, 1, 1)
  16. }
  17. SubShader{
  18. Pass{
  19. CGPROGRAM
  20. #include "UnityCG.cginc"
  21. #pragma vertex vert
  22. #pragma fragment frag
  23. float _Scale;
  24. int _Octaves;
  25. float _Lacunarity;
  26. float _Gain;
  27. float _Amplitude;
  28. float _Frequency;
  29. float3 _Color0;
  30. float3 _Color1;
  31. float3 _Color2;
  32. float3 _Color3;
  33. struct v2f {
  34. float4 pos:SV_POSITION;
  35. half2 uv:TEXCOORD0;
  36. };
  37. inline float mix(float a, float b, float t) {
  38. return b*t + a*(1 - t);
  39. }
  40. inline float3 mix3(float3 a, float3 b, float t) {
  41. return float3(mix(a.x, b.x, t), mix(a.y, b.y, t), mix(a.z, b.z, t));
  42. }
  43. //from:https://www.shadertoy.com/view/XdXGW8
  44. float2 random(float2 x) {
  45. float2 k = float2(0.3183099, 0.3678794);
  46. x = x*k + k.yx;
  47. return -1.0 + 2.0*frac(16.0 * k*frac(x.x*x.y*(x.x + x.y)));
  48. }
  49. float perlinNoise(float2 uv) {
  50. float2 i = floor(uv);
  51. float2 f = frac(uv);
  52. //为了直观 单独计算四个值
  53. float value0 = dot(random(i + float2(0, 0)), f - float2(0, 0));
  54. float value1 = dot(random(i + float2(1, 0)), f - float2(1, 0));
  55. float value2 = dot(random(i + float2(0, 1)), f - float2(0, 1));
  56. float value3 = dot(random(i + float2(1, 1)), f - float2(1, 1));
  57. float2 u = f*f*(3.0 - 2.0*f);
  58. //插值
  59. return mix(mix(value0, value1,u.x), mix(value2, value3, u.x), u.y);
  60. }
  61. float fbm(in float2 uv) {
  62. float v;
  63. float frequency = _Frequency;
  64. float amplitude = _Amplitude;
  65. for (int i = 0; i < _Octaves; i++) {
  66. v += amplitude*perlinNoise(frequency*uv);
  67. frequency *= _Lacunarity;
  68. amplitude *= _Gain;
  69. }
  70. return v;
  71. }
  72. float3 dw(float2 uv) {
  73. //添加的向量只是单纯的偏移可以随便改
  74. //第一层扭曲
  75. float2 q = float2(fbm(uv + float2(0.0, 0.0)),
  76. fbm(uv + float2(5.2, 1.3)));
  77. //第二层扭曲
  78. float2 r = float2(fbm(uv + 4.0*q + float2(1.7, 9.2) + 0.23*_Time.y),
  79. fbm(uv + 4.0*q + float2(8.3, 2.8) + 0.53*_Time.y));
  80. //第三层扭曲
  81. float f= fbm(uv+4*r);
  82. //上色
  83. //第三层
  84. float3 color = mix3(_Color0,_Color1,
  85. clamp((f*f)*4.0, 0.0, 1.0));
  86. //第一层
  87. color = mix3(color, _Color2,
  88. clamp(length(q), 0.0, 1.0));
  89. //第二层
  90. color = mix3(color, _Color3,
  91. clamp(length(r.x), 0.0, 1.0));
  92. return color;
  93. }
  94. v2f vert(appdata_base v) {
  95. v2f o;
  96. o.pos = UnityObjectToClipPos(v.vertex);
  97. o.uv = v.texcoord;
  98. return o;
  99. }
  100. fixed4 frag(v2f i) :SV_Target{
  101. float3 color = dw(i.uv*_Scale);
  102. return fixed4(color, 1);
  103. }
  104. ENDCG
  105. }
  106. }
  107. FallBack "Diffuse"
  108. }

参考内容:https://thebookofshaders.com/13/?lan=ch

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/92960
推荐阅读
相关标签
  

闽ICP备14008679号