Shader "Custom/UniversalLiquidSurface_DebugContact" { Properties { // Tryb (zostaw 3 = River) [Enum(River,3)] _SurfaceType ("Surface Type", Float) = 3 // Tekstury _MainTex ("Main Texture", 2D) = "white" {} _NormalMap ("Normal Map", 2D) = "bump" {} _FoamTex ("Foam Texture", 2D) = "white" {} // Kolory _ShallowColor ("Shallow Water Color (RGB+A)", Color) = (0.1, 0.9, 0.8, 0.3) _DeepColor ("Deep Water Color (RGB+A)", Color) = (0.0, 0.1, 0.3, 0.9) _RiverReflectionColor ("River Reflection Color", Color) = (0.4, 0.6, 0.9, 1) // Parametry kontaktu (okno tolerancji głębokości w przestrzeni kamery) _ContactMin ("Contact Min (eye-depth tolerance)", Float) = 0.02 _ContactMax ("Contact Max (eye-depth tolerance)", Float) = 0.15 // Przepływ i tilingi _RiverFlowSpeedX ("River Flow Speed X", Float) = 0.25 _RiverFlowSpeedY ("River Flow Speed Y", Float) = 0.15 _RiverMainTiling ("River Main Tiling", Float) = 1.0 _RiverNormalTiling ("River Normal Tiling", Float) = 1.0 _RiverFoamTiling ("River Foam Tiling", Float) = 3.0 _RiverFoamPulseSpeed ("River Foam Pulse Speed", Float) = 2.0 // Refleksy i piana _FoamStrength ("Foam Strength", Float) = 0.5 _ReflectionStrength ("Reflection Strength", Float) = 0.5 _RiverEdgeFoam ("River Edge Foam Strength", Float) = 0.5 } SubShader { Tags { "RenderPipeline"="UniversalRenderPipeline" "RenderType"="Transparent" "Queue"="Transparent" } Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Pass { Name "ForwardUnlit" Tags { "LightMode"="UniversalForward" } HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; float3 normalOS : NORMAL; }; struct Varyings { float4 positionHCS : SV_POSITION; float2 uv : TEXCOORD0; float3 normalWS : TEXCOORD1; float3 viewDirWS : TEXCOORD2; }; // Tekstury i samplery TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap); TEXTURE2D(_FoamTex); SAMPLER(sampler_FoamTex); // Depth z URP TEXTURE2D(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture); // ST float4 _MainTex_ST; float4 _NormalMap_ST; float4 _FoamTex_ST; // Parametry float _SurfaceType; float4 _ShallowColor; float4 _DeepColor; float4 _RiverReflectionColor; float _ContactMin; float _ContactMax; float _RiverFlowSpeedX; float _RiverFlowSpeedY; float _RiverMainTiling; float _RiverNormalTiling; float _RiverFoamTiling; float _RiverFoamPulseSpeed; float _FoamStrength; float _ReflectionStrength; float _RiverEdgeFoam; // Helpers float2 ApplyST(float2 uv, float4 st) { return uv * st.xy + st.zw; } float2 ComputeScreenUV(float4 positionHCS) { float2 uv = positionHCS.xy / positionHCS.w; // clip -> NDC uv = uv * 0.5 + 0.5; // -1..1 -> 0..1 return uv; } Varyings vert (Attributes IN) { Varyings OUT; OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); OUT.uv = IN.uv; OUT.normalWS = TransformObjectToWorldNormal(IN.normalOS); OUT.viewDirWS = GetWorldSpaceViewDir(TransformObjectToWorld(IN.positionOS.xyz)); return OUT; } half4 frag (Varyings IN) : SV_Target { if (_SurfaceType == 3) // River (debug pas kontaktu) { // Przepływ UV float2 uvFlow1 = ApplyST(IN.uv * _RiverMainTiling, _MainTex_ST); uvFlow1.y += _Time.y * _RiverFlowSpeedY; float2 uvFlow2 = ApplyST(IN.uv * _RiverMainTiling, _MainTex_ST); uvFlow2.x += _Time.y * _RiverFlowSpeedX; // Normal distortion half4 nTex = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, IN.uv * _RiverNormalTiling); float2 nDistort = (nTex.xy * 2.0 - 1.0) * 0.05; float2 uvDistorted = (uvFlow1 + uvFlow2) * 0.5 + nDistort; // Podstawowy kolor (nieużywany w debug, ale zostawiony dla spójności) half3 riverTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uvDistorted).rgb; // Depth float2 screenUV = ComputeScreenUV(IN.positionHCS); float rawSceneDepth = SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV).r; // Brak obiektu pod wodą -> czarne (brak kontaktu) if (rawSceneDepth >= 0.9999) { return half4(0,0,0,1); } float sceneDepth = LinearEyeDepth(rawSceneDepth, _ZBufferParams); float surfaceDepth = LinearEyeDepth(IN.positionHCS.z / IN.positionHCS.w, _ZBufferParams); // Absolutna różnica głębokości float depthDelta = abs(sceneDepth - surfaceDepth); // Okno tolerancji z miękkimi krawędziami (1 = kontakt, 0 = brak) float contactBand = 1.0 - smoothstep(_ContactMin, _ContactMax, depthDelta); // Zwracamy maskę kontaktową jako grayscale (DEBUG) return half4(contactBand.xxx, 1.0); } // Fallback magenta jeśli SurfaceType != River return half4(1,0,1,1); } ENDHLSL } } }