Shader "Hidden/Griffin/TextureStamperBrush" { Properties { _Mask ("Mask", 2D) = "white" {} _Falloff ("Falloff", 2D) = "black" {} _MinHeight ("Min Height", Range(0.0, 1.0)) = 0 _MaxHeight ("Max Height", Range(0.0, 1.0)) = 1 _HeightTransition ("Height Transition", 2D) = "white" {} _MinSlope ("Min Slope", Range(0.0, 1.0)) = 0 _MaxSlope ("Max Slope", Range(0.0, 1.0)) = 1 _SlopeTransition ("Slope Transition", 2D) = "white" {} _NoiseOrigin ("Noise Origin", Vector) = (0,0,0,0) _NoiseFrequency ("Noise Frequency", Float) = 1 _NoiseOctaves ("Noise Octaves", Int) = 1 _NoiseLacunarity ("Noise Lacunarity", Float) = 2 _NoisePersistence ("Noise Persistence", Float) = 0.5 _NoiseRemap ("Noise Remap", 2D) = "gray" {} _HeightMap ("Height Map", 2D) = "black" {} _NormalMap ("Normal Map", 2D) = "gray" {} _TerrainMask ("Terrain Mask", 2D) = "black" {} } SubShader { Tags { "RenderType"="Transparent" } Blend One Zero Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma shader_feature BLEND_HEIGHT #pragma shader_feature BLEND_SLOPE #pragma shader_feature BLEND_NOISE #include "UnityCG.cginc" #include "StampToolCommon.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; float4 normalizePos : TEXCOORD1; }; sampler2D _Mask; sampler2D _Falloff; float _MinHeight; float _MaxHeight; sampler2D _HeightTransition; float4 _HeightTransition_TexelSize; float _MinSlope; float _MaxSlope; sampler2D _SlopeTransition; float4 _NoiseOrigin; float _NoiseFrequency; int _NoiseOctaves; float _NoiseLacunarity; float _NoisePersistence; sampler2D _NoiseRemap; float _StamperMinHeight; float _StamperMaxHeight; sampler2D _HeightMap; sampler2D _NormalMap; float4x4 _LocalToWorld; sampler2D _TerrainMask; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; o.normalizePos = v.vertex; return o; } float4 frag (v2f i) : SV_Target { float blendHeightValue = 1; float4 heightMapColor = tex2D(_HeightMap, i.normalizePos); float height = GriffinDecodeFloatRG(heightMapColor.rg); #if BLEND_HEIGHT float heightTransitionFactor = (height-_MinHeight)/(_MaxHeight-_MinHeight); float heightTransition = tex2D(_HeightTransition, float2(heightTransitionFactor, 0.5)).r; blendHeightValue = (height>=_MinHeight)*(height<=_MaxHeight)*heightTransition; #endif float blendSlopeValue = 1; #if BLEND_SLOPE float4 normalMapColor = tex2D(_NormalMap, i.normalizePos); float3 normalVector = normalMapColor*2 - float3(1,1,1); float slopeAngle = acos(abs(normalVector.y)); float slopeTransitionFactor = (slopeAngle - _MinSlope)/(_MaxSlope - _MinSlope); float slopeTransition = tex2D(_SlopeTransition, float2(slopeTransitionFactor, 0.5f)).r; blendSlopeValue = (slopeAngle>=_MinSlope)*(slopeAngle<=_MaxSlope)*slopeTransition; #endif float blendNoiseValue = 1; #if BLEND_NOISE float2 refSize = float2(1,1); float noiseValue = 0; float frequency = _NoiseFrequency; float amplitude = 1; float2 noisePos; float2 uv; float sampledNoise; for (int octave=0; octave<4; ++octave) { frequency = frequency*pow(_NoiseLacunarity, octave); amplitude = amplitude*pow(_NoisePersistence, octave); noisePos = _NoiseOrigin.xy + i.uv*frequency; uv = float2(noisePos.x/refSize.x, noisePos.y/refSize.y); sampledNoise = GradientNoise(uv)*amplitude*(octave<_NoiseOctaves); noiseValue += sampledNoise; } float remapFactor = noiseValue*0.5 + 0.5; blendNoiseValue = tex2D(_NoiseRemap, float2(remapFactor, 0.5)).a; #endif float4 maskColor = tex2D(_Mask, i.uv); float maskValue = maskColor.r; float falloffFactor = saturate(2*length(i.uv-float2(0.5,0.5))); float4 falloffColor = tex2D(_Falloff, float2(falloffFactor,0.5)); float falloffValue = falloffColor.r; float insideStamperValue = (height>=_StamperMinHeight)*(height<=_StamperMaxHeight); float result = blendHeightValue * blendSlopeValue * blendNoiseValue * maskValue * falloffValue * insideStamperValue; float terrainMask = 1 - tex2D(_TerrainMask, i.normalizePos).r; result = lerp(0, result, terrainMask); return result; } ENDCG } } }