So I have been following this tutorial on https://www.udemy.com/course/unity-shaders/
Today I have been trying to do the raymarching spherical fog on a custom procedural mesh I have built previously, but I seem to be running into some problems with my implementation.
The first bug seems to be in the ordering or layering of the mesh with the raymarching shader. What seems to be happening is that for all the pixels below camera level, it is grabbing from the far, non-culled plane. Camera angle seems does not impact this particular effect.
The second one occurs when the angle between the object and the camera is high but still within viewing range. In the attached pictures, the orange/salmon color is supposed to be well below water line, but with that angle(view angle is 60 degrees so only between 20 and 30 degrees), and seemingly along the normals that point towards the camera, the water disappears.
I would not be surprised if these two bugs are linked. The color coming from the texture sampler is correct as I have a surface shader that uses the uv stored in the mesh to sample the ocean texture, and I have tried a simpler one that just tried to make the ocean layer transparent through the alpha channel but it was not the effect I was going for. I have also downloaded and copied in Sebastian Lague’s ocean shader in the github linked through here
and it produces the same effect. So with all of those factors I believe it is probably a pretty simple error in my code that I have missed. I have written that shader twice now over the last 5 hours so I feel it’s probably good to try and get some more eyes on the problem. Let me know what y’all think
Shader "IE/OceanShader"
{
Properties
{
_OceanTex ("Texture", 2D) = "white" {}
_DefaultColor("Default Color", Color) = (0.5, 0, 1, 1)
_SeaRadius("Sea Radius", float) = 0.5
_FogCenter("Fog Center/Radius", Vector) = (0, 0, 0, 0.5)
_InnerRatio("Inner Ratio", Range(0.0, 1.0)) = 0.5
_Density("Density", Range(0.0, 1.0)) = 0.5
_StepCount("Step Count", Range(0, 100)) = 5
}
SubShader
{
Tags { "Queue"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Cull Off Lighting Off ZWrite Off
ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _OceanTex;
float4 _OceanTex_ST;
fixed4 _DefaultColor;
float _SeaRadius;
float4 _FogCenter;
float _InnerRatio;
float _Density;
int _StepCount;
sampler2D _CameraDepthTexture;
float CalculateFogIntensity(
float3 sphereCenter,
float sphereRadius,
float innerRatio,
float density,
float3 cameraPosition,
float3 viewDirection,
float maxDistance
)
{
// Calculate Ray Sphere.
float3 localCam = cameraPosition - sphereCenter;
float a = dot(viewDirection, viewDirection);
float b = 2 * dot(viewDirection, localCam);
float c = dot(localCam, localCam) - sphereRadius * sphereRadius;
float d = b * b - 4 * a * c;
if(d <= 0.0)
return 0;
float dSqrt = sqrt(d);
float nearDist = max((-b - dSqrt) / (2 * a), 0);
float farDist = max((-b + dSqrt) / (2 * a), 0);
float backDepth = min(maxDistance, farDist);
float sample = nearDist;
float stepDistance = (backDepth - nearDist) / _StepCount;
float stepContribution = density;
float centerValue = 1 / (1 - innerRatio);
float clarity = 1;
for (int seg = 0; seg < _StepCount; seg++)
{
float3 locPos = localCam + viewDirection * sample;
float val = saturate(centerValue * (1 - length(locPos)/sphereRadius));
float fogAmount = saturate(val * stepContribution);
clarity *= (1 - fogAmount);
sample += stepDistance;
}
return 1 - clarity;
}
struct v2f
{
float3 viewDir : TEXCOORD0;
float4 pos : SV_POSITION;
float4 projPos : TEXCOORD1;
float2 locTex : TEXCOORD2;
};
v2f vert (appdata_base v)
{
v2f o;
float4 wPos = mul(unity_ObjectToWorld, v.vertex);
o.pos = UnityObjectToClipPos(v.vertex);
o.viewDir = wPos.xyz - _WorldSpaceCameraPos;
o.projPos = ComputeScreenPos(o.pos);
o.locTex = v.texcoord;
float inFrontOf = (o.pos.z/_SeaRadius) > 0;
o.pos.z * inFrontOf;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
half4 color = half4(0.5, 0, 1, 1);
float depth = LinearEyeDepth(UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))));
float3 viewDir = normalize(i.viewDir);
float fog = CalculateFogIntensity(_FogCenter.xyz, _SeaRadius, _InnerRatio, _Density, _WorldSpaceCameraPos, viewDir, depth);
color.rgb = tex2D(_OceanTex, i.locTex);
//color.rgb = _DefaultColor;
color.a = fog;
return color;
}
ENDCG
}
}
}