From 8d2c11025c372e8b4ab4e02daf9f7495b162d3f8 Mon Sep 17 00:00:00 2001 From: yum Date: Mon, 27 Jan 2025 16:43:09 -0800 Subject: Restore spherical boundary to fog gimmick --- Editor/tooner.cs | 8 +++++++- feature_macros.cginc | 3 +++ fog.cginc | 45 ++++++++++++++++++++++++++++++++++++++------- globals.cginc | 1 + tooner.shader | 1 + 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/Editor/tooner.cs b/Editor/tooner.cs index e743dc2..9edd3a7 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -2646,6 +2646,7 @@ public class ToonerGUI : ShaderGUI { enum GimmickFog00BoundaryType { Cylinder = 0, Plane = 1, + Sphere = 2, } void DoGimmickFog0() { @@ -2676,7 +2677,7 @@ public class ToonerGUI : ShaderGUI { EditorGUI.EndChangeCheck(); bc.floatValue = (int) boundary_type; - if (boundary_type == GimmickFog00BoundaryType.Cylinder) { + if (boundary_type == GimmickFog00BoundaryType.Cylinder || boundary_type == GimmickFog00BoundaryType.Sphere) { bc = FindProperty("_Gimmick_Fog_00_Radius"); FloatProperty(bc, "Radius"); } else if (boundary_type == GimmickFog00BoundaryType.Plane) { @@ -2685,9 +2686,14 @@ public class ToonerGUI : ShaderGUI { bc = FindProperty("_Gimmick_Fog_00_Plane_Center"); VectorProperty(bc, "Plane center"); } + SetKeyword("_GIMMICK_FOG_00_BOUNDARY_CYLINDER", boundary_type == GimmickFog00BoundaryType.Cylinder); + SetKeyword("_GIMMICK_FOG_00_BOUNDARY_SPHERE", boundary_type == GimmickFog00BoundaryType.Sphere); + SetKeyword("_GIMMICK_FOG_00_BOUNDARY_PLANE", boundary_type == GimmickFog00BoundaryType.Plane); bc = FindProperty("_Gimmick_Fog_00_Step_Size_Factor"); FloatProperty(bc, "Step size multiplier"); + bc = FindProperty("_Gimmick_Fog_00_Initial_Offset"); + FloatProperty(bc, "Initial offset"); bc = FindProperty("_Gimmick_Fog_00_Max_Ray"); FloatProperty(bc, "Max ray length (m)"); bc = FindProperty("_Gimmick_Fog_00_Noise_Scale"); diff --git a/feature_macros.cginc b/feature_macros.cginc index c3379a9..f134e19 100644 --- a/feature_macros.cginc +++ b/feature_macros.cginc @@ -267,6 +267,9 @@ #pragma shader_feature_local _ SSR_ENABLED #pragma shader_feature_local _ SSR_MASK #pragma shader_feature_local _ _GIMMICK_FOG_00 +#pragma shader_feature_local _ _GIMMICK_FOG_00_BOUNDARY_CYLINDER +#pragma shader_feature_local _ _GIMMICK_FOG_00_BOUNDARY_PLANE +#pragma shader_feature_local _ _GIMMICK_FOG_00_BOUNDARY_SPHERE #pragma shader_feature_local _ _GIMMICK_FOG_00_NOISE_2D #pragma shader_feature_local _ _GIMMICK_FOG_00_EMITTER_TEXTURE #pragma shader_feature_local _ _GIMMICK_FOG_00_EMITTER_VARIABLE_DENSITY diff --git a/fog.cginc b/fog.cginc index 8f9c0e3..e47a066 100644 --- a/fog.cginc +++ b/fog.cginc @@ -82,9 +82,13 @@ float map(float3 p, out float3 normal) { #define RADIUS_TRANS_WIDTH_RCP (1.0 / RADIUS_TRANS_WIDTH) // Try to create a smooth transition without doing any length() or other // transcendental ops. - float radius2 = (_Gimmick_Fog_00_Boundary_Type == 0) ? - clamp(_Gimmick_Fog_00_Radius * _Gimmick_Fog_00_Radius - dot(p.xz, p.xz), 0, RADIUS_TRANS_WIDTH) * RADIUS_TRANS_WIDTH_RCP : - 0; +#if 1 && defined(_GIMMICK_FOG_00_BOUNDARY_CYLINDER) + float radius2 = clamp(_Gimmick_Fog_00_Radius * _Gimmick_Fog_00_Radius - dot(p.xz, p.xz), 0, RADIUS_TRANS_WIDTH) * RADIUS_TRANS_WIDTH_RCP; +#elif 1 && defined(_GIMMICK_FOG_00_BOUNDARY_SPHERE) + float radius2 = clamp(_Gimmick_Fog_00_Radius * _Gimmick_Fog_00_Radius - dot(p, p), 0, RADIUS_TRANS_WIDTH) * RADIUS_TRANS_WIDTH_RCP; +#else + float radius2 = 1; +#endif float3 pp = p * _Gimmick_Fog_00_Noise_Scale * FOG_PERLIN_NOISE_SCALE; normal = normalize(perlin_noise_3d_tex(pp+t) * 2 - 1); @@ -262,7 +266,8 @@ Fog00PBR __getFog00(v2f i, ToonerData tdata, const float3 rd = normalize(obj_pos - cam_pos); float3 ro = cam_pos; - if (_Gimmick_Fog_00_Boundary_Type == 0) { +#if defined(_GIMMICK_FOG_00_BOUNDARY_CYLINDER) + { // Raytrace distance to cylinder bool no_intersection = false; float distance_to_cylinder = 1E6; @@ -281,7 +286,9 @@ Fog00PBR __getFog00(v2f i, ToonerData tdata, } } clip(no_intersection ? -1 : 1); - } else if (_Gimmick_Fog_00_Boundary_Type == 1) { + } +#elif defined(_GIMMICK_FOG_00_BOUNDARY_PLANE) + { // Raytrace distance to plane bool no_intersection = false; float distance_to_plane = 1E6; @@ -306,6 +313,28 @@ Fog00PBR __getFog00(v2f i, ToonerData tdata, } clip(no_intersection ? -1 : 1); } +#elif defined(_GIMMICK_FOG_00_BOUNDARY_SPHERE) + { + bool no_intersection = false; + float distance_to_sphere = 1E6; + { + float3 l = ro; + float a = 1; + float b = 2 * dot(rd, l); + float c = dot(l, l) - _Gimmick_Fog_00_Radius * _Gimmick_Fog_00_Radius; + float t0, t1; + if (solveQuadratic(a, b, c, t0, t1)) { + no_intersection = (t0 < 0) * (t1 < 0); + const bool inside_sphere = (t0 < 0) * (t1 > 0); + if (!inside_sphere) { + distance_to_sphere = no_intersection ? distance_to_sphere : min(max(t0, 0), max(t1, 0)); + ro += distance_to_sphere * rd; + } + } + } + clip(no_intersection ? -1 : 1); + } +#endif float density_ss_term = 1 / _Gimmick_Fog_00_Density; //density_ss_term = dclamp(density_ss_term, 0.33, 3.00, 5); @@ -324,7 +353,7 @@ Fog00PBR __getFog00(v2f i, ToonerData tdata, const float dither_seed = rand2(float2(screen_uv_round.x, screen_uv_round.y)*.001); #endif float dither = dither_seed * step_size * _Gimmick_Fog_00_Ray_Origin_Randomization; - ro += rd * (0.001 + dither); + ro += rd * (_Gimmick_Fog_00_Initial_Offset + dither); const float depth_hit_l = length(obj_pos_depth_hit - ro); @@ -425,9 +454,11 @@ Fog00PBR __getFog00(v2f i, ToonerData tdata, if (acc.a > _Gimmick_Fog_00_Alpha_Cutoff) { break; } - if (_Gimmick_Fog_00_Boundary_Type == 0 && dot(p.xz, p.xz) > _Gimmick_Fog_00_Radius * _Gimmick_Fog_00_Radius) { +#if defined(_GIMMICK_FOG_00_BOUNDARY_SPHERE) || defined(_GIMMICK_FOG_00_BOUNDARY_CYLINDER) + if (dot(p.xz, p.xz) > _Gimmick_Fog_00_Radius * _Gimmick_Fog_00_Radius) { break; } +#endif #endif } if (acc.a > _Gimmick_Fog_00_Alpha_Cutoff || ii == FOG_MAX_LOOP) { diff --git a/globals.cginc b/globals.cginc index 1e21712..0364107 100644 --- a/globals.cginc +++ b/globals.cginc @@ -978,6 +978,7 @@ float _Gimmick_Fog_00_Lod_Half_Life; float _Gimmick_Fog_00_Max_Brightness; float _Gimmick_Fog_00_LTCGI_Brightness; float _Gimmick_Fog_00_Overlay_Mode; +float _Gimmick_Fog_00_Initial_Offset; texture3D _Gimmick_Fog_00_Noise; #if defined(_GIMMICK_FOG_00_NOISE_2D) texture2D _Gimmick_Fog_00_Noise_2D; diff --git a/tooner.shader b/tooner.shader index 34123fa..a62e242 100644 --- a/tooner.shader +++ b/tooner.shader @@ -1051,6 +1051,7 @@ Shader "yum_food/tooner" _Gimmick_Fog_00_Emitter_Brightness_Diffuse("fog", Float) = 1 _Gimmick_Fog_00_Emitter_Brightness_Direct("fog", Float) = 1 _Gimmick_Fog_00_Emitter_Lod_Half_Life("fog", Float) = 5 + _Gimmick_Fog_00_Initial_Offset("Initial offset", Float) = 0.00001 _Gimmick_Fog_00_Emitter0_Location("fog", Vector) = (0, 0, 0, 0) _Gimmick_Fog_00_Emitter0_Normal("fog", Vector) = (-1, 0, 0, 0) -- cgit v1.2.3