Files
Fishing2/Assets/ThirdParty/LuxWater/Shaders/Includes/LuxWater_Utils.cginc
2025-05-10 12:49:47 +08:00

146 lines
5.7 KiB
HLSL

// expects first normal to be unpacked already
half3 UnpackAndBlendNormals(fixed3 n1, fixed4 n2, fixed4 n3) {
half3 normal;
#if defined(UNITY_NO_DXT5nm)
normal = normalize( n1 + (n2.xyz * 2 - 1) + (n3.xyz * 2 - 1) );
#else
normal.xy = n1.xy;
normal.xy += (n2.ag * 2 - 1) * _BumpScale.y;
normal.xy += (n3.ag * 2 - 1) * _BumpScale.z;
normal.z = sqrt(1.0 - saturate( normal.x * normal.x + normal.y * normal.y));
normal = normalize(normal);
#endif
return normal;
}
half3 WorldNormal(half3 t0, half3 t1, half3 t2, half3 normal) {
// normalize is done once in the fragment shader
return /*normalize*/( half3( dot(t0, normal), dot(t1, normal), dot(t2, normal) ) );
}
float2 rotate2D(float2 v, float a) {
float s = sin(a);
float c = cos(a);
float2x2 m = float2x2(c, -s, s, c);
return mul(m, v);
}
// Shadow Helpers -------------------------------------------------
UNITY_DECLARE_SHADOWMAP(_LuxParticles_CascadedShadowMap);
float computeShadowFadeDistance(float3 wpos, float z) {
float sphereDist = distance(wpos, unity_ShadowFadeCenterAndType.xyz);
return lerp(z, sphereDist, unity_ShadowFadeCenterAndType.w);
}
half computeShadowFade(float fadeDist) {
return saturate(fadeDist * _LightShadowData.z + _LightShadowData.w);
}
inline fixed4 getCascadeWeights_splitSpheres(float3 wpos) {
float3 fromCenter0 = wpos.xyz - unity_ShadowSplitSpheres[0].xyz;
float3 fromCenter1 = wpos.xyz - unity_ShadowSplitSpheres[1].xyz;
float3 fromCenter2 = wpos.xyz - unity_ShadowSplitSpheres[2].xyz;
float3 fromCenter3 = wpos.xyz - unity_ShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
fixed4 weights = float4(distances2 < unity_ShadowSplitSqRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
return weights;
}
inline float4 getShadowCoord(float4 wpos, fixed4 cascadeWeights) {
float3 sc0 = mul(unity_WorldToShadow[0], wpos).xyz;
float3 sc1 = mul(unity_WorldToShadow[1], wpos).xyz;
float3 sc2 = mul(unity_WorldToShadow[2], wpos).xyz;
float3 sc3 = mul(unity_WorldToShadow[3], wpos).xyz;
float4 shadowMapCoordinate = float4(sc0 * cascadeWeights[0] + sc1 * cascadeWeights[1] + sc2 * cascadeWeights[2] + sc3 * cascadeWeights[3], 1);
#if defined(UNITY_REVERSED_Z)
float noCascadeWeights = 1 - dot(cascadeWeights, float4(1, 1, 1, 1));
shadowMapCoordinate.z += noCascadeWeights;
#endif
return shadowMapCoordinate;
}
float GetLightAttenuation(float3 wpos) {
// Directional Lights only
float atten = 1;
fixed4 cascadeWeights = getCascadeWeights_splitSpheres(wpos);
float4 coord = getShadowCoord(float4(wpos, 1), cascadeWeights);
atten = UNITY_SAMPLE_SHADOW(_LuxParticles_CascadedShadowMap, coord.xyz);
// Fade out shadows
float zDist = dot(_WorldSpaceCameraPos - wpos, UNITY_MATRIX_V[2].xyz);
float fadeDist = computeShadowFadeDistance(wpos, zDist);
half realtimeShadowFade = computeShadowFade(fadeDist);
atten = lerp (_LightShadowData.r, 1.0f, saturate(atten + realtimeShadowFade));
return atten;
}
// https://forum.unity.com/threads/fixing-screen-space-directional-shadows-and-anti-aliasing.379902/
// Thanks bgolus once more!
float MSSADepth(float fragDepth, float sceneDepth, float depth_raw, float2 screenUV) {
// this is good far distances but bad at close distances
// screenUV.xy = (screenUV.xy * (_CameraDepthTexture_TexelSize.zw - 1.0) + 0.5f) * _CameraDepthTexture_TexelSize.xy;
// this is bad too
// screenUV = (floor(screenUV * _CameraDepthTexture_TexelSize.zw) + 0.5) / _CameraDepthTexture_TexelSize.zw;
// Testing, testing, testing - and finding a good compromise...
// screenUV.x -= _CameraDepthTexture_TexelSize.x;
float depthDiff = abs(fragDepth - sceneDepth); //LinearEyeDepth(depth_raw));
// The if does not safe much but stabilizes results (jittering)
if (depthDiff < 20.0) {
// Would help the 0,1 offsets
//screenUV.x -= 0.975 * _CameraDepthTexture_TexelSize.x;
float2 texelSize = _CameraDepthTexture_TexelSize.xy;
float4 offsetDepths = 0;
// https://github.com/TheRealMJP/MSAAFilter/blob/master/MSAAFilter/Resolve.hlsl
// These offsets are not very stable
#define FACTOR 1.0f
float2 uvOffsetsX[5] = {
float2(-0.125f, -0.375f) * FACTOR * texelSize,
float2(0.375f, -0.125f) * FACTOR * texelSize,
float2(-0.375f, 0.125f) * FACTOR * texelSize,
float2(0.125f, 0.375f) * FACTOR * texelSize,
float2(0.0, 0.0)
};
// These offsets create strange jagged artifacts
float2 uvOffsets[5] = {
float2(1.0, 0.0) * texelSize,
float2(-1.0, 0.0) * texelSize,
float2(0.0, 1.0) * texelSize,
float2(0.0, -1.0) * texelSize,
float2(0.0, 0.0)
};
offsetDepths.x = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(screenUV + uvOffsets[0], 0, 0));
offsetDepths.y = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(screenUV + uvOffsets[1], 0, 0));
offsetDepths.z = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(screenUV + uvOffsets[2], 0, 0));
offsetDepths.w = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(screenUV + uvOffsets[3], 0, 0));
float4 offsetDiffs = abs(fragDepth - offsetDepths);
float diffs[4] = { offsetDiffs.x, offsetDiffs.y, offsetDiffs.z, offsetDiffs.w };
int lowest = 0;
float tempDiff = depthDiff;
for (int i = 0; i < 4; i++) {
// TODO: why is it flipped - at least when using perspective?
#if defined(UNITY_REVERSED_Z)
if (diffs[i] > tempDiff) { // DX11
#else
if (diffs[i] < tempDiff) { // OpenGL
#endif
tempDiff = diffs[i];
lowest = i;
}
}
return SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(screenUV + uvOffsets[lowest], 0, 0));
}
else {
return depth_raw;
}
}