You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
3.5 KiB
Plaintext
162 lines
3.5 KiB
Plaintext
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
|
|
|
|
|
|
|
Shader "Suimono2/SuimonoFog" {
|
|
Properties {
|
|
_MainTex ("Base (RGB)", 2D) = "black" {}
|
|
}
|
|
|
|
CGINCLUDE
|
|
|
|
#include "UnityCG.cginc"
|
|
|
|
uniform sampler2D _MainTex;
|
|
uniform sampler2D_float _CameraDepthTexture;
|
|
uniform float4 _HeightParams;
|
|
uniform float4 _DistanceParams;
|
|
|
|
float4 _SceneFogParams;
|
|
|
|
uniform float4 _MainTex_TexelSize;
|
|
uniform float4x4 _FrustumCornersWS;
|
|
uniform float4 _CameraWS;
|
|
|
|
half4 _FogColor,_FogColorHigh;
|
|
float _fogSkybox;
|
|
|
|
struct v2f {
|
|
float4 pos : SV_POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
float2 uv_depth : TEXCOORD1;
|
|
float4 interpolatedRay : TEXCOORD2;
|
|
};
|
|
|
|
v2f vert (appdata_img v)
|
|
{
|
|
v2f o;
|
|
half index = v.vertex.z;
|
|
v.vertex.z = 0.1;
|
|
o.pos = UnityObjectToClipPos(v.vertex);
|
|
o.uv = v.texcoord.xy;
|
|
o.uv_depth = v.texcoord.xy;
|
|
|
|
#if UNITY_UV_STARTS_AT_TOP
|
|
if (_MainTex_TexelSize.y < 0)
|
|
o.uv.y = 1-o.uv.y;
|
|
#endif
|
|
|
|
o.interpolatedRay = _FrustumCornersWS[(int)index];
|
|
o.interpolatedRay.w = index;
|
|
|
|
return o;
|
|
}
|
|
|
|
|
|
// Distance-based fog
|
|
float ComputeDistance (float3 camDir, float zdepth)
|
|
{
|
|
return length(camDir);
|
|
}
|
|
|
|
// Linear half-space fog, from https://www.terathon.com/lengyel/Lengyel-UnifiedFog.pdf
|
|
float ComputeHalfSpace (float3 wsDir)
|
|
{
|
|
float3 wpos = _CameraWS + wsDir;
|
|
float FH = _HeightParams.x;
|
|
float3 C = _CameraWS;
|
|
float3 V = wsDir;
|
|
float3 P = wpos;
|
|
float3 aV = _HeightParams.w * V;
|
|
float FdotC = _HeightParams.y;
|
|
float k = _HeightParams.z;
|
|
float FdotP = P.y-FH;
|
|
float FdotV = wsDir.y;
|
|
float c1 = k * (FdotP + FdotC);
|
|
float c2 = (1-2*k) * FdotP;
|
|
float g = min(c2, 0.0);
|
|
g = -length(aV) * (c1 - g * g / abs(FdotV+1.0e-5f));
|
|
return g;
|
|
}
|
|
|
|
half4 ComputeFog (v2f i, bool distance, bool height) : SV_Target
|
|
{
|
|
half4 sceneColor = tex2D(_MainTex, i.uv);
|
|
|
|
// Reconstruct world space position & direction
|
|
// towards this screen pixel.
|
|
float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth);
|
|
float dpth = Linear01Depth(rawDepth);
|
|
float4 wsDir = dpth * i.interpolatedRay;
|
|
float4 wsPos = _CameraWS + wsDir;
|
|
|
|
// Compute fog distance
|
|
float g = _DistanceParams.x;
|
|
//distance
|
|
g += ComputeDistance (wsDir, dpth);
|
|
//height
|
|
g += ComputeHalfSpace (wsDir);
|
|
|
|
|
|
//CALCULATE FOG
|
|
half usedpth = _DistanceParams.z + ComputeDistance(wsDir, dpth) + ComputeHalfSpace (wsDir);
|
|
half fogFac = saturate(max(0.0,usedpth) * _SceneFogParams.z + _SceneFogParams.w);
|
|
|
|
// Do not fog skybox
|
|
if (_fogSkybox == 1.0){
|
|
if (rawDepth >= 0.999999){
|
|
fogFac = 1.0;
|
|
}
|
|
}
|
|
|
|
_FogColor = lerp(_FogColor,_FogColorHigh,fogFac * _FogColorHigh.a);
|
|
|
|
// Lerp between fog color & original scene color
|
|
half4 fCol = lerp (lerp((half4)sceneColor, (half4)_FogColor* half4(0.4646,0.4646,0.4646,0.4646), _FogColor.a), (half4)sceneColor, fogFac);
|
|
|
|
//lerp color to only depth value
|
|
fCol.rgb = sceneColor.rgb;
|
|
fCol.a = lerp (lerp((half)0.0, (half)1.0, _FogColor.a), (half)0.0, fogFac);
|
|
|
|
return fCol;
|
|
}
|
|
|
|
ENDCG
|
|
|
|
SubShader
|
|
{
|
|
ZTest Always Cull Off ZWrite Off Fog { Mode Off }
|
|
|
|
// 0: distance + height
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, true); }
|
|
ENDCG
|
|
}
|
|
// 1: distance
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, false); }
|
|
ENDCG
|
|
}
|
|
// 2: height
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
half4 frag (v2f i) : SV_Target { return ComputeFog (i, false, true); }
|
|
ENDCG
|
|
}
|
|
}
|
|
|
|
Fallback off
|
|
|
|
}
|