168 lines
4.5 KiB
HLSL
168 lines
4.5 KiB
HLSL
#ifndef __NOISE__
|
|
#define __NOISE__
|
|
|
|
#define PI 3.14159265358979
|
|
|
|
#define DECLARENOISEKEYWORDS(_PRE) #pragma shader_feature_local _ _PRE##NOISE _PRE##FBM _PRE##WORLEY _PRE##WORM _PRE##WORMFBM _PRE##NOISETEXTURE
|
|
#define DECLARENOISEVARS(_PRE) Texture2D _PRE##NoiseTexture; float4 _PRE##NoiseTexture_ST; float4 _PRE##Noise; int _PRE##NoiseChannel;
|
|
|
|
float Hash12(float2 p)
|
|
{
|
|
float3 p3 = frac(float3(p.xyx) * .1031);
|
|
p3 += dot(p3, p3.yzx + 33.33);
|
|
return frac((p3.x + p3.y) * p3.z);
|
|
}
|
|
|
|
float2 Hash2D( 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)) );
|
|
}
|
|
|
|
float3 Erode(float2 p, float2 dir)
|
|
{
|
|
float2 ip = floor(p);
|
|
float2 fp = frac(p);
|
|
float f = 2.*PI;
|
|
float3 va = 0;
|
|
float wt = 0.0;
|
|
for (int i=-2; i<=1; i++)
|
|
{
|
|
for (int j=-2; j<=1; j++)
|
|
{
|
|
float2 o = float2(i, j);
|
|
float2 h = Hash2D(ip - o)*0.5;
|
|
float2 pp = fp +o - h;
|
|
float d = dot(pp, pp);
|
|
float w = exp(-d*2.0);
|
|
wt +=w;
|
|
float mag = dot(pp,dir);
|
|
va += float3(cos(mag*f), -sin(mag*f)*(pp+dir))*w;
|
|
}
|
|
}
|
|
return va/wt;
|
|
}
|
|
|
|
float ErosionNoise(float2 uv, float3 n)
|
|
{
|
|
float2 dir = n.zx * float2(1.0, -1.0);
|
|
|
|
float3 h = 0;
|
|
float a = 0.7;
|
|
float f = 1.0;
|
|
for (int xx=0;xx<5;xx++)
|
|
{
|
|
float3 eros = Erode(uv*f, dir+h.zy*float2(1.0, -1.0));
|
|
h += float3(1.0, f, f) * eros * a;
|
|
a*=0.4;
|
|
f*=2.0;
|
|
}
|
|
|
|
return abs(h.x);
|
|
}
|
|
|
|
float Noise2D(float2 p )
|
|
{
|
|
float2 i = floor( p );
|
|
float2 f = frac( p );
|
|
|
|
float2 u = f*f*(3.0-2.0*f);
|
|
|
|
return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ),
|
|
dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),
|
|
lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ),
|
|
dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);
|
|
}
|
|
|
|
|
|
float2 WorleyHash2D(float2 p)
|
|
{
|
|
return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3);
|
|
}
|
|
|
|
float WorleyNoise2D(float2 p)
|
|
{
|
|
float dist = 1;
|
|
float2 i = floor(p);
|
|
float2 f = frac(p);
|
|
|
|
for(int x = -1;x<=1;x++)
|
|
{
|
|
for(int y = -1;y<=1;y++)
|
|
{
|
|
float d = length(WorleyHash2D(i+float2(x,y))+float2(x,y) - f);
|
|
dist = min(dist,d);
|
|
}
|
|
}
|
|
return sqrt(dist);
|
|
|
|
}
|
|
|
|
float FBM2D(float2 uv)
|
|
{
|
|
float f = 0.5000*Noise2D( uv ); uv *= 2.01;
|
|
f += 0.3300*Noise2D( uv ); uv *= 1.96;
|
|
f += 0.170*Noise2D( uv );
|
|
return f;
|
|
}
|
|
|
|
|
|
float2 Hash22( float2 n ) { return sin(n.x*n.y+float2(0,1.571)); }
|
|
|
|
float WormNoise(float2 p)
|
|
{
|
|
const float kF = 6.0;
|
|
|
|
float2 i = floor(p) + 77;
|
|
float2 f = frac(p);
|
|
f = f*f*(3.0-2.0*f);
|
|
return lerp(lerp(sin(kF*dot(p,Hash22(i+float2(0,0)))),
|
|
sin(kF*dot(p,Hash22(i+float2(1,0)))),f.x),
|
|
lerp(sin(kF*dot(p,Hash22(i+float2(0,1)))),
|
|
sin(kF*dot(p,Hash22(i+float2(1,1)))),f.x),f.y);
|
|
}
|
|
|
|
float WormNoiseFBM(float2 uv)
|
|
{
|
|
const float2x2 m = float2x2( 1.6, 1.2, -1.2, 1.6 );
|
|
float f = 0.5000*WormNoise( uv ); uv = mul(uv, m);
|
|
f += 0.3300*WormNoise( uv ); uv = mul(uv, m);
|
|
f += 0.1700*WormNoise( uv );
|
|
return f;
|
|
}
|
|
|
|
|
|
float Noise(float2 uv, float4 param)
|
|
{
|
|
return ((Noise2D(uv * param.x + param.z) - param.w) * param.y);
|
|
}
|
|
|
|
float NoiseFBM(float2 uv, float4 param)
|
|
{
|
|
return ((FBM2D(uv * param.x + param.z) - param.w) * param.y);
|
|
}
|
|
|
|
float NoiseWorley(float2 uv, float4 param)
|
|
{
|
|
return ((WorleyNoise2D(uv * param.x + param.z) - param.w) * param.y);
|
|
}
|
|
|
|
float NoiseWorm(float2 uv, float4 param)
|
|
{
|
|
return ((WormNoise(uv * param.x + param.z) - param.w) * param.y);
|
|
}
|
|
|
|
float NoiseWormFBM(float2 uv, float4 param)
|
|
{
|
|
return ((WormNoiseFBM(uv * param.x + param.z) - param.w) * param.y);
|
|
}
|
|
|
|
float NoiseErosion(float2 uv, float4 param, float3 normal)
|
|
{
|
|
return ((ErosionNoise(uv * param.x + param.z, normal) - param.w) * param.y);
|
|
}
|
|
|
|
#endif
|
|
|