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

// 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
}