From 4bd9c2ba494013f292ddc14d793bc2b362aff365 Mon Sep 17 00:00:00 2001 From: yum Date: Fri, 31 Jan 2025 21:11:00 -0800 Subject: Add bayer matrices & grabpass-based lens shader --- Editor/tooner.cs | 66 +++++++++++++++++++++++++++++++++++++++++++++++---- audiolink.cginc | 6 ++--- feature_macros.cginc | 5 ++++ globals.cginc | 13 ++++++++++ interpolators.cginc | 5 ++-- math.cginc | 19 +++++++++++++++ tooner.shader | 10 ++++++++ tooner_lighting.cginc | 46 ++++++++++++++++++++++++++++------- 8 files changed, 153 insertions(+), 17 deletions(-) diff --git a/Editor/tooner.cs b/Editor/tooner.cs index f4cd4f2..fab06e0 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -529,11 +529,11 @@ public class ToonerGUI : ShaderGUI { enum TilingMode { Clamp, Repeat, - } + }; enum BaseColorMode { Color, SDF, - } + }; void DoDecal() { show_ui.Add(AddCollapsibleMenu("Decals", "_Decal")); EditorGUI.indentLevel += 1; @@ -792,7 +792,7 @@ public class ToonerGUI : ShaderGUI { Subtract, Min, Max, - } + }; void DoMatcap() { for (int i = 0; i < 2; i++) { @@ -2647,7 +2647,7 @@ public class ToonerGUI : ShaderGUI { Cylinder = 0, Plane = 1, Sphere = 2, - } + }; void DoGimmickFog0() { MaterialProperty bc; @@ -3179,6 +3179,63 @@ public class ToonerGUI : ShaderGUI { EditorGUI.indentLevel -= 1; } + enum Lens00Mode { + Bayer, + InterleavedGradientNoise, + } + + void DoLens00() { + MaterialProperty bc; + + bc = FindProperty("_Gimmick_Lens_00_Enable_Static"); + bool enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = Toggle("Lens00", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + SetKeyword("_GIMMICK_LENS_00", enabled); + + if (!enabled) { + return; + } + + EditorGUI.indentLevel += 1; + + bc = FindProperty("_Gimmick_Lens_00_Enable_Frame_Counter"); + enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = Toggle("Frame counter", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + SetKeyword("_GIMMICK_LENS_00_FRAME_COUNTER", enabled); + + bc = FindProperty("_Gimmick_Lens_00_Subdivisions"); + FloatProperty(bc, "Quantization subdivisions"); + + if (enabled) { + EditorGUI.indentLevel += 1; + bc = FindProperty("_Gimmick_Lens_00_Frame_Counter_Speed"); + FloatProperty(bc, "Speed"); + EditorGUI.indentLevel -= 1; + } + + + bc = FindProperty("_Gimmick_Lens_00_Scale"); + FloatProperty(bc, "Scale"); + + bc = FindProperty("_Gimmick_Lens_00_Mode"); + Lens00Mode mode = (Lens00Mode) Math.Round(bc.floatValue); + EditorGUI.BeginChangeCheck(); + mode = (Lens00Mode) EnumPopup( + MakeLabel("Mode"), mode); + EditorGUI.EndChangeCheck(); + bc.floatValue = (float) mode; + SetKeyword("_GIMMICK_LENS_00_BAYER", mode == Lens00Mode.Bayer); + SetKeyword("_GIMMICK_LENS_00_INTERLEAVED_GRADIENT_NOISE", mode == Lens00Mode.InterleavedGradientNoise); + + EditorGUI.indentLevel -= 1; + } + void DoGimmicks() { show_ui.Add(AddCollapsibleMenu("Gimmicks", "_Gimmicks")); EditorGUI.indentLevel += 1; @@ -3211,6 +3268,7 @@ public class ToonerGUI : ShaderGUI { DoExplosion(); DoGeoScroll(); DoGimmickEpilepsyMode(); + DoLens00(); EditorGUI.indentLevel -= 1; show_ui.RemoveAt(show_ui.Count - 1); diff --git a/audiolink.cginc b/audiolink.cginc index 802f584..2fe3f2b 100644 --- a/audiolink.cginc +++ b/audiolink.cginc @@ -2,9 +2,9 @@ #define __AUDIOLINK #if defined (_GIMMICK_QUANTIZE_LOCATION_AUDIOLINK) || defined(_GIMMICK_AL_CHROMA_00) || defined(_GIMMICK_FOG_00) || defined(_RENDERING_CUTOUT) || defined(_GIMMICK_DS2) - +#define TOONER_AUDIOLINK_AVAILABLE #include "Packages/com.llealloo.audiolink/Runtime/Shaders/AudioLink.cginc" - -#endif // _AUDIOLINK +#else +#endif #endif // __AUDIOLINK diff --git a/feature_macros.cginc b/feature_macros.cginc index c5a4da7..ecbc709 100644 --- a/feature_macros.cginc +++ b/feature_macros.cginc @@ -286,6 +286,11 @@ #pragma shader_feature_local _ _OPTIMIZE_INTERPOLATORS #pragma shader_feature_local _ _ACES_FILMIC #pragma shader_feature_local _ _GIMMICK_ZWRITE_ABOMINATION +#pragma shader_feature_local _ _GIMMICK_LENS_00 +#pragma shader_feature_local _ _GIMMICK_LENS_00_FRAME_COUNTER +#pragma shader_feature_local _ _GIMMICK_LENS_00_GRABPASS +#pragma shader_feature_local _ _GIMMICK_LENS_00_BAYER +#pragma shader_feature_local _ _GIMMICK_LENS_00_INTERLEAVED_GRADIENT_NOISE #endif // __FEATURE_MACROS_INC diff --git a/globals.cginc b/globals.cginc index 8f08a97..a1eca79 100644 --- a/globals.cginc +++ b/globals.cginc @@ -60,11 +60,15 @@ float _SpecularStrength; float _FresnelStrength; float _UseFresnel; float _ReflectionStrength; + +texture2D _Tooner_Grabpass; + #if defined(_REFLECTION_STRENGTH_TEX) texture2D _ReflectionStrengthTex; #endif float3 shadowedReflections; int _ReflShadows; + float _ReflShadowStrength; float _BrightnessReflShad; float _ContrastReflShad; @@ -1126,5 +1130,14 @@ texture2D _Rendering_Cutout_Noise_Mask; float4 _Rendering_Cutout_Noise_Mask_TexelSize; #endif +#if defined(_GIMMICK_LENS_00) +float _Gimmick_Lens_00_Enable_Frame_Counter; +float _Gimmick_Lens_00_Scale; +float _Gimmick_Lens_00_Subdivisions; +#if defined(_GIMMICK_LENS_00_FRAME_COUNTER) +float _Gimmick_Lens_00_Frame_Counter_Speed; +#endif +#endif + #endif diff --git a/interpolators.cginc b/interpolators.cginc index d363d50..64b0402 100644 --- a/interpolators.cginc +++ b/interpolators.cginc @@ -108,13 +108,14 @@ struct v2f float3 centerCamPos : TEXCOORD14; float2 screenPos : TEXCOORD15; + float4 grabPos : TEXCOORD16; #if defined(VERTEXLIGHT_ON) - float3 vertexLightColor : TEXCOORD16; + float3 vertexLightColor : TEXCOORD17; #endif #if defined(_TROCHOID) - float3 objPos_pre_trochoid : TEXCOORD17; + float3 objPos_pre_trochoid : TEXCOORD18; #endif UNITY_VERTEX_INPUT_INSTANCE_ID diff --git a/math.cginc b/math.cginc index 80fa9ab..bb422a4 100644 --- a/math.cginc +++ b/math.cginc @@ -7,6 +7,25 @@ #define TAU PI * 2.0 #define PHI 1.618033989 +static const float BayerM4x4[16] = { + 0.0/15.0, 8.0/15.0, 2.0/15.0, 10.0/15.0, + 12.0/15.0, 4.0/15.0, 14.0/15.0, 6.0/15.0, + 3.0/15.0, 11.0/15.0, 1.0/15.0, 9.0/15.0, + 15.0/15.0, 7.0/15.0, 13.0/15.0, 5.0/15.0 +}; + +// xdd +static const float BayerM8x8[64] = { + 0.0/63.0, 32.0/63.0, 8.0/63.0, 40.0/63.0, 2.0/63.0, 34.0/63.0, 10.0/63.0, 42.0/63.0, + 48.0/63.0, 16.0/63.0, 56.0/63.0, 24.0/63.0, 50.0/63.0, 18.0/63.0, 58.0/63.0, 26.0/63.0, + 12.0/63.0, 44.0/63.0, 4.0/63.0, 36.0/63.0, 14.0/63.0, 46.0/63.0, 6.0/63.0, 38.0/63.0, + 60.0/63.0, 28.0/63.0, 52.0/63.0, 20.0/63.0, 62.0/63.0, 30.0/63.0, 54.0/63.0, 22.0/63.0, + 3.0/63.0, 35.0/63.0, 11.0/63.0, 43.0/63.0, 1.0/63.0, 33.0/63.0, 9.0/63.0, 41.0/63.0, + 51.0/63.0, 19.0/63.0, 59.0/63.0, 27.0/63.0, 49.0/63.0, 17.0/63.0, 57.0/63.0, 25.0/63.0, + 15.0/63.0, 47.0/63.0, 7.0/63.0, 39.0/63.0, 13.0/63.0, 45.0/63.0, 5.0/63.0, 37.0/63.0, + 63.0/63.0, 31.0/63.0, 55.0/63.0, 23.0/63.0, 61.0/63.0, 29.0/63.0, 53.0/63.0, 21.0/63.0 +}; + // Hacky parameterizable whiteout blending. Probably some big mistakes but it // passes the eyeball test. // At w=0.5, this looks kinda like whiteout blending. diff --git a/tooner.shader b/tooner.shader index d44eef4..a816e67 100644 --- a/tooner.shader +++ b/tooner.shader @@ -1167,9 +1167,19 @@ Shader "yum_food/tooner" _Gimmick_Box_Discard_Corner_1("Corner 1", Vector) = (0, 0, 0, 0) _Gimmick_Box_Discard_Corner_2("Corner 2", Vector) = (0, 0, 0, 0) _Gimmick_Box_Discard_Invert("Invert", Float) = 0 + + _Gimmick_Lens_00_Enable_Static("Enable lens 00", Float) = 0 + _Gimmick_Lens_00_Enable_Frame_Counter("Enable frame counter", Float) = 0 + _Gimmick_Lens_00_Frame_Counter_Speed("Speed", Float) = 1 + _Gimmick_Lens_00_Subdivisions("Quantization subdivisions", Float) = 1 + _Gimmick_Lens_00_Mode("Mode", Float) = 0 // 0 = Bayer, 1 = InterleavedGradientNoise + _Gimmick_Lens_00_Scale("Scale", Float) = 1 + + } SubShader { + GrabPass { "_Tooner_Grabpass" } Tags { "VRCFallback"="ToonCutout" "DisableBatching"="True" diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc index b9ce630..3241394 100644 --- a/tooner_lighting.cginc +++ b/tooner_lighting.cginc @@ -267,6 +267,7 @@ v2f vert(appdata v) float2 suv = o.pos * float2(0.5, 0.5 * _ProjectionParams.x); o.screenPos = TransformStereoScreenSpaceTex(suv + 0.5 * o.pos.w, o.pos.w); + o.grabPos = ComputeGrabScreenPos(o.pos); getVertexLightColor(o); UNITY_TRANSFER_FOG(o, o.pos); @@ -442,6 +443,11 @@ void geom(triangle v2f tri_in[3], tri_out.RestartStrip(); } +#if defined(_LENS00) + +#endif + + #if defined(_RORSCHACH) || defined(_GLITTER) || defined(_RIM_LIGHTING0_GLITTER) || defined(_RIM_LIGHTING1_GLITTER) || defined(_RIM_LIGHTING2_GLITTER) || defined(_RIM_LIGHTING3_GLITTER) struct RorschachPBR { float4 albedo; @@ -1055,8 +1061,18 @@ float4 effect(inout v2f i, out float depth) float4 albedo = _Color; #endif // _BASECOLOR_MAP +#if defined(_FRAME_COUNTER) + const float frame = floor(_Frame_Counter); +#elif defined(TOONER_AUDIOLINK_AVAILABLE) + const float frame = ((float) AudioLinkData(ALPASS_GENERALVU + int2(1, 0)).x); +#else + const float frame = 0; +#endif // _FRAME_COUNTER + + #if defined(_GIMMICK_GERSTNER_WATER) #if defined(_EXPLODE) + if (_Explode_Phase < 1E-6) #endif { @@ -1445,14 +1461,6 @@ float4 effect(inout v2f i, out float depth) #endif #if defined(_RENDERING_CUTOUT) -#if defined(_FRAME_COUNTER) - float frame = floor(_Frame_Counter); -#else - float frame = 0; - if (AudioLinkIsAvailable()) { - frame = ((float) AudioLinkData(ALPASS_GENERALVU + int2(1, 0)).x); - } -#endif // _FRAME_COUNTER #if defined(_RENDERING_CUTOUT_STOCHASTIC) float ar = rand2(i.uv0); clip(albedo.a - ar); @@ -2275,6 +2283,28 @@ float4 effect(inout v2f i, out float depth) } #endif +#if defined(_GIMMICK_LENS_00) + { + // Use tdata.screen_uv to sample 8x8 Bayer matrix. + //uint2 screen_uv_round = floor(tdata.screen_uv * _ScreenParams.xy * _Gimmick_Lens_00_Scale); + //uint2 screen_uv_round = floor(tdata.screen_uv * _ScreenParams.xy * _Gimmick_Lens_00_Scale); + uint2 glasses_uv_round = floor(i.uv0 * _ScreenParams.xy * _Gimmick_Lens_00_Scale); + uint2 bayer_idx = (glasses_uv_round % 8); +#if defined(_GIMMICK_LENS_00_BAYER) + float mask = BayerM8x8[bayer_idx.y * 8 + bayer_idx.x]; +#elif defined(_GIMMICK_LENS_00_INTERLEAVED_GRADIENT_NOISE) + float mask = ign(glasses_uv_round); +#endif + mask = frac(mask + frame * PHI * _Gimmick_Lens_00_Frame_Counter_Speed); + float2 grab_uv = i.grabPos.xy / i.grabPos.w; + + //grab_uv = floor(grab_uv * _ScreenParams.xy * _Gimmick_Lens_00_Scale) / (_ScreenParams.xy * _Gimmick_Lens_00_Scale); + float3 grab_color = _Tooner_Grabpass.SampleLevel(linear_clamp_s, grab_uv, 0).rgb; + grab_color = round(grab_color * _Gimmick_Lens_00_Subdivisions) / _Gimmick_Lens_00_Subdivisions; + lit.rgb = (grab_color > mask); + } +#endif + #if defined(_GIMMICK_FLAT_COLOR) if (round(_Gimmick_Flat_Color_Enable_Dynamic)) { #if defined(_RENDERING_CUTOUT) -- cgit v1.2.3