From 2cf50223c6a88a6cbea64e3128c7b847dba1f8f2 Mon Sep 17 00:00:00 2001 From: yum Date: Fri, 6 Sep 2024 16:32:09 -0700 Subject: Add rorschach gimmick Wound up looking more like voronoi but oh well lol. Fix iq sdf include - now it can be included multiple times. --- Editor/tooner.cs | 31 +++++++++++++++++++ feature_macros.cginc | 1 + globals.cginc | 6 ++++ iq_sdf.cginc | 5 +++ rorschach.cginc | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ tooner.shader | 5 +++ tooner_lighting.cginc | 6 ++++ 7 files changed, 138 insertions(+) create mode 100644 rorschach.cginc diff --git a/Editor/tooner.cs b/Editor/tooner.cs index a7b0b19..97b0f1e 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -1421,6 +1421,36 @@ public class ToonerGUI : ShaderGUI { EditorGUI.indentLevel -= 1; } + void DoGimmickRorschach() { + MaterialProperty bc; + bc = FindProperty("_Rorschach_Enable_Static"); + bool enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = EditorGUILayout.Toggle("Rorschach", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + SetKeyword("_RORSCHACH", enabled); + + if (!enabled) { + return; + } + + EditorGUI.indentLevel += 1; + + bc = FindProperty("_Rorschach_Enable_Dynamic"); + enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = EditorGUILayout.Toggle("Enable (runtime switch)", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + + bc = FindProperty("_Rorschach_Count_X"); + editor.FloatProperty(bc, "Count (x)"); + bc = FindProperty("_Rorschach_Count_Y"); + editor.FloatProperty(bc, "Count (y)"); + + EditorGUI.indentLevel -= 1; + } void DoGimmicks() { DoGimmickFlatColor(); @@ -1431,6 +1461,7 @@ public class ToonerGUI : ShaderGUI { DoGimmickPixellate(); DoGimmickTrochoid(); DoGimmickFaceMeWorldY(); + DoGimmickRorschach(); } void DoMochieParams() { diff --git a/feature_macros.cginc b/feature_macros.cginc index 7a50526..8dca391 100644 --- a/feature_macros.cginc +++ b/feature_macros.cginc @@ -142,6 +142,7 @@ #pragma shader_feature_local _ _PIXELLATE #pragma shader_feature_local _ _TROCHOID #pragma shader_feature_local _ _FACE_ME_WORLD_Y +#pragma shader_feature_local _ _RORSCHACH #pragma shader_feature_local _ _CLEARCOAT #pragma shader_feature_local _ _CLEARCOAT_MASK #pragma shader_feature_local _ _CLEARCOAT_MASK2 diff --git a/globals.cginc b/globals.cginc index 0a95482..c1f142a 100644 --- a/globals.cginc +++ b/globals.cginc @@ -595,5 +595,11 @@ float _FaceMeWorldY_Enable_Y; float _FaceMeWorldY_Enable_Z; #endif +#if defined(_RORSCHACH) +float _Rorschach_Enable_Dynamic; +float _Rorschach_Count_X; +float _Rorschach_Count_Y; +#endif + #endif diff --git a/iq_sdf.cginc b/iq_sdf.cginc index 472256c..4d1072e 100644 --- a/iq_sdf.cginc +++ b/iq_sdf.cginc @@ -1,3 +1,6 @@ +#ifndef __IQ_SDF_INC +#define __IQ_SDF_INC + #include "pema99.cginc" // The MIT License @@ -100,3 +103,5 @@ float3 op_rep(in float3 p, in float3 c) } // End licensed section + +#endif // __IQ_SDF_INC diff --git a/rorschach.cginc b/rorschach.cginc new file mode 100644 index 0000000..bfa550d --- /dev/null +++ b/rorschach.cginc @@ -0,0 +1,84 @@ +#ifndef __RORSCHACH_INC +#define __RORSCHACH_INC + +#if defined(_RORSCHACH) + +#include "globals.cginc" +#include "interpolators.cginc" +#include "iq_sdf.cginc" +#include "pema99.cginc" + +struct RorschachPBR { + float4 albedo; +}; + +float map_sdf(float3 p, float2 e, float3 period) +{ + float r = 1 * min(period.x, min(period.y, period.z)); + float st = sin(_Time[1] * e.y * e.y + e.x * 3.14159265 * 2); + r *= st; + return distance_from_sphere(p, r); +} + +float map_dr( + float3 p, + float3 period, + float3 count, + out float3 which + ) +{ + which = round(p / period); + // Direction to nearest neighboring cell. + float3 min_d = p - period * which; + float3 o = sign(min_d); + + float d = 1E9; + float3 which_tmp = which; + for (int xi = -2; xi < 3; xi++) + for (int yi = -2; yi < 3; yi++) + { + float3 rid = which + float3(xi, yi, 0) * o; + float3 r = p - period * rid; + float2 e = float2( + rand3(rid), + rand3(rid + 1)); + float cur_d = map_sdf(r, e, period); + which_tmp = cur_d < d ? rid : which; + d = min(d, cur_d); + } + + which = which_tmp; + return d; +} + +RorschachPBR get_rorschach(v2f i) +{ + RorschachPBR result; + result.albedo = float4(0, 0, 0, 1); + + float3 ro = float3(i.uv0.x - 0.5, i.uv0.y - 0.5, 0); + float3 rd = float3(0, 0, 1); + + float3 which; + float3 period = float3(1 / (_Rorschach_Count_X+1), 1 / (_Rorschach_Count_Y+1), 1); + float3 count = float3(_Rorschach_Count_X, _Rorschach_Count_Y, 1); + float d = map_dr(ro, period, count, which); + d -= map_dr(1 - ro, period, count, which) * 4; + + d = 1 - d; + d *= d; + d *= d; + d *= d; + d = 1 - d; + + d *= 3; + d = saturate(d); + + result.albedo.rgb = d; + + return result; +} + +#endif // _RORSCHACH +#endif // __RORSCHACH_INC + diff --git a/tooner.shader b/tooner.shader index 6088c59..a0b61ea 100644 --- a/tooner.shader +++ b/tooner.shader @@ -470,6 +470,11 @@ Shader "yum_food/tooner" _FaceMeWorldY_Enable_Y("x", Float) = 1 _FaceMeWorldY_Enable_Z("x", Float) = 0 + _Rorschach_Enable_Static("Enable rorschach gimmick", Float) = 0.0 + _Rorschach_Enable_Dynamic("Enable rorschach gimmick", Float) = 0.0 + _Rorschach_Count_X("Enable rorschach gimmick", Float) = 2 + _Rorschach_Count_Y("Enable rorschach gimmick", Float) = 2 + _Enable_SSR("Enable SSR", Float) = 0 _SSRStrength("SSR Strength", Float) = 1 _SSRHeight("SSR Height", Float) = 0.1 diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc index 221b1a6..3c2874b 100644 --- a/tooner_lighting.cginc +++ b/tooner_lighting.cginc @@ -13,6 +13,7 @@ #include "motion.cginc" #include "pbr.cginc" #include "poi.cginc" +#include "rorschach.cginc" #include "shear_math.cginc" #include "tooner_scroll.cginc" #include "trochoid_math.cginc" @@ -1160,6 +1161,11 @@ float4 effect(inout v2f i) } #endif +#if defined(_RORSCHACH) + if (_Rorschach_Enable_Dynamic) { + albedo = get_rorschach(i).albedo; + } +#endif #if defined(_RENDERING_CUTOUT) #if defined(_RENDERING_CUTOUT_STOCHASTIC) -- cgit v1.2.3