diff options
| -rw-r--r-- | Editor/tooner.cs | 100 | ||||
| -rw-r--r-- | disinfo.cginc | 100 | ||||
| -rw-r--r-- | feature_macros.cginc | 3 | ||||
| -rw-r--r-- | globals.cginc | 23 | ||||
| -rw-r--r-- | math.cginc | 10 | ||||
| -rw-r--r-- | oklab.cginc | 2 | ||||
| -rw-r--r-- | tooner.shader | 38 | ||||
| -rw-r--r-- | tooner_lighting.cginc | 80 |
8 files changed, 347 insertions, 9 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs index 55e2dba..c4c2f5a 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -1692,6 +1692,105 @@ public class ToonerGUI : ShaderGUI { EditorGUI.indentLevel -= 1; } + void DoGimmickLetterGrid() { + MaterialProperty bc; + bc = FindProperty("_Gimmick_Letter_Grid_Enable_Static"); + bool enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = EditorGUILayout.Toggle("Letter grid", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + SetKeyword("_GIMMICK_LETTER_GRID", enabled); + + if (!enabled) { + return; + } + + EditorGUI.indentLevel += 1; + + bc = FindProperty("_Gimmick_Letter_Grid_Texture"); + editor.TexturePropertySingleLine( + MakeLabel(bc, "Texture"), + bc); + + bc = FindProperty("_Gimmick_Letter_Grid_Tex_Res_X"); + editor.FloatProperty(bc, "Number of glyphs in texture (X)"); + bc = FindProperty("_Gimmick_Letter_Grid_Tex_Res_Y"); + editor.FloatProperty(bc, "Number of glyphs in texture (Y)"); + + bc = FindProperty("_Gimmick_Letter_Grid_Res_X"); + editor.FloatProperty(bc, "Number of glyphs in grid (X)"); + bc = FindProperty("_Gimmick_Letter_Grid_Res_Y"); + editor.FloatProperty(bc, "Number of glyphs in grid (Y)"); + + bc = FindProperty("_Gimmick_Letter_Grid_UV_Scale_Offset"); + editor.VectorProperty(bc, "UV scale & offset"); + bc = FindProperty("_Gimmick_Letter_Grid_Padding"); + editor.FloatProperty(bc, "Padding"); + + bc = FindProperty("_Gimmick_Letter_Grid_Color"); + editor.ColorProperty(bc, "Color"); + bc = FindProperty("_Gimmick_Letter_Grid_Metallic"); + editor.RangeProperty(bc, "Metallic"); + bc = FindProperty("_Gimmick_Letter_Grid_Roughness"); + editor.RangeProperty(bc, "Roughness"); + bc = FindProperty("_Gimmick_Letter_Grid_Emission"); + editor.FloatProperty(bc, "Emission"); + + bc = FindProperty("_Gimmick_Letter_Grid_UV_Select"); + editor.RangeProperty( + bc, + "UV channel"); + + bc = FindProperty("_Gimmick_Letter_Grid_Color_Wave"); + enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = EditorGUILayout.Toggle("Color waves", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + SetKeyword("_GIMMICK_LETTER_GRID_COLOR_WAVE", enabled); + + if (enabled) { + EditorGUI.indentLevel += 1; + bc = FindProperty("_Gimmick_Letter_Grid_Color_Wave_Speed"); + editor.FloatProperty(bc, "Speed"); + bc = FindProperty("_Gimmick_Letter_Grid_Color_Wave_Frequency"); + editor.FloatProperty(bc, "Frequency"); + EditorGUI.indentLevel -= 1; + } + + bc = FindProperty("_Gimmick_Letter_Grid_Rim_Lighting"); + enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = EditorGUILayout.Toggle("Rim lighting", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + SetKeyword("_GIMMICK_LETTER_GRID_RIM_LIGHTING", enabled); + + if (enabled) { + EditorGUI.indentLevel += 1; + bc = FindProperty("_Gimmick_Letter_Grid_Rim_Lighting_Power"); + editor.FloatProperty(bc, "Power"); + bc = FindProperty("_Gimmick_Letter_Grid_Rim_Lighting_Center"); + editor.FloatProperty(bc, "Center"); + bc = FindProperty("_Gimmick_Letter_Grid_Rim_Lighting_Quantization"); + editor.FloatProperty(bc, "Quantization"); + bc = FindProperty("_Gimmick_Letter_Grid_Rim_Lighting_Mask"); + editor.TexturePropertySingleLine(MakeLabel(bc, "Mask"), bc); + if (bc.textureValue) { + EditorGUI.indentLevel += 1; + bc = FindProperty("_Gimmick_Letter_Grid_Rim_Lighting_Mask_UV_Select"); + editor.FloatProperty(bc, "Mask UV Select"); + bc = FindProperty("_Gimmick_Letter_Grid_Rim_Lighting_Mask_Invert"); + editor.FloatProperty(bc, "Mask invert"); + EditorGUI.indentLevel -= 1; + } + EditorGUI.indentLevel -= 1; + } + + EditorGUI.indentLevel -= 1; + } + void DoGimmicks() { if (!AddCollapsibleMenu("Gimmicks", "_Gimmicks")) { return; @@ -1710,6 +1809,7 @@ public class ToonerGUI : ShaderGUI { DoGimmickFaceMeWorldY(); DoGimmickRorschach(); DoGimmickMirrorUVFlip(); + DoGimmickLetterGrid(); DoClones(); DoExplosion(); DoGeoScroll(); diff --git a/disinfo.cginc b/disinfo.cginc new file mode 100644 index 0000000..c5cc19c --- /dev/null +++ b/disinfo.cginc @@ -0,0 +1,100 @@ +#include "globals.cginc" + +#ifndef __DISINFO_INC +#define __DISINFO_INC + +/* + * A small font rendering library. + * + * Sample usage: + * + * fixed4 frag(v2f i) : SV_Target + * { + * float2 uv = i.uv; + * int2 cell_pos; + * float2 cell_uv; + * float2 res = int2(4, 4); + * if (!getBoxLoc(uv, 0.1, 0.9, res, cell_pos, cell_uv)) { + * return float4(0, 0, 0, 1); + * } + * float2 duv = float2(ddx(i.uv.x), ddy(i.uv.y)) / 4; + * float4 font_color = renderInBox(67, cell_uv, duv); + * + * return font_color; + * } + */ + +// Returns false if `uv` does not fall within `bounds`. +bool remapUVSmaller(float2 uv, float2 bottom_left, float2 top_right, + out float2 uvr) { + if (!(uv.x > bottom_left.x && uv.x < top_right.x && + uv.y > bottom_left.y && uv.y < top_right.y)) { + return false; + } + + uvr = uv - bottom_left; + uvr = uvr / (top_right - bottom_left); + + return true; +} + +// bounds: the left/right/top/bottom bounds of the inner UV region, +// respectively. +// Always returns true. +bool remapUVBigger(float2 uv, float2 bottom_left, float2 top_right, + out float2 uvr) { + uvr = uv * (top_right - bottom_left) + bottom_left; + + return true; +} + +bool getBoxLoc(float2 uv, float2 bottom_left, float2 top_right, + int2 res, float padding, out int2 cell_pos, out float2 cell_uv) +{ + float2 box_uv; + if (!remapUVSmaller(uv, bottom_left, top_right, box_uv)) { + return false; + } + + // The integer index of the cell pointed to by `uv`, on the interval + // [0, res.x - 1] * [0, res.y - 1] + cell_pos = fmod(floor(box_uv * res), res); + + float2 box_sz = 1.0 / float2(res); + float2 cell_bot_left = (cell_pos - padding) * box_sz; + float2 cell_top_right = (cell_pos + 1 + padding) * box_sz; + if (!remapUVSmaller(box_uv, cell_bot_left, cell_top_right, cell_uv)) { + // This should never happen Clueless + return true; + } + + return true; +} + +// `c` is a character encoded as ASCII. +float4 renderInBox(int c, float2 uv, float2 cell_uv, texture2D font, int2 font_res) +{ + int letter_idx = c; + int2 letter_pos = int2( + font_res.x - (letter_idx % font_res.x), + letter_idx / font_res.x); + letter_pos.x = font_res.x - letter_pos.x; + letter_pos.y = (font_res.y - 1) - letter_pos.y; + float2 letter_box_sz = 1.0 / float2(font_res); + float2 letter_bot_left = letter_pos * letter_box_sz; + float2 letter_top_right = (letter_pos + 1) * letter_box_sz; + float2 letter_uv; + remapUVBigger(cell_uv, letter_bot_left, letter_top_right, letter_uv); + +#if 0 + float4 font_color = font.SampleGrad(linear_clamp_s, letter_uv, + abs(ddx(uv.x)) + abs(ddx(uv.y)), + abs(ddy(uv.x)) + abs(ddy(uv.y))); +#else + float4 font_color = font.SampleLevel(linear_clamp_s, letter_uv, 0); +#endif + return font_color; +} + +#endif // __DISINFO_INC + diff --git a/feature_macros.cginc b/feature_macros.cginc index 4aed35b..40f2bc3 100644 --- a/feature_macros.cginc +++ b/feature_macros.cginc @@ -155,6 +155,9 @@ #pragma shader_feature_local _ _DISCARD #pragma shader_feature_local _ _BRIGHTNESS_CLAMP #pragma shader_feature_local _ _WORLD_INTERPOLATORS +#pragma shader_feature_local _ _GIMMICK_LETTER_GRID +#pragma shader_feature_local _ _GIMMICK_LETTER_GRID_COLOR_WAVE +#pragma shader_feature_local _ _GIMMICK_LETTER_GRID_RIM_LIGHTING #endif // __FEATURE_MACROS_INC diff --git a/globals.cginc b/globals.cginc index feaec79..25cd343 100644 --- a/globals.cginc +++ b/globals.cginc @@ -636,5 +636,28 @@ float _Rorschach_Mask_Invert; float _Mirror_UV_Flip_Enable_Dynamic; #endif +#if defined(_GIMMICK_LETTER_GRID) +texture2D _Gimmick_Letter_Grid_Texture; +float _Gimmick_Letter_Grid_Res_X; +float _Gimmick_Letter_Grid_Res_Y; +float _Gimmick_Letter_Grid_Tex_Res_X; +float _Gimmick_Letter_Grid_Tex_Res_Y; +float4 _Gimmick_Letter_Grid_UV_Scale_Offset; +float _Gimmick_Letter_Grid_Padding; +float4 _Gimmick_Letter_Grid_Color; +float _Gimmick_Letter_Grid_Metallic; +float _Gimmick_Letter_Grid_Roughness; +float _Gimmick_Letter_Grid_Emission; +float _Gimmick_Letter_Grid_UV_Select; +float _Gimmick_Letter_Grid_Color_Wave_Speed; +float _Gimmick_Letter_Grid_Color_Wave_Frequency; +float _Gimmick_Letter_Grid_Rim_Lighting_Power; +float _Gimmick_Letter_Grid_Rim_Lighting_Center; +float _Gimmick_Letter_Grid_Rim_Lighting_Quantization; +texture2D _Gimmick_Letter_Grid_Rim_Lighting_Mask; +float _Gimmick_Letter_Grid_Rim_Lighting_Mask_UV_Select; +float _Gimmick_Letter_Grid_Rim_Lighting_Mask_Invert; +#endif + #endif @@ -113,5 +113,15 @@ float fbm(float3 p, const int n_octaves, float w) return res; } +float median(float x, float y, float z) +{ + return max(min(x, y), min(max(x, y), z)); +} + +float median(float3 x) +{ + return median(x.x, x.y, x.z); +} + #endif // __MATH_INC diff --git a/oklab.cginc b/oklab.cginc index c91204d..1b453af 100644 --- a/oklab.cginc +++ b/oklab.cginc @@ -29,7 +29,7 @@ #ifndef __OKLAB_INC #define __OKLAB_INC -#if defined(_OKLAB) +#if defined(_OKLAB) || defined(_GIMMICK_LETTER_GRID_COLOR_WAVE) // Utilities relating to the OKLAB color space, as defined here: // https://bottosson.github.io/posts/oklab/ diff --git a/tooner.shader b/tooner.shader index 345e3a9..645a3db 100644 --- a/tooner.shader +++ b/tooner.shader @@ -209,17 +209,41 @@ Shader "yum_food/tooner" _Glitter_Enabled("Glitter enabled", Float) = 0 _Glitter_Mask("Glitter mask", 2D) = "white" {} - _Glitter_Color("Glitter mask", Color) = (1, 1, 1, 1) - _Glitter_Density("Glitter density", float) = 400 + _Glitter_Color("Glitter color", Color) = (1, 1, 1, 1) + _Glitter_Density("Glitter density", Float) = 400 _Glitter_Amount("Glitter amount", Range(1, 100)) = 35 - _Glitter_Speed("Glitter speed", float) = 1 - _Glitter_Seed("Glitter seed", float) = 1 - _Glitter_Brightness("Glitter brightness (unlit)", float) = 1 - _Glitter_Brightness_Lit("Glitter brightness (lit)", float) = 0 + _Glitter_Speed("Glitter speed", Float) = 1 + _Glitter_Seed("Glitter seed", Float) = 1 + _Glitter_Brightness("Glitter brightness (unlit)", Float) = 1 + _Glitter_Brightness_Lit("Glitter brightness (lit)", Float) = 0 _Glitter_Angle("Glitter angle", Range(0, 90)) = 90 - _Glitter_Power("Glitter power", float) = 30 + _Glitter_Power("Glitter power", Float) = 30 _Glitter_UV_Select("Glitter UV channel", Range(0, 7)) = 0 + _Gimmick_Letter_Grid_Enable_Static("Enable letter grid (static)", Float) = 0 + _Gimmick_Letter_Grid_Texture("Letter grid texture", 2D) = "black" {} + _Gimmick_Letter_Grid_Tex_Res_X("Texture letter grid X resolution", Float) = 16 + _Gimmick_Letter_Grid_Tex_Res_Y("Texture letter grid Y resolution", Float) = 8 + _Gimmick_Letter_Grid_Res_X("Letter grid X resolution", Float) = 8 + _Gimmick_Letter_Grid_Res_Y("Letter grid Y resolution", Float) = 8 + _Gimmick_Letter_Grid_UV_Scale_Offset("Letter grid UV bounds", Vector) = (1, 1, 0, 0) + _Gimmick_Letter_Grid_Padding("Padding", Float) = 0.02 + _Gimmick_Letter_Grid_Color("Color", Color) = (1, 1, 1, 1) + _Gimmick_Letter_Grid_Metallic("Metallic", Range(0, 1)) = 0 + _Gimmick_Letter_Grid_Roughness("Roughness", Range(0 ,1)) = 0.5 + _Gimmick_Letter_Grid_Emission("Emission", Range(0 ,1)) = 0.0 + _Gimmick_Letter_Grid_UV_Select("Letter grid UV channel", Range(0, 7)) = 0 + _Gimmick_Letter_Grid_Color_Wave("Letter grid color wave", Float) = 0 + _Gimmick_Letter_Grid_Color_Wave_Speed("Letter grid color wave", Float) = 1 + _Gimmick_Letter_Grid_Color_Wave_Frequency("Letter grid color wave", Float) = 1 + _Gimmick_Letter_Grid_Rim_Lighting("_Gimmick_Letter_Grid_Rim_Lighting", Float) = 0 + _Gimmick_Letter_Grid_Rim_Lighting_Power("_Gimmick_Letter_Grid_Rim_Lighting_Power", Float) = 5 + _Gimmick_Letter_Grid_Rim_Lighting_Center("_Gimmick_Letter_Grid_Rim_Lighting_Center", Float) = 0 + _Gimmick_Letter_Grid_Rim_Lighting_Quantization("_Gimmick_Letter_Grid_Rim_Lighting_Quantization", Float) = -1 + _Gimmick_Letter_Grid_Rim_Lighting_Mask("Mask", 2D) = "white" {} + _Gimmick_Letter_Grid_Rim_Lighting_Mask_UV_Select("_Gimmick_Letter_Grid_Rim_Lighting_Mask_UV_Select", Float) = 0 + _Gimmick_Letter_Grid_Rim_Lighting_Mask_Invert("_Gimmick_Letter_Grid_Rim_Lighting_Mask_Invert", Float) = 0 + [MaterialToggle] _Explode_Toggle("Explode toggle", Float) = 0 _Explode_Phase("Explode phase", Range(0, 1)) = 0 [Enum(UnityEngine.Rendering.CullMode)] _OutlinesCull ("Outlines pass culling mode", Float) = 1 diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc index fa65cec..19063f3 100644 --- a/tooner_lighting.cginc +++ b/tooner_lighting.cginc @@ -5,6 +5,7 @@ #include "audiolink.cginc" #include "clones.cginc" #include "cnlohr.cginc" +#include "disinfo.cginc" #include "eyes.cginc" #include "globals.cginc" #include "halos.cginc" @@ -1402,6 +1403,7 @@ float4 effect(inout v2f i) #else float roughness = _Roughness; #endif + #if defined(VERTEXLIGHT_ON) float4 vertex_light_color = float4(i.vertexLightColor, 1); #else @@ -1968,6 +1970,79 @@ float4 effect(inout v2f i) } #endif // _RIM_LIGHTING0 || _RIM_LIGHTING1 || _RIM_LIGHTING2 || _RIM_LIGHTING3 +#if defined(_GIMMICK_LETTER_GRID) + float3 gimmick_letter_grid_emission = 0; + { + int2 cell_pos; + int2 font_res = int2(round(_Gimmick_Letter_Grid_Tex_Res_X), round(_Gimmick_Letter_Grid_Tex_Res_Y)); + int2 grid_res = int2(round(_Gimmick_Letter_Grid_Res_X), round(_Gimmick_Letter_Grid_Res_Y)); + float2 cell_uv; // uv within each letter cell + + float4 scoff = _Gimmick_Letter_Grid_UV_Scale_Offset; + float2 uv = ((get_uv_by_channel(i, _Gimmick_Letter_Grid_UV_Select) - 0.5) - scoff.zw) * scoff.xy + 0.5; + bool in_box = getBoxLoc(uv, + /*bottom_left=*/0, + /*top_right=*/1, + /*res=*/grid_res, + /*padding=*/_Gimmick_Letter_Grid_Padding, + cell_pos, cell_uv); + + float n_glyphs = font_res.x * font_res.y; + float cell_rand = rand2(cell_pos); + float c = glsl_mod(cell_pos.y * grid_res.x + cell_pos.x + cell_rand * n_glyphs + _Time[3], n_glyphs); + float3 msd = renderInBox(c, uv, cell_uv, _Gimmick_Letter_Grid_Texture, font_res).rgb; + float sd = median(msd); + float px_range = 2; // determined by msdf-atlas-gen.exe; 2 is default + float2 unit_range = px_range / 1024; + float2 screen_tex_size = 1 / fwidth(cell_uv); + float screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), 1.0); + float screen_px_distance = screen_px_range * (sd - 0.5); + float op = saturate(screen_px_distance + 0.5); + op = saturate(floor(op * 4)); + + float4 grid_color = _Gimmick_Letter_Grid_Color; + +#if defined(_GIMMICK_LETTER_GRID_COLOR_WAVE) + { + float2 c = grid_res/2; + float d = floor(length(cell_pos - c)); + d *= _Gimmick_Letter_Grid_Color_Wave_Frequency; + + float3 col = LRGBtoOKLCH(grid_color.rgb); + col[2] += d - _Time[3] * _Gimmick_Letter_Grid_Color_Wave_Speed; + col = OKLCHtoLRGB(col); + grid_color.rgb = col; + } +#endif // _GIMMICK_LETTER_GRID_COLOR_WAVE +#if defined(_GIMMICK_LETTER_GRID_RIM_LIGHTING) + { + float theta = atan2(length(cross(MATCAP_VIEW_DIR(), normal)), dot(MATCAP_VIEW_DIR(), normal)); + float rl = abs(theta) / PI; // on [0, 1] + rl = pow(2, -_Gimmick_Letter_Grid_Rim_Lighting_Power * abs(rl - _Gimmick_Letter_Grid_Rim_Lighting_Center)); + float q = _Gimmick_Letter_Grid_Rim_Lighting_Quantization; + if (q > 0) { + rl = floor(rl * q) / q; + } + + float4 matcap_mask_raw = _Gimmick_Letter_Grid_Rim_Lighting_Mask.SampleBias(GET_SAMPLER_RL3, + get_uv_by_channel(i, _Gimmick_Letter_Grid_Rim_Lighting_Mask_UV_Select), _Global_Sample_Bias); + float matcap_mask = matcap_mask_raw.r; + matcap_mask = (bool) round(_Gimmick_Letter_Grid_Rim_Lighting_Mask_Invert) ? 1 - matcap_mask : matcap_mask; + matcap_mask *= matcap_mask_raw.a; + + op *= rl * matcap_mask; + } +#endif // GIMMICK_LETTER_GRID_RIM_LIGHTING + + albedo = lerp(albedo, grid_color, op * in_box); + metallic = lerp(metallic, _Gimmick_Letter_Grid_Metallic, op * in_box); + //metallic = lerp(metallic, glsl_mod(_Time[3], 1.0), op * in_box); + roughness = lerp(roughness, _Gimmick_Letter_Grid_Roughness, op * in_box); + gimmick_letter_grid_emission = _Gimmick_Letter_Grid_Color * _Gimmick_Letter_Grid_Emission * op * in_box; + } +#endif // _GIMMICK_LETTER_GRID + + #if defined(_OKLAB) // Do hue shift in perceptually uniform color space so it doesn't look like // shit. @@ -2074,7 +2149,6 @@ float4 effect(inout v2f i) #endif albedo.a = 1; #endif - return float4(lit.rgb + _Gimmick_Flat_Color_Emission * _Global_Emission_Factor, albedo.a); } #endif @@ -2114,6 +2188,10 @@ float4 effect(inout v2f i) #if defined(_RORSCHACH) result.rgb += rorschach_albedo.rgb * _Rorschach_Emission_Strength; #endif +#if defined(_GIMMICK_LETTER_GRID) + result.rgb += gimmick_letter_grid_emission; +#endif + #if defined(_EXPLODE) && defined(_AUDIOLINK) if (AudioLinkIsAvailable() && _Explode_Phase > 1E-6) { float4 al_color = |
