|
|
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" |
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" |
|
|
|
|
|
|
|
#pragma shader_feature _DEBUG |
|
|
|
#pragma multi_compile _ _DEBUG |
|
|
|
|
|
|
|
#pragma vertex vert |
|
|
|
#pragma fragment frag |
|
|
|
|
|
|
|
|
|
|
struct Varyings |
|
|
|
{ |
|
|
|
float2 uv : TEXCOORD0; |
|
|
|
float4 screenpos : TEXCOORD1; |
|
|
|
float4 positionOS : SV_POSITION; |
|
|
|
float3 positionWS : TEXCOORD2; |
|
|
|
float4 screenpos : TEXCOORD0; |
|
|
|
float4 positionCS : SV_POSITION; |
|
|
|
}; |
|
|
|
|
|
|
|
TEXTURE2D(_CausticMap); SAMPLER(sampler_CausticMap); |
|
|
|
|
|
|
half _BlendDistance; |
|
|
|
half4x4 _MainLightDir; |
|
|
|
|
|
|
|
// World Posision reconstriction |
|
|
|
#ifdef UNITY_REVERSED_Z |
|
|
|
depth = 1 - depth; |
|
|
|
float4x4 mat = UNITY_MATRIX_I_VP; |
|
|
|
#if UNITY_REVERSED_Z |
|
|
|
mat._12_22_32_42 = -mat._12_22_32_42; |
|
|
|
#else |
|
|
|
depth = depth * 2 - 1; |
|
|
|
// World Pos reconstriction |
|
|
|
float4 raw = mul(UNITY_MATRIX_I_VP, float4(screenPos * 2 - 1, depth * 2 - 1, 1)); |
|
|
|
float3 worldPos = raw.rgb / raw.a; |
|
|
|
float4 raw = mul(mat, float4(screenPos * 2 - 1, depth, 1)); |
|
|
|
float3 worldPos = raw.rgb / raw.a; |
|
|
|
return worldPos; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
//anim |
|
|
|
float2 uv = rawUV * _Size; |
|
|
|
return uv + offset * 0.1; |
|
|
|
} |
|
|
|
|
|
|
Varyings output; |
|
|
|
|
|
|
|
output.positionOS = vertexInput.positionCS; |
|
|
|
output.positionWS = vertexInput.positionWS; |
|
|
|
output.screenpos = ComputeScreenPos(output.positionOS); |
|
|
|
output.uv = float2(input.uv.x, 1.0 - input.uv.y); |
|
|
|
output.positionCS = vertexInput.positionCS; |
|
|
|
output.screenpos = ComputeScreenPos(output.positionCS); |
|
|
|
|
|
|
|
|
|
|
|
sampler2D _MainTex; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get depth |
|
|
|
|
|
|
|
// Get main light |
|
|
|
Light MainLight = GetMainLight(); |
|
|
|
|
|
|
|
// Reconstruct Position of objects in depth map |
|
|
|
Light mainLight = GetMainLight(); |
|
|
|
float3 lightPos = mul(WorldPos, _MainLightDir).xyz; |
|
|
|
// Get light direction and use it to rotate the world position |
|
|
|
float3 LightUVs = mul(WorldPos, _MainLightDir).xyz; |
|
|
|
// Read wave texture for noise to offset cautics UVs |
|
|
|
float2 causticUV = CausticUVs(lightPos.xy, waveOffset); |
|
|
|
float2 causticUV = CausticUVs(LightUVs.xy, waveOffset); |
|
|
|
float LodLevel = abs(WorldPos.y - _WaterLevel) * 4 / _BlendDistance; |
|
|
|
float4 A = SAMPLE_TEXTURE2D_LOD(_CausticMap, sampler_CausticMap, causticUV + _Time.x, LodLevel); |
|
|
|
float4 B = SAMPLE_TEXTURE2D_LOD(_CausticMap, sampler_CausticMap, causticUV * 2.0, LodLevel); |
|
|
|
|
|
|
|
float CausticsDriver = (A.z * B.z) * 10 + A.z + B.z; |
|
|
|
|
|
|
|
// Mask caustics from above water and fade below |
|
|
|
|
|
|
|
float4 ref1 = SAMPLE_TEXTURE2D_LOD(_CausticMap, sampler_CausticMap, causticUV + _Time.x, abs(WorldPos.y - _WaterLevel) * 4 / _BlendDistance); |
|
|
|
float4 ref2 = SAMPLE_TEXTURE2D_LOD(_CausticMap, sampler_CausticMap, causticUV * 2, abs(WorldPos.y - _WaterLevel) * 4 / _BlendDistance); |
|
|
|
CausticsDriver *= min(upperMask, lowerMask); |
|
|
|
float ref = (ref1.z * ref2.z) * 10 + ref1.z + ref2.z; |
|
|
|
float3 caustics = ref * min(upperMask, lowerMask); |
|
|
|
caustics *= float3(ref1.w * 0.5, ref2.w * 0.75, ref2.x) * mainLight.color; |
|
|
|
// Fake light dispersion |
|
|
|
half3 Caustics = CausticsDriver * half3(A.w * 0.5, B.w * 0.75, B.x) * MainLight.color; |
|
|
|
half3 output = caustics + 1; |
|
|
|
return real4(caustics, 1); |
|
|
|
return real4(Caustics, 1.0); |
|
|
|
return real4(output, 1); |
|
|
|
// Add 1 for blending level to work nicely |
|
|
|
return real4(Caustics + 1.0, 1.0); |
|
|
|
} |
|
|
|
ENDHLSL |
|
|
|
} |