unity中噪声函数和应用

关于下面的噪声图,一定要自己动手输出每张图的效果,结合代码分析图的效果。
1.白噪声WhiteNoise
主要是用到 frac函数,此函数主要是 返回小数部分
{小注: frac(10x) 和 frac(100x)的区别}

在这里插入图片描述

            // 白噪声
            float whiteNoise(float2 uv,int seed)
            {
                float r = frac(sin(dot(uv,float2(seed + 12.9898,seed + 78.233)))*43758.5453);
                return r;
            }

2.柏林噪声perlinNoise
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述下面是smoothStep的函数用代码来表达的形式:
重点:t = t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);

            // smooth interpolation for perlin noise
            float SmoothLerp(float min, float max, float t)
            {
                t = t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
                return min + t * (max - min);
            }

在这里插入图片描述

“双线性插值”:
(1)在水平方向上插值X1
(1)在水平方向上插值X2
(1)在将X1和X2在竖直方向上插值得到结果

// 当w为0时,返回a,当w为1时返回b,否则返回a与b的插值
float lerp(float a, float b, float w) {
   return a + w*(b-a);
} 

3.分形布朗运动
在这里插入图片描述在这里插入图片描述

下面给出代码:包括白噪声,柏林噪声,用分形布朗运动对柏林噪声进行处理:
高度雾 + 噪声–>流动的雾:
在这里插入图片描述

Shader "custom/fog"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _FogXSpeed("_fogXSpeed",range(0,0.5)) = 0.01
        _FogYSpeed("_fogYSpeed",range(0,0.5)) = 0.03
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            Tags { "RenderType"="Opaque" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };


            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 scrProj : TEXCOORD1;
                float2 uv_depth : TEXCOORD2;
                float4 interpolatedRay : TEXCOORD3;
            };

            sampler2D _MainTex;
            half4 _MainTex_TexelSize;
            sampler2D _CameraDepthTexture;
            float4x4 _FrustumCornersRay;

            float4 _FogColor;
            float _FogDensity;
            float _FogStart;
            float _FogEnd;
            float _FogXSpeed;
            float _FogYSpeed;

            // 白噪声
            float whiteNoise(int seed, int i, int j)
            {
                //return  frac(sin(dot(float2(i,cos(j)),float2(seed+12.9898,seed + 78.233)))*43758.5453);
                return frac(
                    sin(dot(float2(i, cos(j)), float2(float(seed) + 12.9898, float(seed) + 78.233))) * 43758.5453);
            }

            //求出梯度值
            float HashGrid(int seed, int i, int j)
            {
                // 将得到的白噪声的值(0,1) -》还原为 (-1,-1) 
                float r = whiteNoise(seed, i, j);
                r = r * 2 - 1;
                return r;
            }
            // 梯度向量
            float2 ComputeGradient(int seed, int gridX, int gridY)
            {
                float2 gradient = float2(HashGrid(seed * 123 + 456, gridX, gridY),
                                         HashGrid(seed * 456 + 123, gridX, gridY));
                return gradient;
            }

            // 柏林噪声
            float perlinNoise(int seed, float2 p, float gridSize)
            {
                p /= gridSize;
                int gridX = floor(p.x);
                int gridY = floor(p.y);
                float2 gradient00 = ComputeGradient(seed, gridX, gridY);
                float2 gradient01 = ComputeGradient(seed, gridX, gridY + 1);
                float2 gradient10 = ComputeGradient(seed, gridX + 1, gridY);
                float2 gradient11 = ComputeGradient(seed, gridX + 1, gridY + 1);

                float2 v00 = float2(gridX, gridY);
                float2 v01 = float2(gridX, gridY + 1);
                float2 v10 = float2(gridX + 1, gridY);
                float2 v11 = float2(gridX + 1, gridY + 1);
                float dp00 = dot((p - v00), gradient00);
                float dp01 = dot((p - v01), gradient01);
                float dp10 = dot((p - v10), gradient10);
                float dp11 = dot((p - v11), gradient11);
                // blinear interpolation 双线性插值
                float tx = (p.x - v00.x);
                float ty = (p.y - v00.y);
                // 此处将lerp 转换成smoothstep 比较一下效果
                float res = smoothstep(lerp(dp00, dp10, tx), lerp(dp01, dp11, tx), ty);
                float res = lerp(lerp(dp00, dp10, tx), lerp(dp01, dp11, tx), ty);
                return res;
            }

            float PerlinNoiseFBM6(int seed, float2 p, float gridSize)
            {
                // const float aspect = 2.0f;
                // p.x *= aspect;
                // fBM : https://www.iquilezles.org/www/articles/fbm/fbm.htm
                // https://www.shadertoy.com/view/lsl3RH
                // https://www.shadertoy.com/view/XslGRr
                //Vector4 deltaVec = new Vector4(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f), 0.0f, 0.0f); ;// new Vector4(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f), 0.0f, 0.0f);
                float2x2 mat = {
                    //some rotation matrix
                    0.8f, 0.6f,
                    -0.6f, 0.8f
                };
                float f = 0.0f;
                int numFbmSteps = 6;
                float multiplier[6] = {2.02f, 2.03f, 2.01f, 2.04f, 2.01f, 2.02f};
                // float multiplier[6] = { 1.02f, 2.03f, 3.01f, 2.04f, 3.01f, 3.02f };
                float amp = 1.0f;
                for (int i = 0; i < numFbmSteps; ++i)
                {
                    f += amp * perlinNoise(seed, p, gridSize);
                    p = mul(mat, p) * multiplier[i];
                    //(2.0f + Random.Range(0.0f, 0.05f));//brownian motion applied to sample coord
                    // p *= multiplier[i];
                    amp *= 0.5f;
                }
                return f / 0.96875f;
            }
            // 分形布朗运动
            float perLinNoiseFBM(int seed,float2 p,float gridSize)
            {
                float2x2 mat = {
                    0.8f,0.6f,
                    -0.6f,0.8f
                };
                float f = 0.0f;
                int numFbmSteps = 6;
                float multiplier[6] = {2.02f,2.03f,2.01f,2.04f,2.01f,2.02f};
                float amp = 1.0f;
                for (int i = 0;i<numFbmSteps;i++)
                {
                    f += amp * perlinNoise(seed,p,gridSize);
                    p = mul(mat,p) * multiplier[i];
                    amp *= 0.5f;
                }
                return  f / 0.96875f;
            }            

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.uv_depth = v.uv;
                # if UNITY_UV_STARTS_AT_TOP
                o.uv_depth.y = 1 - o.uv_depth.y;
                #endif
                int index = 0;
                float2 uv = v.uv;
                if (uv.x < 0.5 && uv.y < 0.5)
                {
                    index = 0;
                }
                else if (uv.x > 0.5 && uv.y < 0.5)
                {
                    index = 1;
                }
                else if (uv.x > 0.5 && uv.y > 0.5)
                {
                    index = 2;
                }
                else if (uv.x < 0.5 && uv.y > 0.5)
                {
                    index = 3;
                }
                #if UNITY_UV_STARTS_AT_TOP
                if (_MainTex_TexelSize.y < 0)
                    index = 3 - index;
                #endif
                o.interpolatedRay = _FrustumCornersRay[index];
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float speed = _Time.y * float2(_FogXSpeed,_FogYSpeed);
                float gridSize = 0.500;
                float nosie = perLinNoiseFBM(42, i.uv + speed, gridSize);
                // 重建世界坐标系
                float depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth));
                float3 worldPos = _WorldSpaceCameraPos + depth * i.interpolatedRay.xyz;
                 // y值越小, 浓度越高
                 float fogDensity = (_FogEnd - worldPos.y) / (_FogEnd - _FogStart);
                
                 fogDensity = saturate(fogDensity * _FogDensity * (1+ nosie));
                
                 fixed4 finalCol = tex2D(_MainTex,i.uv);
                 finalCol.rbg = lerp(finalCol.rgb,_FogColor.rgb,fogDensity);               
                
                
                return fixed4(finalCol);
            }
            ENDCG
        }
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[ExecuteInEditMode]
[ImageEffectAllowedInSceneView]
public class fog : MonoBehaviour
{
    #region const data
    private const string m_FrustumCornersRay = "_FrustumCornersRay";
    private const string fogCol = "_FogColor";
    private const string fogDen = "_FogDensity";
    private const string fogSt = "_FogStart";
    private const string fogEn = "_FogEnd";
    
    #endregion

    private Material m_Material;

    public Camera camera;
    public Shader FogShader;
    [Range(0,3)]
    public float fogDensity;
    public Color fogColor;
    public float fogStart = 0;
    public float fogEnd = 2.0f;

    [Range(0,0.3f)]
    public float _FogXSpeed;
    [Range(0,0.3f)]
    public float _FogYSpeed;
    private void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (!m_Material)
        {
            m_Material= new Material(FogShader);
        }

        Matrix4x4 frustumCorners = Matrix4x4.identity;
        float fov = camera.fieldOfView;
        float near = camera.nearClipPlane;
        float aspect = camera.aspect;

        float halfHeight = near * Mathf.Tan(fov * 0.5f * Mathf.Deg2Rad);
        var cameraTransform = camera.transform;
        Vector3 toRight = cameraTransform.right  * halfHeight * aspect;
        Vector3 toTop = cameraTransform.up * halfHeight;
        
        // 
        Vector3 topLeft = cameraTransform.forward * near +   toTop-toRight;
        // magnitude ,返回向量的长度
        float scale = topLeft.magnitude / near;
        topLeft.Normalize();
        topLeft *= scale;
        
        //
        Vector3 topRight = cameraTransform.forward * near + toRight + toTop;
        topRight.Normalize();
        topRight *= scale;
        

        //
        Vector3 bottmLeft = cameraTransform.forward * near - toTop - toRight;
        bottmLeft.Normalize();
        bottmLeft *= scale;
        //
        Vector3 bottmRigh = cameraTransform.forward * near - toTop + toRight;
        bottmRigh.Normalize();
        bottmRigh *= scale;
        
        
        frustumCorners.SetRow(0,bottmLeft);
        frustumCorners.SetRow(1,bottmRigh);
        frustumCorners.SetRow(2,topRight);
        frustumCorners.SetRow(3,topLeft);
        
        m_Material.SetMatrix(m_FrustumCornersRay,frustumCorners);
        
        m_Material.SetColor(fogCol,fogColor);
        m_Material.SetFloat(fogDen,fogDensity);
        m_Material.SetFloat(fogSt,fogStart);
        m_Material.SetFloat(fogEn,fogEnd);
        m_Material.SetFloat("_FogXSpeed",_FogXSpeed);
        m_Material.SetFloat("_FogYSpeed",_FogYSpeed);
        Graphics.Blit(src,dest,m_Material);
    }
}

LibNoise分形噪声函数库的JAVA翻译版,个人开发,仅供参考。 包中包含: 异常模块: noise.Exception noise.ExceptionInvalidParam 无效的参数异常。 noise.ExceptionNoModule 无模块异常,无法检索到该源模块 noise.ExceptionOutOfMemory noise.ExceptionUnknown 模型模块: noise.model.Line 线 noise.model.Plane 平面 noise.model.Sphere 球体 noise.model.Cylinder 圆柱 发生器模块: noise.module.Perlin 培林噪声 noise.module.RidgedMulti 脊多重分形噪声 noise.module.Billow 巨浪 value = |perlin_value|*2-1.0; noise.module.Voronoi 细胞噪声,Voronoi图 noise.module.Const 常量 value = const; noise.module.Cylinders 圆柱 noise.module.Checkerboard 棋盘格 value = (floor(x) & 1 ^ floor(y) & 1 ^ floor(z) & 1) != 0 ? -1.0 : 1.0; noise.module.Spheres 球体 选择器模块: noise.module.Select 选择 noise.module.Blend 混合 value = ((1.0 - (modules[3].value+1)/2) * modules[0].value) + ((modules[3].value+1)/2 * modules[1].value); 修饰器模块: noise.module.Invert 倒置 value = -value; noise.module.Abs 绝对值 value = |value|; noise.module.Clamp 截取 value = (value < lowerBound ?lowerBound : value) or (value > upperBound ?upperBound : value);lowerBound:下截取值;upperBound:上截取值 noise.module.Curve 曲线 value = noise.module.Curve.ControlPoint 控制点 noise.module.ScaleBias 偏移缩放, value = value*scale+offset noise.module.Turbulence 湍流 value = modules[0].getValue(x+modules[1].value * power,y+modules[2].value * power,z+modules[3].value * power); noise.module.Exponent 指数 value = (pow(abs((value + 1.0) / 2.0), exponent) * 2.0 - 1.0); 组合模块: noise.module.Add 添加 value = modules[0].value+modules[1].value; noise.module.Max 最大值 value = max(value); noise.module.Min 最小值 value = min(value); noise.module.Multiply 乘法 value = modules[0].value * modules[1].value; noise.module.Power 权重 value = pow(modules[0].value , modules[1].value); 变压模块: noise.module.Displace 位移替换,扭曲 value = modules[0].getValue(x+modules[1].value,y+modules[2].value,z+modules[3].value); noise.module.RotatePoint 点旋转 noise.module.ScalePoint 点缩放,轴缩放 value = modules[0].getValue (x * xScale, y * yScale,z * zScale); noise.module.Terrace 露台,梯台 noise.module.TranslatePoint 位移变换 value = modules[0].getValue (x * xTranslation, y * yTranslation,z * zTranslation); 其他: noise.module.Cache 缓存 value = noise.module.Module 噪声模块基类 如果发现有要更改的地方,请发邮件给我,或者本人QQ:343179390,欢迎技术探讨
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值