H_SafeExperienceDrivingSystem/U3D_DrivingSystem/Assets/Plugin/DCG Shaders/Water Shader/Shaders/WaterFog.shader

176 lines
6.0 KiB
GLSL

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Hidden/DCG/Water Shader/Water Fog"
{
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _CameraDepthTexture;
#define PI 3.1416
float4 _FogColor, _SunLightColor, _BoxMin, _BoxMax, _LightColor, VolumeSize;
float _sunIntensity = 1.2,
sunRadius,
_FogDensity,
sunDistance = 100,
sunDistanceFactor = 500,
_Ray, gain=1,
threshold=0,
Exposure;
float3 LightTransform = float3(0, 0, 1);
float hit (float3 start, float3 dir, float3 M1, float3 M2, inout float hitMin, inout float hitMax)
{
float yMin, yMax, zMin, zMax;
float flag = 1.0;
if (dir.x > 0)
{
hitMin = (M1.x - start.x) / dir.x;
hitMax = (M2.x - start.x) / dir.x;
}
else
{
hitMin = (M2.x - start.x) / dir.x;
hitMax = (M1.x - start.x) / dir.x;
}
if (dir.y > 0)
{
yMin = (M1.y - start.y) / dir.y;
yMax = (M2.y - start.y) / dir.y;
}
else
{
yMin = (M2.y - start.y) / dir.y;
yMax = (M1.y - start.y) / dir.y;
}
if ((hitMin > yMax) || (yMin > hitMax)) flag = -1.0;
if (yMin > hitMin) hitMin = yMin;
if (yMax < hitMax) hitMax = yMax;
if (dir.z > 0)
{
zMin = (M1.z - start.z) / dir.z;
zMax = (M2.z - start.z) / dir.z;
}
else
{
zMin = (M2.z - start.z) / dir.z;
zMax = (M1.z - start.z) / dir.z;
}
if ((hitMin > zMax) || (zMin > hitMax)) flag = -1.0;
if (zMin > hitMin) hitMin = zMin;
if (zMax < hitMax) hitMax = zMax;
return (flag > 0.0);
}
float He(float3 E, float3 L, float mieDirectionalG)
{
float theta=saturate(dot(E, L));
return (1.0 / (4.0 * PI)) * ((1.0 - mieDirectionalG * mieDirectionalG) / pow(1.0 - 2.0 * mieDirectionalG * theta + mieDirectionalG * mieDirectionalG, 1.5)) ;
}
struct v2f
{
float4 SampleCoordinates : SV_POSITION;
float3 Wpos : TEXCOORD0;
float4 ScreenUVs : TEXCOORD1;
float3 LocalPos : TEXCOORD2;
float3 ViewPos : TEXCOORD3;
float3 LocalEyePos : TEXCOORD4;
float3 LightLocalDir : TEXCOORD5;
};
half Threshold(float a, float Gain, float Contrast)
{
float Guy = a * Gain;
float thresh = Guy - Contrast;
return saturate(lerp(0.0f ,Guy , thresh ));
}
v2f vert (appdata_full i)
{
v2f o;
o.SampleCoordinates = UnityObjectToClipPos(i.vertex);
o.Wpos = mul((float4x4)unity_ObjectToWorld, float4(i.vertex.xyz, 1)).xyz;
o.ScreenUVs = ComputeScreenPos(o.SampleCoordinates);
o.ViewPos = mul((float4x4)UNITY_MATRIX_MV, float4(i.vertex.xyz, 1)).xyz;
o.LocalPos = i.vertex.xyz;
o.LocalEyePos = mul((float4x4)unity_WorldToObject, (float4(_WorldSpaceCameraPos, 1))).xyz;
o.LightLocalDir = mul((float4x4)unity_WorldToObject, (float4(LightTransform.xyz, 1))).xyz;
return o;
}
float4 frag (v2f i) : COLOR
{
float3 direction = normalize(i.LocalPos - i.LocalEyePos);
float hitMin, hitMax;
float Volume = hit(i.LocalEyePos, direction, _BoxMin.xyz, _BoxMax.xyz, hitMin, hitMax);
int Inside[3] = {0, 0, 0}, bOutside;
Inside[0] = step(0, abs(i.LocalEyePos.x) - _BoxMax.x);
Inside[1] = step(0, abs(i.LocalEyePos.y) - _BoxMax.y);
Inside[2] = step(0, abs(i.LocalEyePos.z) - _BoxMax.z);
bOutside = min(1,(float)(Inside[0] + Inside[1] + Inside[2]));
hitMin*=bOutside;
float2 ScreenUVs = i.ScreenUVs.xy/i.ScreenUVs.w;
float Depth = length(DECODE_EYEDEPTH(tex2D(_CameraDepthTexture, ScreenUVs).r )/normalize(i.ViewPos).z);
float lDepth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D (_CameraDepthTexture, ScreenUVs)));
float MinMax[2] = {max(hitMin, hitMax), min(hitMin, hitMax)};
float thickness = min(MinMax[0], Depth) - min(MinMax[1], Depth);
float Fog = thickness / _FogDensity;
Fog = 1.0 - exp2( -Fog );
Fog *= Volume;
float4 ReturnFog=0;
float3 Normalized_CameraWorldDir = normalize(i.Wpos - _WorldSpaceCameraPos);
float3 Normalized_CameraLocalDir = normalize(i.LocalPos - i.LocalEyePos);
float3 CameraLocalDir = (i.LocalPos - i.LocalEyePos);
half DistanceClamp = saturate( Depth / sunDistanceFactor - sunDistance);
#define STEPS 50
float inv_STEPS = 1.0f/(float)STEPS;
float4 Noise=0, ShadowColor=0;
float3 rayStart = i.LocalEyePos + Normalized_CameraLocalDir * hitMin;
float3 rayStop = i.LocalEyePos + Normalized_CameraLocalDir * hitMax;
float3 SampleDirection = rayStop - rayStart;
float3 step = normalize(SampleDirection) * _Ray;
float3 stepLocal = normalize(direction) * _Ray;
float Ray = distance(rayStop, rayStart);
half jitter = 1;
float3 SampleCoordinates = rayStart;
#ifdef _FOG_SUNLIGHT
float Inscattering = He(Normalized_CameraWorldDir, LightTransform, sunRadius);
Inscattering *= DistanceClamp * Fog;
ReturnFog = float4( _FogColor.rgb + _FogColor.rgb * _SunLightColor.rgb * _sunIntensity * Inscattering, _FogColor.a);
#else
ReturnFog = _FogColor;
#endif
ReturnFog.rgb *= Exposure;
ReturnFog.a *= (Fog * _FogColor.a);
return ReturnFog;
}
ENDCG
SubShader
{
Tags {
"Queue"="Overlay"
"IgnoreProjector"="True"
"RenderType"="Transparent "
}
Blend SrcAlpha OneMinusSrcAlpha
Cull Front
ZWrite Off
ZTest Always
Lighting Off
Pass{Fog {Mode Off }
CGPROGRAM
#pragma multi_compile _ _FOG_SUNLIGHT
#pragma glsl
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
ENDCG
}
}
}