174 lines
7.5 KiB
Plaintext
174 lines
7.5 KiB
Plaintext
|
|
|
|
|
|
half FilterParticulateRange(float4 range, float y)
|
|
{
|
|
half w = saturate((y - range.x) / max(range.y - range.x, 0.0001));
|
|
w *= 1.0 - saturate((y - range.z) / max(range.w - range.z, 0.0001));
|
|
return w;
|
|
}
|
|
|
|
half FilterParticulateSlope(float4 range, float3 worldNormalVertex, float windRot)
|
|
{
|
|
float2 windDir = RotateUV(float2(1, 0), windRot);
|
|
// fix for denormalization from normalize
|
|
float2 flow = worldNormalVertex.y < 0.99 ? lerp(worldNormalVertex.xz, normalize(worldNormalVertex.xz), max(0.1, worldNormalVertex.z)) : worldNormalVertex.xz;
|
|
float cofacing = dot(windDir, flow); // 1 going downhill, -1 going uphill
|
|
return FilterParticulateRange(range, cofacing);
|
|
}
|
|
|
|
fixed ComputeParticulateMask(float2 wuv, float4 parms)
|
|
{
|
|
wuv *= float2(parms.z, 1) * parms.w;
|
|
float speed = _Time.x * parms.x;
|
|
fixed w1 = SAMPLE_TEXTURE2D(_GlitterWind, sampler_Diffuse, wuv * 3 + speed * float2(1,0)).a;
|
|
fixed w2 = SAMPLE_TEXTURE2D(_GlitterWind, sampler_Diffuse, wuv + speed * float2(1.1,0)).a;
|
|
return (w1 * w2);
|
|
}
|
|
|
|
fixed ProcessParticulateMask(inout fixed mask, float contrast)
|
|
{
|
|
mask = pow(mask, abs(contrast));
|
|
fixed invMask = 1.0 - mask;
|
|
invMask *= invMask;
|
|
invMask *= invMask;
|
|
return invMask;
|
|
}
|
|
|
|
void DoWindParticulate(Input i, inout MicroSplatLayer o, Config config, half4 weights, float camDist, float3 worldNormalVertex, half snowWeight)
|
|
{
|
|
|
|
#if defined(UNITY_PASS_FORWARDBASE) || defined(UNITY_PASS_DEFERRED) || (defined(_HDRP) || _URP)
|
|
|
|
float3 lightTS = GetGlobalLightDirTS(i);
|
|
|
|
float3 upVector = float3(0,0,1);
|
|
|
|
half upDot = max(0.0, dot(worldNormalVertex, i.worldUpVector));
|
|
|
|
float2 uv = i.worldPos.xz * 0.01;
|
|
#if _PLANETVECTORS
|
|
uv = i.uv_Control0.xy;
|
|
#endif
|
|
#if _GLOBALPARTICULATEROTATION
|
|
float windRotation = _Global_WindParticulateRotation;
|
|
#else
|
|
float windRotation = _WindParticulateRotation;
|
|
#endif
|
|
|
|
float2 wuv = RotateUV(uv, windRotation);
|
|
|
|
half windBlend = 1.0;
|
|
#if _PERTEXWINDPARTICULATE
|
|
SAMPLE_PER_TEX(ptWind, 7.5, config, half4(1,1,1,1));
|
|
windBlend = BlendWeights(ptWind0.a, ptWind1.a, ptWind2.a, ptWind3.a, weights);
|
|
#endif
|
|
|
|
#if _WINDPARTICULATE || _WINDSHADOWS
|
|
float windWorldMask = FilterParticulateRange(_WindParticulateHeightMask, i.worldPos.y);
|
|
windWorldMask *= FilterParticulateRange(_WindParticulateAngleMask, upDot);
|
|
#if _WINDPARTICULATEUPFILTER
|
|
windWorldMask *= FilterParticulateSlope(_WindParticulateUpMask, worldNormalVertex, windRotation);
|
|
#endif
|
|
#endif
|
|
|
|
#if _WINDSHADOWS
|
|
float2 offset = lightTS.yx * _WindParticulateShadow.x;
|
|
fixed shadowMask = ComputeParticulateMask(wuv + offset.xy, _WindParticulateParams);
|
|
|
|
#if _GLOBALWINDPARTICULATESTRENGTH
|
|
float shadowWindStrength = _Global_WindParticulateStrength;
|
|
#else
|
|
float shadowWindStrength = _WindParticulateStrength;
|
|
#endif
|
|
shadowMask *= shadowWindStrength * windBlend * windWorldMask;
|
|
shadowMask *= (1.0 - snowWeight);
|
|
|
|
fixed shadowInvMask = ProcessParticulateMask(shadowMask, _WindParticulateParams.y);
|
|
o.Albedo = lerp(o.Albedo, o.Albedo * _WindParticulateShadowColor.rgb * _WindParticulateShadowColor.a, saturate(shadowMask * _WindParticulateShadow.y));
|
|
o.Normal.xy *= shadowInvMask;
|
|
o.Occlusion -= shadowMask * 0.5 * _WindParticulateOcclusionStrength;
|
|
o.Smoothness *= shadowInvMask;
|
|
o.Metallic *= shadowInvMask;
|
|
#endif
|
|
|
|
#if _WINDPARTICULATE
|
|
// compute mask
|
|
fixed windMask = ComputeParticulateMask(wuv, _WindParticulateParams);
|
|
|
|
#if _GLOBALWINDPARTICULATESTRENGTH
|
|
float windStrength = _Global_WindParticulateStrength;
|
|
#else
|
|
float windStrength = _WindParticulateStrength;
|
|
#endif
|
|
|
|
windMask *= windStrength * windBlend * windWorldMask;
|
|
windMask *= (1.0 - snowWeight);
|
|
|
|
fixed windInvMask = ProcessParticulateMask(windMask, _WindParticulateParams.y);
|
|
|
|
o.Albedo = lerp(o.Albedo, _WindParticulateColor.rgb, windMask * _WindParticulateColor.a);
|
|
o.Emission += _WindParticulateColor.rgb * windMask * _WindParticulateColor.a * _WindEmissive.x;
|
|
o.Normal.xy *= windInvMask;
|
|
o.Smoothness *= windInvMask;
|
|
o.Occlusion -= (1.0 - windInvMask) * _WindParticulateOcclusionStrength;
|
|
o.Metallic *= windInvMask;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#if _SNOWPARTICULATE || _SNOWSHADOWS
|
|
float snowWorldMask = FilterParticulateRange(_SnowParticulateHeightMask, i.worldPos.y);
|
|
snowWorldMask *= FilterParticulateRange(_SnowParticulateAngleMask, upDot);
|
|
#if _WINDPARTICULATEUPFILTER
|
|
snowWorldMask *= FilterParticulateSlope(_SnowParticulateUpMask, worldNormalVertex, windRotation);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#if _SNOWSHADOWS
|
|
float2 snowOffset = lightTS.yx * _SnowParticulateShadow.x;
|
|
#if _GLOBALSNOWPARTICULATESTRENGTH
|
|
float snowShadowStrength = _Global_SnowParticulateStrength;
|
|
#else
|
|
float snowShadowStrength = _SnowParticulateStrength;
|
|
#endif
|
|
|
|
fixed snowShadowMask = ComputeParticulateMask(wuv + snowOffset.xy, _SnowParticulateParams) * snowShadowStrength;
|
|
snowShadowMask *= snowWeight * snowWorldMask;
|
|
|
|
fixed snowShadowInvMask = ProcessParticulateMask(snowShadowMask, _SnowParticulateParams.y);
|
|
o.Albedo = lerp(o.Albedo, o.Albedo * _SnowParticulateShadowColor.rgb * _SnowParticulateShadowColor.a, saturate(snowShadowMask * _SnowParticulateShadow.y));
|
|
|
|
o.Normal.xy *= snowShadowInvMask;
|
|
o.Occlusion -= snowShadowMask * 0.5 * _SnowParticulateOcclusionStrength;
|
|
o.Smoothness *= snowShadowInvMask;
|
|
o.Metallic *= snowShadowInvMask;
|
|
#endif
|
|
|
|
#if _SNOWPARTICULATE
|
|
// compute mask
|
|
#if _GLOBALSNOWPARTICULATESTRENGTH
|
|
float snowStrength = _Global_SnowParticulateStrength;
|
|
#else
|
|
float snowStrength = _SnowParticulateStrength;
|
|
#endif
|
|
|
|
fixed snowMask = ComputeParticulateMask(wuv, _SnowParticulateParams) * snowStrength;
|
|
snowMask *= snowWeight * snowWorldMask;
|
|
fixed snowInvMask = ProcessParticulateMask(snowMask, _SnowParticulateParams.y);
|
|
|
|
o.Albedo = lerp(o.Albedo, _SnowParticulateColor.rgb, snowMask * _SnowParticulateColor.a);
|
|
o.Emission += _SnowParticulateColor.rgb * _SnowParticulateColor.a * snowMask * _WindEmissive.y;
|
|
o.Normal.xy *= snowInvMask;
|
|
o.Smoothness *= snowInvMask;
|
|
o.Occlusion -= (1-snowInvMask) * _SnowParticulateOcclusionStrength;
|
|
o.Metallic *= snowInvMask;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
}
|