Files
Fishing2/Assets/ThirdParty/LuxWater/Shaders/LuxWater_SurfaceShader_deprecated.__shader
2025-05-10 12:49:47 +08:00

879 lines
32 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Shader "Lux Water/WaterSurface SurfaceShader deprecated" {
Properties {
[Enum(Off,0,On,1)]_ZWrite ("ZWrite", Float) = 1.0
[Enum(UnityEngine.Rendering.CullMode)] _Culling ("Culling", Float) = 0
[Space(5)]
[Toggle(EFFECT_BUMP)]
_UVSpaceMappingEnabled ("UV Space Texture Mapping", Float) = 0
[Space(5)]
[Toggle(USINGWATERVOLUME)]
_UsesWaterVolume ("Uses Water Volume", Float) = 0
_WaterSurfaceYPos (" Water Surface Position (Y)", Float) = 0
[Header(Basic Properties)]
_Glossiness (" Smoothness", Range(0,1)) = 0.92
_SpecColor (" Specular", Color) = (0.15,0.15,0.15)
[Space(5)]
_InvFade (" Edge Blend Factor", Range(0.001, 6)) = 1
[Header(Reflections)]
[Toggle(GEOM_TYPE_MESH)]
_PlanarEnabled (" Enable Planar Reflections", Float) = 0
[HideInInspector]_LuxWater_ReflectionTex("ReflectionTex", 2D) = "gray" {}
[Space(5)]
_FresnelPower (" Fresnel Power", Range(1,5)) = 5
_ReflectionStrength (" Strength", Range(0,1)) = 1
_ReflectionGlossiness (" Smoothness", Range(0,1)) = 1
_ReflectionBumpScale (" Bump Scale", Range(0,1)) = 0.3
[Space(5)]
_WaterIOR (" Underwater IOR", Range(1.1,1.4)) = 1.3333
_UnderWaterReflCol (" Underwater Reflection Tint", Color) = (1,1,1,0)
[Header(Underwater Fog)]
_Color (" Fog Color", Color) = (1,1,1,1)
[LuxWaterVectorThreeDrawer]
_DepthAtten (" - Depth: Fade Start (X) Fade Range (Y) Density (Z)", Vector) = (0, 32, 1, 0)
[PowerSlider(3.0)] _Density (" - View Depth", Range(0.0,4)) = 0.1
_FogAbsorptionCancellation (" Absorption Cancellation", Range(0.0,1)) = 1
[Header(Light Absorption)]
[Space(4)]
_AbsorptionStrength (" Strength", Range(0,1)) = 1
_AbsorptionHeight (" - Depth", Range(0.0,8)) = 1
_AbsorptionMaxHeight (" - Max Depth", Float) = 60
_AbsorptionDepth (" - View Depth", Range(0,0.2)) = 0.07
_AbsorptionColorStrength (" Color Absorption", Range(0,1)) = 0.5
[Header(Translucent Lighting)]
_TranslucencyColor (" Translucency Color", color) = (0.1,0.2,0.3,0)
_ScatteringPower (" Scattering Power", Range(0.1, 10.0)) = 5
[Header(Normals)]
[NoScaleOffset] _BumpMap (" Normal Map", 2D) = "bump" {}
[Header( Far Normal)]
[LuxWaterVectorTwoDrawer]
_FarBumpSampleParams (" Tiling (X) Fade (Y)", Vector) = (0.25, 0.01, 0, 0)
[Header( Detail Normals)]
[LuxWaterVectorThreeDrawer]
_BumpScale (" Scale", Vector) = (1, 0.5, 0.25, 0)
[LuxWaterVectorFourGFDrawer]
_BumpTiling (" Tiling", Vector) = (1, 0.5, 0.478, 0.1)
[LuxWaterVectorFourGFDrawer]
_BumpSpeed (" Speed", Vector) = (1.7, 1.0, 0, 1.0)
[LuxWaterVectorFourGFDrawer]
_BumpRotation (" Rotation", Vector) = (0, 8.0, 32.0, 0)
// Combined Speed and Rotation Values
[HideInInspector]_FinalBumpSpeed01(" Final BumpSpeed01", Vector) = (0, 0, 0, 0)
[HideInInspector]_FinalBumpSpeed23(" Final BumpSpeed23", Vector) = (0, 0, 0, 0)
[Space(5)]
_Refraction (" Refraction", Range(0,1024)) = 512
[Header(Foam)]
[Toggle(GEOM_TYPE_BRANCH_DETAIL)] _FoamEnabled (" Enable Foam", Float) = 1
[NoScaleOffset]_MainTex (" Normal (RGB) Mask (A)", 2D) = "white" {}
_FoamTiling (" Tiling", Float) = .1
[Space(5)]
_FoamColor (" Color (RGB) Opacity (A)", color) = (0.7, 0.7, 0.7, 0.8)
_FoamScale (" Scale", Range(0, 40)) = 20
_FoamSpeed (" Speed", Float) = 0.9
_FoamParallax (" Parallax", Range(0.0, 1)) = .35
_FoamNormalScale (" Normal Scale", Float) = 1
_FoamSoftIntersectionFactor (" Edge Blend Factor", Range(0.0, 3)) = 1
[Header(Caustics)]
[Toggle(GEOM_TYPE_FROND)]
_CausticsEnabled (" Enable Caustics", Float) = 1
[Toggle(GEOM_TYPE_LEAF)]
_CausticMode (" Normals from GBuffer", Float) = 1
[NoScaleOffset] _CausticTex (" Caustics (R) Noise (GB)", 2D) = "black" {}
_CausticsTiling (" Tiling", Float) = .1
[Space(5)]
_CausticsScale (" Scale", Range(0, 8)) = 2
_CausticsSpeed (" Speed", Float) = 0.9
_CausticsSelfDistortion (" Distortion", Float) = 0.2
[Header(Advanced Options)]
[Toggle(GEOM_TYPE_BRANCH)]
_PixelSnap (" Enable Pixel Snapping", Float) = 0
[Header(Gerstner Waves)]
[Toggle(_GERSTNERDISPLACEMENT)]
_GerstnerEnabled (" Enable Gerstner Waves", Float) = 0
[Space(5)]
[LuxWaterVectorFourDrawer]
_GAmplitude (" Amplitude", Vector) = (0.3 ,0.35, 0.25, 0.25)
[Space(24)]
[LuxWaterVectorFourDrawer]
_GFrequency (" Frequency", Vector) = (1.3, 1.35, 1.25, 1.25)
[LuxWaterGFDrawer]
_GGlobalFrequency (" Global Factor", Float) = 1.0
[HideInInspector]
_GFinalFrequency (" Final Frequency", Vector) = (1.3, 1.35, 1.25, 1.25)
[LuxWaterVectorFourDrawer]
_GSteepness (" Steepness", Vector) = (1.0, 1.0, 1.0, 1.0)
[Space(24)]
[LuxWaterVectorFourDrawer]
_GSpeed (" Speed", Vector) = (1.2, 1.375, 1.1, 1.5)
[LuxWaterGFDrawer]_GGlobalSpeed (" Global Factor", Float) = 1.0
[HideInInspector]_GFinalSpeed (" Final Speed", Vector) = (1.2, 1.375, 1.1, 1.5)
[LuxWaterVectorFourDrawer]
_GRotation (" Rotation", Vector) = (0, 8.0, 32.0, 0)
[LuxWaterGFDrawer]
_GGlobalRotation (" Global Factor", Float) = 0
[HideInInspector]_GDirectionAB (" Direction AB", Vector) = (0.3 ,0.85, 0.85, 0.25)
[HideInInspector]_GDirectionCD (" Direction CD", Vector) = (0.1 ,0.9, 0.5, 0.5)
[Space(5)]
[LuxWaterVectorThreeDrawer]
_GerstnerVertexIntensity (" Final Displacement", Vector) = (1.0,1.0,1.0,0.0)
[Space(5)]
_GerstnerNormalIntensity (" Normal Scale", Range(0,1)) = 0.05
//_GerstnerVerticalIntensity (" Vertical Displacement", Range(0,1)) = 0.05
_FoamCaps (" Foam Caps", Range(0,4)) = 0.5
}
SubShader {
Tags {"Queue"="Transparent-1" "RenderType"="Opaque" "ForceNoShadowCasting" = "True"}
LOD 200
// Metal: We have to explicitly set ZWrite Off only if camera uses deferred rendering
// But then we can not have multiple overlapping volumes on no 2 pass shader ... :(
// Let's use VFACE instead
ZWrite [_ZWrite]
ZTest LEqual
Cull [_Culling]
Blend SrcAlpha OneMinusSrcAlpha
GrabPass{ "_GrabTexture" }
CGPROGRAM
#pragma surface surf StandardSpecularLuxWater vertex:vert novertexlights nometa keepalpha nolightmap addshadow nofog
#pragma target 3.0
#pragma exclude_renderers d3d9 d3d11_9x
// Fog Mode
// #define FOG_LINEAR
// #define FOG_EXP
#define FOG_EXP2
// Metal deffered support
//#define LUXWATERMETALDEFERRED
// Water projector support
// #pragma multi_compile __ USINGWATERPROJECTORS
// Water volume support
#pragma multi_compile __ USINGWATERVOLUME
// In order to safe keywords we use speedtree's keywords
// Planar reflections
// #pragma multi_compile __ GEOM_TYPE_MESH
// Foam
#pragma shader_feature GEOM_TYPE_BRANCH_DETAIL
// Caustics
#pragma shader_feature GEOM_TYPE_FROND
// Caustic Normal Mode
#pragma shader_feature GEOM_TYPE_LEAF
// Gerstner Waves
#pragma shader_feature _GERSTNERDISPLACEMENT
// Snapping
// #pragma shader_feature GEOM_TYPE_BRANCH
// Texture Mapping
// #pragma shader_feature EFFECT_BUMP
#include "Includes/LuxWater_PBSLighting.cginc"
// To make it still compile...
#if defined(SHADER_API_METAL) && defined(LUXWATERMETALDEFERRED)
sampler2D _Lux_GrabbedDepth;
float4 _Lux_GrabbedDepth_TexelSize;
#else
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
float4 _CameraDepthTexture_TexelSize;
#endif
sampler2D _MainTex;
// Normal maps
float2 _FarBumpSampleParams;
float4 _BumpTiling;
float4 _BumpScale;
float4 _FinalBumpSpeed01;
float2 _FinalBumpSpeed23;
struct appdata_water {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
//float4 texcoord : TEXCOORD0;
fixed4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Input {
float4 BumpUVs;
float4 grabUV;
float4 ViewRay_WaterYpos;
#if defined(USINGWATERPROJECTORS)
float4 projectorScreenPos;
#else
float4 BumpSmallAndFoamUVs;
#endif
fixed4 color : COLOR0;
float facingSign : VFACE;
float3 viewDir;
float3 worldNormal;
float3 worldPos;
INTERNAL_DATA
};
uniform float _WaterSurfaceYPos;
// Gerstner Waves
float3 _GerstnerVertexIntensity;
float _GerstnerNormalIntensity;
//float _GerstnerVerticalIntensity;
uniform float4 _GAmplitude;
uniform float4 _GFinalFrequency;
uniform float4 _GSteepness;
uniform float4 _GFinalSpeed;
uniform float4 _GDirectionAB;
uniform float4 _GDirectionCD;
#include "Includes/LuxWater_Utils.cginc"
#include "Includes/LuxWater_GerstnerWaves.cginc"
void vert(inout appdata_full v, out Input o) {
UNITY_INITIALIZE_OUTPUT(Input, o);
// Calculate wpos up front as we need it anyway and it allows us to optimize other calculations
float4 wpos = mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1.0));
// In case we use water projector and gerstnerwaves we need the undistored screenUVs
#if defined(USINGWATERPROJECTORS) && defined(_GERSTNERDISPLACEMENT)
float4 hposOrig = mul(UNITY_MATRIX_VP, wpos);
o.projectorScreenPos = ComputeScreenPos(hposOrig);
#endif
#if defined(EFFECT_BUMP)
// uv
float2 BaseUVs = v.texcoord.xy * _BumpTiling.w;
#else
// world space texure mapping
float2 BaseUVs = wpos.xz * _BumpTiling.w;
#endif
#if defined(_GERSTNERDISPLACEMENT)
half3 vtxForAni = (wpos).xzz;
half3 nrml;
half3 offsets;
Gerstner (
offsets, nrml, v.vertex.xyz, vtxForAni, // offsets, nrml will be written
_GAmplitude, // amplitude
_GFinalFrequency, // frequency
_GSteepness, // steepness
_GFinalSpeed, // speed
_GDirectionAB, // direction # 1, 2
_GDirectionCD // direction # 3, 4
);
//v.vertex.xyz += offsets; // * _GerstnerIntensity;
v.normal = nrml;
// Actually not doing anything with the tangent looks most like water...
// Estimate the tangent
/* v.tangent.xyz = cross(v.normal, float3(0,0,1));
v.tangent.w = -1;
*/
// A general tangent estimation
/* float3 T1 = float3(1, 0, 1);
float3 Bi = cross(T1, v.normal);
float3 newTangent = cross(v.normal, Bi);
normalize(newTangent);
v.tangent.xyz = newTangent.xyz;
w should be fine
if (dot(cross(v.normal,newTangent),Bi) < 0)
v.tangent.w = -1.0f;
else
v.tangent.w = 1.0f;
*/
// version 1.01: power 3 skipped, new factor
float foam = offsets.y /* * offsets.y * offsets.y */ + (abs(offsets.x) + abs(offsets.z)) * 0.1875; // * 0.125;
// version 1.01: smoothstep added
v.color.a = smoothstep(0.0, 1.0, saturate(foam));
// version 1.02: Apply Gerstner dispalcement in world space
wpos.xyz += offsets * v.color.r;
v.vertex = mul(unity_WorldToObject, wpos);
// Debug - will be skipped by the compiler
//v.color.rgb = COMPUTE_VIEW_NORMAL * 0.5 + 0.5;
//v.color.rgb = mul((float3x3)UNITY_MATRIX_MVP, v.normal);
#endif
// Calculate ClipPos (optimized)
float4 hpos = mul(UNITY_MATRIX_VP, wpos);
// Get Grab UVs
o.grabUV = ComputeGrabScreenPos(hpos); // grabUV.w = hpos.w = eyedepth
// Calculate ViewRay by transforming WorldPos to ViewPos (optimized)
o.ViewRay_WaterYpos.xyz = mul(UNITY_MATRIX_V, wpos).xyz * float3(-1, -1, 1);
// Store wpos.y of watersurface
o.ViewRay_WaterYpos.w = wpos.y;
// UVs
#if !defined(USINGWATERPROJECTORS)
o.BumpUVs.xy = BaseUVs * _BumpTiling.x + _Time.xx * _FinalBumpSpeed01.xy;
o.BumpUVs.zw = BaseUVs * _BumpTiling.y + _Time.xx * _FinalBumpSpeed01.zw;
o.BumpSmallAndFoamUVs.xy = BaseUVs * _BumpTiling.z + _Time.xx * _FinalBumpSpeed23.xy;
#else
o.BumpUVs.xy = BaseUVs;
#endif
}
// Basic Properties
half _Glossiness;
half _InvFade;
// Reflections
half _ReflectionBumpScale;
half _ReflectionGlossiness;
// Planar reflections
#if defined(GEOM_TYPE_MESH)
sampler2D _LuxWater_ReflectionTex;
half _LuxWater_ReflectionTexMip;
float4 _LuxWater_ReflectionTex_TexelSize;
#endif
// Underwater Fog
fixed4 _Color;
half3 _DepthAtten;
half _Density;
half _FinalFogDensity;
half _FogAbsorptionCancellation;
// Absorption
half _AbsorptionHeight;
half _AbsorptionMaxHeight;
float _AbsorptionDepth;
fixed _AbsorptionColorStrength;
fixed _AbsorptionStrength;
// Normals
sampler2D _BumpMap;
half _Refraction;
// Foam
fixed4 _FoamColor;
half _FoamScale;
float _FoamSpeed;
half _FoamParallax;
half _FoamSoftIntersectionFactor;
float _FoamTiling;
float _FoamNormalScale;
half _FoamCaps;
// Caustics
sampler2D _CausticTex;
#if defined(GEOM_TYPE_LEAF)
sampler2D _CameraGBufferTexture2; //Deferred Normals
#endif
half _CausticsScale;
half _CausticsSpeed;
half _CausticsTiling;
half _CausticsSelfDistortion;
// Water projectors
#if defined(USINGWATERPROJECTORS)
sampler2D _LuxWater_FoamOverlay;
sampler2D _LuxWater_NormalOverlay;
#endif
// Metal fix
#if defined(SHADER_API_METAL)
float _Culling;
#endif
// Translucency (in lighting function)
//half _ScatteringPower;
//half3 _TranslucencyColor;
sampler2D _GrabTexture;
float4 _GrabTexture_TexelSize;
void surf (Input IN, inout SurfaceOutputStandardSpecularLuxWater o) {
#define surfaceEyeDepth IN.grabUV.w
float3 viewDir = normalize(IN.viewDir);
fixed4 c = _Color;
// -----------------------------------------------------------------------
// Water Projectors: Get screen UVs and vignette
#if defined(USINGWATERPROJECTORS)
float2 projectionUVs;
#if defined(_GERSTNERDISPLACEMENT)
projectionUVs = IN.projectorScreenPos.xy / IN.projectorScreenPos.w;
float2 strength = abs(projectionUVs - 0.5); // 0 - 0.5 range
strength = saturate ((float2(0.5, 0.5) - strength) * 2);
float vignette = min(strength.x, strength.y);
vignette = saturate(vignette * 4); // sharpen
#else
projectionUVs = IN.grabUV.xy / IN.grabUV.w;
#endif
#endif
// -----------------------------------------------------------------------
// Init smoothness which will be tweaked later on
o.Smoothness = _Glossiness;
o.ReflectionSmoothness = _ReflectionGlossiness;
o.Specular = _SpecColor;
// -----------------------------------------------------------------------
// Animate and blend normals
// Sample and blend far and 1st detail normal
#if defined(USINGWATERPROJECTORS)
float4 BumpUVs;
BumpUVs.xy = IN.BumpUVs.xy * _BumpTiling.x + _Time.xx * _FinalBumpSpeed01.xy;
BumpUVs.zw = IN.BumpUVs.xy * _BumpTiling.y + _Time.xx * _FinalBumpSpeed01.zw;
float2 BumpSmallAndFoamUVs = IN.BumpUVs.xy * _BumpTiling.z + _Time.xx * _FinalBumpSpeed23.xy;
#else
float4 BumpUVs = IN.BumpUVs;
float2 BumpSmallAndFoamUVs = IN.BumpSmallAndFoamUVs.xy;
#endif
fixed4 farSample = tex2D(_BumpMap, BumpUVs.xy * _FarBumpSampleParams.x + _Time.x * _FinalBumpSpeed01.xy * _FarBumpSampleParams.x);
fixed4 normalSample = tex2D(_BumpMap, BumpUVs.xy + (farSample.ag * 2.0 - 1.0 ) * 0.05 );
normalSample = lerp( normalSample, farSample, saturate(surfaceEyeDepth * _FarBumpSampleParams.y) );
half3 refractNormal;
#if defined(UNITY_NO_DXT5nm)
refractNormal = (normalSample.rgb * 2 - 1) * _BumpScale.x;
#else
refractNormal = (normalSample.agg * 2 - 1) * _BumpScale.x;
#endif
// refracted 2nd detail normal sample
fixed4 normalSampleSmall = tex2D(_BumpMap, BumpUVs.zw + refractNormal.xy * 0.05 );
// 3rd detail normal sample
fixed4 normalSampleSmallest = tex2D(_BumpMap, BumpSmallAndFoamUVs);
o.Normal = UnpackAndBlendNormals (refractNormal, normalSampleSmall, normalSampleSmallest);
// -----------------------------------------------------------------------
// Normal Projectors
#if defined (USINGWATERPROJECTORS)
fixed4 projectedNormal = tex2D(_LuxWater_NormalOverlay, projectionUVs);
// Using regular ARGB rt
// fixed3 pNormal = projectedNormal.rgb * 2 - 1;
// Using ARGBHalf and additibve blending
fixed3 pNormal = projectedNormal.rgb;
// pNormal.xy *= -1; // proper tangent space - moved to normal projector shader
pNormal = lerp( half3(0,0,1), pNormal, projectedNormal.a
#if defined(_GERSTNERDISPLACEMENT)
* vignette
#endif
);
//o.ProjectedNormal = half4( pow(projectedNormal.rgb, 1.0 / 2.2) * 2 - 1, projectedNormal.a);
o.Normal = normalize(half3(o.Normal.xy + pNormal.xy, o.Normal.z*pNormal.z));
#endif
// -----------------------------------------------------------------------
// Handle Backface Rendering
// Metal has inversed facingSign which is not handled by Unity?
#if defined(SHADER_API_METAL)
float fsign = (_Culling == 0) ? -1 : 1;
o.FacingSign = fsign * IN.facingSign;
#else
o.FacingSign = IN.facingSign;
#endif
o.Normal *= o.FacingSign;
float3 worldNormal = WorldNormalVector(IN, o.Normal);
half3 wNormal = WorldNormalVector(IN, float3(0, 0, o.FacingSign));
float3 worldViewDir = normalize (IN.worldPos - _WorldSpaceCameraPos.xyz);
// -----------------------------------------------------------------------
// Edgeblendfactor - in view space
// This does not work on metal if we are using deferred rendering and enable ZWrite... - > force DepthNormalTexture?
#if defined(SHADER_API_METAL) && defined(LUXWATERMETALDEFERRED)
half origDepth = tex2Dproj(_Lux_GrabbedDepth, UNITY_PROJ_COORD(IN.grabUV)).r;
#else
half origDepth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.grabUV));
#endif
float sceneDepth = LinearEyeDepth(origDepth);
float edgeBlendFactor = saturate (_InvFade * (sceneDepth - surfaceEyeDepth));
float origEdgeBlendFactor = edgeBlendFactor;
// -----------------------------------------------------------------------
// Refraction - calculate distorted grab UVs
// Calculate fade factor for refraction according to depth
float perspectiveFadeFactor = IN.grabUV.z; // Works on metal and dx11 but not opengl
#if defined(UNITY_REVERSED_Z)
perspectiveFadeFactor = 1.0 - perspectiveFadeFactor;
#else
#if defined (SHADER_API_GLCORE) || defined (SHADER_API_D3D9)
perspectiveFadeFactor = 1.0 - perspectiveFadeFactor * _ProjectionParams.w;
#endif
#endif
float2 offsetFactor = _GrabTexture_TexelSize.xy * _Refraction * perspectiveFadeFactor * edgeBlendFactor;
float2 offset = worldNormal.xz * offsetFactor;
float4 distortedGrabUVs = IN.grabUV;
distortedGrabUVs.xy += offset;
// Snap distortedGrabUVs to pixels as otherwise the depth texture lookup will return
// a false depth which leads to a 1 pixel error (caused by fog and absorption) at high depth and color discontinuities (e.g. ship above ground).
float2 snappedDistortedGrabUVs = distortedGrabUVs.xy / distortedGrabUVs.w;
#if defined(GEOM_TYPE_BRANCH)
// Casting to int and float actually looks better than using round
// snappedDistortedGrabUVs = (float2)((int2)(snappedDistortedGrabUVs * _GrabTexture_TexelSize.zw + float2(1, 1))) - float2(0.5, 0.5);
// snappedDistortedGrabUVs *= _GrabTexture_TexelSize.xy;
// As proposed by bgolus:
snappedDistortedGrabUVs = (floor(snappedDistortedGrabUVs * _GrabTexture_TexelSize.zw) + 0.5) / _GrabTexture_TexelSize.zw;
#endif
// -----------------------------------------------------------------------
// Do not grab pixels from foreground
//float refractedRawDepth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(distortedGrabUVs));
#if defined(SHADER_API_METAL) && defined(LUXWATERMETALDEFERRED)
float refractedRawDepth = tex2Dlod(_Lux_GrabbedDepth, float4(snappedDistortedGrabUVs, 0, 0) ).r;
#else
float refractedRawDepth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(snappedDistortedGrabUVs, 0, 0));
#endif
float refractedSceneEyeDepth = LinearEyeDepth(refractedRawDepth);
if ( refractedSceneEyeDepth < surfaceEyeDepth ) {
distortedGrabUVs = IN.grabUV;
refractedRawDepth = origDepth;
snappedDistortedGrabUVs = IN.grabUV/IN.grabUV.w;
}
// Get final scene 01 and eye depth
refractedSceneEyeDepth = LinearEyeDepth(refractedRawDepth);
float refractedScene01Depth = Linear01Depth (refractedRawDepth);
float viewDepth = refractedSceneEyeDepth - surfaceEyeDepth;
// Adjust edgeBlendFactor according to the final refracted depth sample
edgeBlendFactor = saturate (_InvFade * viewDepth );
o.Refraction.a = 0; // no fog breaks on dx11, so it is added at the bottom
o.Absorption = 1; // no absorption
o.Caustics = 0;
// -----------------------------------------------------------------------
// Fog and Absorption
// Reconstruct world position of refracted pixel
float3 ray = IN.ViewRay_WaterYpos.xyz;
ray = ray * (_ProjectionParams.z / ray.z);
// This is only an estimation as the view vector is not correct
float4 vpos = float4(ray * refractedScene01Depth,1);
float3 wpos = mul (unity_CameraToWorld, vpos).xyz;
#if defined(USINGWATERVOLUME)
#define waterYPos _WaterSurfaceYPos
#else
#define waterYPos IN.ViewRay_WaterYpos.w
#endif
// for foam / caustics in forward
float4 vposUnrefracted = float4(ray * Linear01Depth(origDepth) ,1);
float3 wposUnrefracted = mul (unity_CameraToWorld, vposUnrefracted).xyz;
// Calculate Depth Attenuation based on world position and water y
float depthAtten = saturate( (waterYPos - wpos.y - _DepthAtten.x) / (_DepthAtten.y) );
depthAtten = saturate( 1.0 - exp( -depthAtten * 8.0 ) ) * saturate(_DepthAtten.z);
// Backside rendering
if (o.FacingSign < 0.0f) {
viewDepth = surfaceEyeDepth; //(viewDepth < surfaceEyeDepth) ? surfaceEyeDepth : viewDepth ;
}
// Calculate Attenuation along viewDirection
float viewAtten = saturate( 1.0 - exp( -viewDepth * _Density) );
// Store final fog density
o.Refraction.a = max(depthAtten, viewAtten);
// Absorption
float3 ColorAbsortion = float3(0.45f, 0.029f, 0.018f);
// Calculate Depth Attenuation
float depthBelowSurface = saturate( (waterYPos - wpos.y) / _AbsorptionMaxHeight);
depthBelowSurface = exp2(-depthBelowSurface * depthBelowSurface * _AbsorptionHeight);
// Calculate Attenuation along viewDirection
float d = exp( -viewDepth * _AbsorptionDepth );
// Combine and apply strength
d = lerp (1, saturate( d * depthBelowSurface), _AbsorptionStrength );
// Cancel absorption by fog
d = saturate(d + o.Refraction.a * _FogAbsorptionCancellation);
// Add color absorption
ColorAbsortion = lerp( d, -ColorAbsortion, _AbsorptionColorStrength * (1.0 - d));
o.Absorption = saturate(ColorAbsortion);
// -----------------------------------------------------------------------
// Front face rendering only
#if defined(SHADER_D3D11) || defined(SHADER_XBOXONE) || defined(SHADER_VULKAN) || defined(SHADER_API_GLCORE) || defined(SHADER_API_METAL)
UNITY_BRANCH
if (o.FacingSign > 0.0f) {
#endif
// -----------------------------------------------------------------------
// Caustics
#if defined(GEOM_TYPE_FROND)
float CausticsTime = _Time.x * _CausticsSpeed;
#if defined(GEOM_TYPE_LEAF)
half3 gNormal = tex2Dproj(_CameraGBufferTexture2, UNITY_PROJ_COORD(distortedGrabUVs)).rgb;
gNormal = gNormal * 2 - 1;
#else
half3 gNormal = normalize(cross(ddx(wposUnrefracted), ddy(wposUnrefracted))); // this produces gaps
//half3 gNormal = normalize(cross(ddx(wpos), ddy(wpos))); // This of course would be correct but shows up crazy discontinueties.
gNormal.y = -gNormal.y;
#endif
float2 cTexUV = wpos.xz * _CausticsTiling + offset;
float2 mainDir = _FinalBumpSpeed01.xy;
// Make caustics distort themselves by adding gb
fixed4 causticsSample = tex2D(_CausticTex, cTexUV + CausticsTime.xx * mainDir);
causticsSample += tex2D(_CausticTex, cTexUV * 0.78 + float2(-CausticsTime, -CausticsTime * 0.87) * mainDir + causticsSample.gb * _CausticsSelfDistortion );
causticsSample += tex2D(_CausticTex, cTexUV * 1.13 + float2(CausticsTime, 0.36) * mainDir - causticsSample.gb * _CausticsSelfDistortion );
//causticsSample = tex2D(_CausticTex, cTexUV + CausticsTime.xx * mainDir);
//fixed4 causticsSample1 = tex2D(_CausticTex, cTexUV * 0.78 + float2(-CausticsTime, -CausticsTime * 0.87) * mainDir + causticsSample.gb*0.2 );
//causticsSample = tex2D(_CausticTex, cTexUV + CausticsTime.xx * mainDir + float2(causticsSample.g, causticsSample1.b) * 0.1);
o.Caustics = causticsSample.r * saturate( (gNormal.y - 0.125) * 2);
o.Caustics *= _CausticsScale * edgeBlendFactor * edgeBlendFactor;
#endif
#if defined(SHADER_D3D11) || defined(SHADER_XBOXONE) || defined(SHADER_VULKAN) || defined(SHADER_API_GLCORE) || defined(SHADER_API_METAL)
}
#endif
// End of front face rendering only
// -----------------------------------------------------------------------
#if defined (UNITY_PASS_FORWARDBASE)
//o.Refraction.rgb = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(distortedGrabUVs) ).rgb;
o.Refraction.rgb = tex2Dlod(_GrabTexture, float4(snappedDistortedGrabUVs,0,0) ).rgb;
#else
o.Refraction.rgb = 0;
#endif
// -----------------------------------------------------------------------
// Simple subsurface scattering approximation
o.Translucency = 1;
//o.TranslucencyColor = _TranslucencyColor;
//o.ScatteringPower = _ScatteringPower;
// -----------------------------------------------------------------------
// Foam
#if defined(GEOM_TYPE_BRANCH_DETAIL)
half FoamSoftIntersectionFactor = .75;
float height = _FoamParallax * worldNormal.z;
// Compute parallax offset based on texture mapping
#if defined(EFFECT_BUMP)
float2 parallaxOffset = normalize(IN.viewDir.xy) * height;
#else
float2 parallaxOffset = worldViewDir.xz * height;
#endif
// float2 foamUVS = IN.worldPos.xz * _FoamTiling + _Time.xx * _FinalBumpSpeed01.xy * _FoamSpeed + worldNormal.xz*0.05 + parallaxOffset;
// We want the distortion from the Gerstner waves, so we have to use IN.BumpUVs
float2 foamUVS = IN.BumpUVs.xy * _FoamTiling + _Time.xx * _FoamSpeed * _FinalBumpSpeed01.xy + parallaxOffset;
half4 rawFoamSample = tex2D(_MainTex, foamUVS );
half FoamSample = 1; //(rawFoamSample.a * _FoamScale);
half FoamThreshold = o.Normal.z * 2 - 1;
// SceneDepth looks totally boring...
//half FoamSoftIntersection = saturate( _FoamSoftIntersectionFactor * (min(sceneDepth,refractedSceneEyeDepth) - surfaceEyeDepth ) );
half FoamSoftIntersection = saturate( _FoamSoftIntersectionFactor * (refractedSceneEyeDepth - surfaceEyeDepth ) );
// This introduces ghosting:
// FoamSoftIntersection = min(FoamSoftIntersection, saturate( _FoamSoftIntersectionFactor * (waterYPos - wposUnrefracted.y) ) );
// This does not really help:
// FoamSoftIntersection = min(FoamSoftIntersection, saturate( _FoamSoftIntersectionFactor * (waterYPos - wpos.y) ) );
// Get shoreline foam mask
float shorelineFoam = saturate(-FoamSoftIntersection * (1 + FoamThreshold.x) + 1 );
shorelineFoam = shorelineFoam * saturate(FoamSoftIntersection - FoamSoftIntersection * FoamSoftIntersection );
FoamSample *= shorelineFoam;
// Get foam caps
half underWaterFoam = 0;
#if defined(_GERSTNERDISPLACEMENT)
float foamCaps = IN.color.a;
foamCaps = saturate(foamCaps * _FoamCaps);
foamCaps *= foamCaps;
FoamSample += foamCaps;
half4 underwaterFoamSample = tex2D(_MainTex, foamUVS * 0.637 );
underWaterFoam = smoothstep(0.0, 0.75, foamCaps * 1.5 * underwaterFoamSample.a);
#endif
// Mask foam by the water's normals
FoamSample *= saturate(0.6 + (o.Normal.x * o.Normal.z) * 2.0);
FoamSample = saturate(FoamSample * _FoamScale);
FoamSample = FoamSample * smoothstep( 0.8 - rawFoamSample.a, 1.6 - rawFoamSample.a, FoamSample) * _FoamScale;
// Add Foam Projectors
#if defined (USINGWATERPROJECTORS)
fixed4 projectedFoam = tex2D(_LuxWater_FoamOverlay, projectionUVs);
// This way we get "regular" foam
FoamSample = saturate(FoamSample + projectedFoam.r
#if defined(_GERSTNERDISPLACEMENT)
* vignette
#endif
* smoothstep( 0.8 - rawFoamSample.a, 1.6 - rawFoamSample.a, projectedFoam.r));
#endif
o.Foam.a = saturate(FoamSample * _FoamColor.a);
o.Foam.rgb = _FoamColor.rgb;
half3 FoamNormal = UnpackScaleNormal(rawFoamSample.rgbr, o.Foam.a * _FoamNormalScale);
FoamNormal *= o.FacingSign;
// Add simple Foam Projectors
#if defined (USINGWATERPROJECTORS)
//o.Foam.rgb = lerp(o.Foam.rgb, half3(1,0,0), saturate(projectedFoam.g + (1 - o.Foam.a ) * 64 * projectedFoam.g ) );
o.Foam.a = saturate(o.Foam.a + projectedFoam.g
#if defined(_GERSTNERDISPLACEMENT)
* vignette
#endif
);
#endif
// Tweak all other outputs
o.Translucency *= 1.0 - o.Foam.a;
o.Normal = lerp(o.Normal, FoamNormal, o.Foam.a);
o.Smoothness = lerp(o.Smoothness, 0.1, o.Foam.a);
o.ReflectionSmoothness = lerp(o.ReflectionSmoothness, 0.1, o.Foam.a);
o.Caustics *= (1.0 - o.Foam.a);
// Add underwater foam to foam mask
#if defined(_GERSTNERDISPLACEMENT)
o.Foam.a = saturate(o.Foam.a + underWaterFoam);
#endif
#endif
// -----------------------------------------------------------------------
// Reflections
// Planar reflections
#if defined (GEOM_TYPE_MESH)
#if defined (UNITY_PASS_FORWARDBASE)
#if defined(_GERSTNERDISPLACEMENT)
// When Gerstner Waves are enabled reflOffeset is calculated using tangent space normal (wrong of course) + geometric worldnormal, so we can adjust both independently.
//float2 reflOffset = (o.Normal.xy * _ReflectionBumpScale + wNormal.xz * o.FacingSign * _ReflectionGeoScale) * offsetFactor;
float2 reflOffset = WorldNormalVector(IN, lerp( half3(0,0,1 * o.FacingSign), o.Normal, _ReflectionBumpScale)).xz * offsetFactor;
//reflOffset.y -= IN.color.a * _GerstnerVerticalIntensity * perspectiveFadeFactor; // perspectiveFadeFactor does not do much
float2 refluv = (IN.grabUV.xy / IN.grabUV.w) + reflOffset;
#else
// When displacement is disabled we take the "regular" worldnormal.
float2 reflOffset = WorldNormalVector(IN, lerp( half3(0,0,1 * o.FacingSign), o.Normal, _ReflectionBumpScale)).xz * offsetFactor;
float2 refluv = (IN.grabUV.xy / IN.grabUV.w) + reflOffset;
#endif
o.Reflections = tex2D(_LuxWater_ReflectionTex, refluv.xy);
o.ReflectionNormal = 0;
#else
o.Reflections = 0;
#endif
#else
o.ReflectionNormal = WorldNormalVector( IN, lerp( half3(0,0,1 * o.FacingSign), o.Normal, _ReflectionBumpScale) );
// #if defined(_GERSTNERDISPLACEMENT)
// o.ReflectionNormal = lerp(half3(0,1,0), o.ReflectionNormal, _ReflectionGeoScale);
// #endif
#endif
///
o.Albedo = c.rgb;
// In order to minimize artifacts cause by unity's fog and refracted background with a completely different depth we have to use 2 blend values.
// x is used to blend water with scene.
// y is used to blend refracted to fully lit water surface.
// this introduces minimal ghosting but looks best so far.
o.Alpha.x = origEdgeBlendFactor;
o.Alpha.y = edgeBlendFactor;
// Needed by custom fog
o.ClipSpaceDepth = UNITY_Z_0_FAR_FROM_CLIPSPACE(IN.grabUV.z);
// o.Emission += IN.color.a * 0.0001;
// make worlPos get compiled out
// o.worldNormalFace = WorldNormalVector(IN, half3(0,0,1));
// o.Emission += /*(1 - edgeBlendFactor) +*/ (IN.worldPos.x + o.worldNormalFace.y + edgeBlendFactor) * 0.0000001 ;
// o.Emission += /*(1 - edgeBlendFactor) +*/ frac(IN.worldPos.x + o.worldNormalFace.y) * 0.0001 ;
}
ENDCG
// ////////////////////////
}
CustomEditor "LuxWaterMaterialEditor"
}