So a big part of this game im making is going to be the oceans and ocean fog. I made a shader with fog and everything already, but I can not find any answers online on finding exact world space coordinates of each pixel in the fragment shader. Its a very simple concept. Im going to get the pixel coordinate, and see if its below or above the water surface transform. If its below, I execute my ocean fog, if its above the water surface, i dont execute the fog. I have already gotten an effect with the shader below thats very close to what i need, but it works awkwardly. Im going for that seamless transition of the camera above and below the water surface (like in subnautica or sea of thieves). I am using the universal render pipeline if that matters at all. The shader is being applied through a blit custom render feature which works great.
Any help is really appreciated.
Here is my image effect script:
Shader "Custom/ScreenFog"
{
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
_DepthLevel("Depth Level", Range(1, 3)) = 2
_FogColor("FogColor", Color) = (1, 0, 0, 1)
_Cutoff("Cutoff", Float) = 0.5
_Falloff("Falloff", Float) = 0.5
//fake bool, 1 true, 0 false;
_isUnderwater("is Underwater", Float) = 1
}
SubShader
{
Pass
{
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D_float _CameraDepthTexture;
uniform fixed _DepthLevel;
uniform half4 _MainTex_TexelSize;
struct uinput
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
//cbuffer cbmat : register(b0)
//{
// float4x4 tW; //World transform
// float4x4 tWVP;//World * View * Projection
//};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 wpos : TEXCOORD1;
};
sampler2D _MainTex;
float _Cutoff;
float _Falloff;
fixed4 _FogColor;
float _isUnderwater;
float4 _MainTex_ST;
v2f vert(uinput v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
float3 viewVector = mul(unity_CameraInvProjection, float4(v.uv.xy * 5 - 1, 0, 1));
o.wpos = mul(unity_CameraToWorld, float4(viewVector, 0));
return o;
}
fixed4 frag(v2f o) : SV_TARGET
{
if (o.wpos.y > 0) {
_isUnderwater = 1;
}
else {
_isUnderwater = 0;
}
if (_isUnderwater == 1) {
float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, o.uv));
depth = pow(Linear01Depth(depth), _DepthLevel * (_DepthLevel * _DepthLevel / 2));
depth = smoothstep(_Cutoff - _Falloff, _Cutoff, depth);
fixed4 fogOnly = _FogColor;
fixed4 col = tex2D(_MainTex, o.uv);
col = lerp(col, fogOnly, depth);
return 1 - col;
}
else if (_isUnderwater == 0) {
float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, o.uv));
depth = pow(Linear01Depth(depth), _DepthLevel * (_DepthLevel * _DepthLevel / 2));
depth = smoothstep(_Cutoff - _Falloff, _Cutoff, depth);
fixed4 fogOnly = _FogColor;
fixed4 col = tex2D(_MainTex, o.uv);
col = lerp(col, fogOnly, depth);
return col;
}
else {
return _FogColor;
}
}
ENDCG
}
}
}