221 lines
8.1 KiB
Plaintext
221 lines
8.1 KiB
Plaintext
Shader "Hidden/MicroVerse/HeightmapStamp"
|
|
{
|
|
Properties
|
|
{
|
|
[HideInInspector] _MainTex ("Heightmap Texture", 2D) = "white" {}
|
|
[HideInInspector] _StampTex("Stamp", 2D) = "black" {}
|
|
[HideInInspector] _FalloffTexture("Falloff", 2D) = "white" {}
|
|
}
|
|
SubShader
|
|
{
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
|
|
#pragma shader_feature_local_fragment _ _USEFALLOFF _USEFALLOFFRANGE _USEFALLOFFTEXTURE _USEFALLOFFSPLINEAREA
|
|
#pragma shader_feature_local_fragment _ _TWIST
|
|
#pragma shader_feature_local_fragment _ _EROSION
|
|
#pragma shader_feature_local_fragment _ _HEIGHTBIAS
|
|
#pragma shader_feature_local_fragment _ _USEORIGINALHEIGHTMAP
|
|
#pragma shader_feature_local_fragment _ _ABSOLUTEHEIGHT
|
|
#pragma shader_feature_local_fragment _ _PASTESTAMP
|
|
#pragma shader_feature_local_fragment _ _USEPOWORTILT
|
|
#pragma shader_feature_local_fragment _ _USEHEIGHTREMAPCUVE
|
|
|
|
#pragma shader_feature_local_fragment _ _USEFALLOFFPAINTAREA
|
|
|
|
#pragma shader_feature_local _ _FALLOFFSMOOTHSTEP _FALLOFFEASEIN _FALLOFFEASEOUT _FALLOFFEASEINOUT
|
|
#pragma shader_feature_local _ _FALLOFFNOISE _FALLOFFFBM _FALLOFFWORLEY _FALLOFFWORM _FALLOFFWORMFBM _FALLOFFNOISETEXTURE
|
|
|
|
// because unity's height format is stupid and only uses half the possible
|
|
// precision.
|
|
#define kMaxHeight (32766.0f/65535.0f)
|
|
|
|
#include_with_pragmas "UnityCG.cginc"
|
|
#include_with_pragmas "/../Noise.cginc"
|
|
#include_with_pragmas "/../HeightStampFiltering.cginc"
|
|
|
|
struct vertexInput
|
|
{
|
|
float4 vertex : POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float4 vertex : SV_POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
float2 stampUV: TEXCOORD1;
|
|
};
|
|
|
|
Texture2D _MainTex;
|
|
Texture2D _HeightRemapCurve;
|
|
SamplerState shared_point_clamp;
|
|
|
|
float2 _HeightRemap;
|
|
float2 _HeightRenorm;
|
|
float _Twist;
|
|
float _Erosion;
|
|
float _ErosionSize;
|
|
float _HeightBias;
|
|
float4 _ScaleOffset;
|
|
float _MipBias;
|
|
float2 _RemapRange;
|
|
float3 _NoiseUV;
|
|
sampler2D _StampTex;
|
|
float4 _StampTex_TexelSize;
|
|
sampler2D _PlacementMask;
|
|
float4x4 _Transform;
|
|
|
|
float _AlphaMapSize;
|
|
float3 _RealSize;
|
|
|
|
|
|
float _Blend;
|
|
float _Invert;
|
|
float _Power;
|
|
float3 _Tilt;
|
|
float2 _TiltScale;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sampler2D _OriginalHeights;
|
|
|
|
v2f vert(vertexInput v)
|
|
{
|
|
v2f o;
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
o.uv = v.uv;
|
|
|
|
o.stampUV = mul(_Transform, float4(v.uv, 0, 1)).xy;
|
|
o.stampUV -= 0.5;
|
|
float2 tilt = saturate(abs(_Tilt.zx));
|
|
tilt *= tilt;
|
|
o.stampUV *= _TiltScale > 0.5 ? lerp(1, 3.14, tilt) : 1;
|
|
o.stampUV += 0.5;
|
|
return o;
|
|
}
|
|
|
|
|
|
|
|
float3 GenerateStampNormal(float2 uv, float height, float spread)
|
|
{
|
|
float2 offset = _StampTex_TexelSize.xy * spread;
|
|
float2 uvx = uv + float2(offset.x, 0.0);
|
|
float2 uvy = uv + float2(0.0, offset.y);
|
|
|
|
float x = tex2D(_StampTex, uvx).r;
|
|
float y = tex2D(_StampTex, uvy).r;
|
|
|
|
float2 dxy = height - float2(x, y);
|
|
|
|
dxy = dxy * 1 / offset.xy;
|
|
return normalize(float4( dxy.x, dxy.y, 1.0, height)).xzy * 0.5 + 0.5;
|
|
}
|
|
|
|
|
|
// radial distort UV coordinates
|
|
float2 RadialUV(float2 uv, float2 center, float str, float2 offset)
|
|
{
|
|
float2 delta = uv - center;
|
|
float delta2 = dot(delta.xy, delta.xy);
|
|
float2 delta_offset = delta2 * str;
|
|
return uv + float2(delta.y, -delta.x) * delta_offset + offset;
|
|
}
|
|
|
|
|
|
|
|
float4 frag(v2f i) : SV_Target
|
|
{
|
|
float4 heightSample = _MainTex.SampleLevel(shared_point_clamp, i.uv, 0);
|
|
bool cp = (i.stampUV.x < 0 || i.stampUV.x > 1 || i.stampUV.y < 0|| i.stampUV.y > 1);
|
|
if (cp)
|
|
return heightSample;
|
|
float height = UnpackHeightmap(heightSample);
|
|
|
|
float2 noiseUV = (i.uv * _NoiseUV.z) + _NoiseUV.xy * _NoiseUV.z;
|
|
|
|
float2 stampUV = i.stampUV * _ScaleOffset.xy + _ScaleOffset.zw;
|
|
|
|
#if _TWIST
|
|
stampUV = RadialUV(i.stampUV, 0.5, _Twist, 0);
|
|
#endif
|
|
|
|
float stamp = tex2Dlod(_StampTex, float4(stampUV, 0, _MipBias)).r;
|
|
|
|
stamp = abs(_Invert - stamp);
|
|
|
|
#if _USEHEIGHTREMAPCUVE
|
|
stamp = _HeightRemapCurve.SampleLevel(shared_linear_clamp, float2(stamp, 0), 0);
|
|
#endif
|
|
|
|
#if _USEPOWORTILT
|
|
stamp = pow(stamp, _Power);
|
|
float2 tilt = lerp(float2(-1, -1), float2(1,1), stampUV) * (_Tilt.zx);
|
|
stamp += tilt.x + tilt.y;
|
|
#endif
|
|
|
|
#if _EROSION
|
|
float3 normal = GenerateStampNormal(stampUV, stamp, _ErosionSize) * 0.3333;
|
|
normal += GenerateStampNormal(stampUV, stamp, _ErosionSize*3) * 0.3333;
|
|
normal += GenerateStampNormal(stampUV, stamp, _ErosionSize*7) * 0.3334;
|
|
|
|
float erosNoise = ErosionNoise(stampUV, normal);
|
|
float erosStr = (1 - normal.y);
|
|
erosStr *= erosStr;
|
|
stamp -= erosStr * erosNoise * _Erosion / _RealSize.y;
|
|
#endif
|
|
|
|
float2 falloffuv = noiseUV;
|
|
if (_FalloffNoise2.x > 0)
|
|
falloffuv = stampUV;
|
|
|
|
float noise = 0;
|
|
float falloff = ComputeFalloff(i.uv, i.stampUV, noiseUV, 0);
|
|
|
|
#if _FALLOFFNOISE
|
|
noise = (Noise(falloffuv, _FalloffNoise)) / _RealSize.y;
|
|
#elif _FALLOFFFBM
|
|
noise = (NoiseFBM(falloffuv, _FalloffNoise)) / _RealSize.y;
|
|
#elif _FALLOFFWORLEY
|
|
noise = (NoiseWorley(falloffuv, _FalloffNoise)) / _RealSize.y;
|
|
#elif _FALLOFFWORM
|
|
noise = (NoiseWorm(falloffuv, _FalloffNoise)) / _RealSize.y;
|
|
#elif _FALLOFFWORMFBM
|
|
noise = (NoiseWormFBM(falloffuv, _FalloffNoise)) / _RealSize.y;
|
|
#elif _FALLOFFNOISETEXTURE
|
|
noise = (tex2D(_FalloffNoiseTexture, falloffuv * _FalloffNoiseTexture_ST.xy + _FalloffNoiseTexture_ST.zw)[_FalloffNoiseChannel] * 2.0 - 1.0) / _RealSize.y * _FalloffNoise.y + _FalloffNoise.w;
|
|
#endif
|
|
|
|
|
|
|
|
#if _FALLOFFNOISE || _FALLOFFFBM || _FALLOFFWORLEY || _FALLOFFWORM || _FALLOFFWORMFBM || _FALLOFFNOISETEXTURE
|
|
noise *= 1-falloff;
|
|
falloff = ComputeFalloff(i.uv, stampUV, noiseUV, noise);
|
|
#endif
|
|
|
|
falloff *= 1.0 - tex2D(_PlacementMask, i.uv).x;
|
|
|
|
#if _USEORIGINALHEIGHTMAP
|
|
float originalHeight = UnpackHeightmap(tex2D(_OriginalHeights, i.uv));
|
|
return PackHeightmap(originalHeight);
|
|
#endif
|
|
|
|
#if _ABSOLUTEHEIGHT
|
|
stamp *= _HeightRenorm.y;
|
|
#endif
|
|
|
|
float newHeight = saturate(_HeightRemap.x + stamp * (_HeightRemap.y - _HeightRemap.x));
|
|
|
|
float blend = CombineHeight(height, newHeight, _CombineMode);
|
|
return PackHeightmap(clamp(lerp(height, blend, falloff), 0, kMaxHeight));
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
} |