From 4adbc6dfbf2409f34e11e001db2b434feeeb435f Mon Sep 17 00:00:00 2001 From: yum Date: Sun, 3 Nov 2024 15:35:40 -0800 Subject: Add interleaved gradient noise cutout mode Based on screen space uvs. --- Editor/tooner.cs | 4 +++- feature_macros.cginc | 1 + globals.cginc | 6 ++++++ pbr.cginc | 19 ++++--------------- tooner_lighting.cginc | 15 ++++++++++++++- tooner_outline_pass.cginc | 12 +++++++++++- 6 files changed, 39 insertions(+), 18 deletions(-) diff --git a/Editor/tooner.cs b/Editor/tooner.cs index f6f3da8..53ae1a8 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -2365,7 +2365,8 @@ public class ToonerGUI : ShaderGUI { enum CutoutMode { Cutoff, - Stochastic + Stochastic, + InterleavedGradientNoise, } // unity is made by fucking morons and they don't expose this so i'm @@ -2479,6 +2480,7 @@ public class ToonerGUI : ShaderGUI { EditorGUI.EndChangeCheck(); bc.floatValue = (float) cmode; SetKeyword("_RENDERING_CUTOUT_STOCHASTIC", cmode == CutoutMode.Stochastic); + SetKeyword("_RENDERING_CUTOUT_IGN", cmode == CutoutMode.InterleavedGradientNoise); if (cmode == CutoutMode.Cutoff) { bc = FindProperty("_Alpha_Cutoff"); diff --git a/feature_macros.cginc b/feature_macros.cginc index 1bcb217..7f68ef1 100644 --- a/feature_macros.cginc +++ b/feature_macros.cginc @@ -19,6 +19,7 @@ #pragma shader_feature_local _ _EMISSION1 #pragma shader_feature_local _ _RENDERING_CUTOUT #pragma shader_feature_local _ _RENDERING_CUTOUT_STOCHASTIC +#pragma shader_feature_local _ _RENDERING_CUTOUT_IGN #pragma shader_feature_local _ _RENDERING_FADE #pragma shader_feature_local _ _RENDERING_TRANSPARENT #pragma shader_feature_local _ _RENDERING_TRANSCLIPPING diff --git a/globals.cginc b/globals.cginc index 4b032c9..a62bb07 100644 --- a/globals.cginc +++ b/globals.cginc @@ -3,6 +3,12 @@ #ifndef __GLOBALS_INC #define __GLOBALS_INC +struct ToonerData +{ + float2 screen_uv; + uint2 screen_uv_round; +}; + UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); SamplerState point_repeat_s; diff --git a/pbr.cginc b/pbr.cginc index ea15096..68e26e9 100644 --- a/pbr.cginc +++ b/pbr.cginc @@ -194,7 +194,8 @@ float4 getLitColor( // hack while i figure out view-dependent flickering in outlines bool enable_direct, float3 diffuse_contrib, - v2f i) + v2f i, + ToonerData tdata) { float3 specular_tint; float one_minus_reflectivity; @@ -387,21 +388,9 @@ float4 getLitColor( indirect_light).xyz; #endif - // TODO optimize this and formalize with parameters + // TODO formalize with parameters // Break up color banding by adding some dithering to shaded color. - float screen_dither; - { - float2 screen_uv; - { - float3 full_vec_eye_to_geometry = i.worldPos - _WorldSpaceCameraPos; - float3 world_dir = normalize(i.worldPos - _WorldSpaceCameraPos); - float perspective_divide = 1.0 / i.pos.w; - float perspective_factor = length(full_vec_eye_to_geometry * perspective_divide); - screen_uv = i.screenPos.xy * perspective_divide; - } - uint2 screen_uv_round = floor(screen_uv * _ScreenParams.xy); - screen_dither = ign(screen_uv_round) * 0.00390625; - } + float screen_dither = ign(tdata.screen_uv_round) * .00390625; pbr += screen_dither; #if defined(_CLEARCOAT) diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc index 2952f29..c6fd02a 100644 --- a/tooner_lighting.cginc +++ b/tooner_lighting.cginc @@ -1363,6 +1363,16 @@ float4 pixellate_color(int2 px_res, float2 uv, float4 c) float4 effect(inout v2f i, out float depth) { + ToonerData tdata; + { + float3 full_vec_eye_to_geometry = i.worldPos - _WorldSpaceCameraPos; + float3 world_dir = normalize(i.worldPos - _WorldSpaceCameraPos); + float perspective_divide = 1.0 / i.pos.w; + float perspective_factor = length(full_vec_eye_to_geometry * perspective_divide); + tdata.screen_uv = i.screenPos.xy * perspective_divide; + tdata.screen_uv_round = floor(tdata.screen_uv * _ScreenParams.xy); + } + #if defined(EXPERIMENT__CUSTOM_DEPTH) { float4 clip_pos = mul(UNITY_MATRIX_VP, float4(i.worldPos, 1.0)); @@ -1502,6 +1512,9 @@ float4 effect(inout v2f i, out float depth) #if defined(_RENDERING_CUTOUT_STOCHASTIC) float ar = rand2(i.uv0); clip(albedo.a - ar); +#elif defined(_RENDERING_CUTOUT_IGN) + float ar = ign(tdata.screen_uv_round); + clip(albedo.a - ar); #else clip(albedo.a - _Alpha_Cutoff); #endif @@ -2418,7 +2431,7 @@ float4 effect(inout v2f i, out float depth) float4 lit = getLitColor(vertex_light_color, albedo, i.worldPos, normal, metallic, 1.0 - roughness, i.uv0, ao, /*enable_direct=*/true, - diffuse_contrib, i); + diffuse_contrib, i, tdata); #if defined(_GIMMICK_FLAT_COLOR) if (round(_Gimmick_Flat_Color_Enable_Dynamic)) { diff --git a/tooner_outline_pass.cginc b/tooner_outline_pass.cginc index 1d05763..a318c5f 100644 --- a/tooner_outline_pass.cginc +++ b/tooner_outline_pass.cginc @@ -276,6 +276,16 @@ void geom(triangle v2f tri_in[3], fixed4 frag (v2f i) : SV_Target { + ToonerData tdata; + { + float3 full_vec_eye_to_geometry = i.worldPos - _WorldSpaceCameraPos; + float3 world_dir = normalize(i.worldPos - _WorldSpaceCameraPos); + float perspective_divide = 1.0 / i.pos.w; + float perspective_factor = length(full_vec_eye_to_geometry * perspective_divide); + tdata.screen_uv = i.screenPos.xy * perspective_divide; + tdata.screen_uv_round = floor(tdata.screen_uv * _ScreenParams.xy); + } + i.normal = -normalize(i.normal); #if defined(_OUTLINES) @@ -331,7 +341,7 @@ fixed4 frag (v2f i) : SV_Target albedo, i.worldPos, i.normal, /*metallic=*/0, /*smoothness=*/0, i.uv0, ao, /*enable_direct=*/false, - /*diffuse_contrib=*/0, i); + /*diffuse_contrib=*/0, i, tdata); result += albedo * _Outline_Emission_Strength; #if defined(_GIMMICK_AL_CHROMA_00) -- cgit v1.2.3