diff options
| author | yum <yum.food.vr@gmail.com> | 2024-12-01 00:11:04 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2024-12-01 00:11:04 -0800 |
| commit | 3089bd2ea6a3952e3ea0f31d8fc5eca1864cefab (patch) | |
| tree | 8dc16932eb96cc4e592b865731b10c37a8fb31e8 | |
| parent | 8232f195185d7550c331a78ed57b1a44746d294b (diff) | |
Add small programmable text display gimmick
Use Third_Party/gen_atlas to create a 512x512 texture and put it in the
texture slot (the resolution is hardcoded to 512 in shader). Use sliders to
control the grid size. If desired, use global offset to make it possible
to linearly animate between e.g. 0-9 and have it display as ASCII
'0'-'9'.
| -rw-r--r-- | Editor/tooner.cs | 62 | ||||
| -rw-r--r-- | Third_Party/gen_atlas | 13 | ||||
| -rw-r--r-- | disinfo.cginc | 4 | ||||
| -rw-r--r-- | feature_macros.cginc | 2 | ||||
| -rw-r--r-- | globals.cginc | 20 | ||||
| -rw-r--r-- | tooner.shader | 19 | ||||
| -rw-r--r-- | tooner_lighting.cginc | 65 |
7 files changed, 174 insertions, 11 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs index e9ba50e..fca422b 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -1987,6 +1987,67 @@ public class ToonerGUI : ShaderGUI { EditorGUI.indentLevel -= 1; } + void DoGimmickLetterGrid2() { + MaterialProperty bc; + bc = FindProperty("_Gimmick_Letter_Grid_2_Enable_Static"); + bool enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = Toggle("Letter grid 2", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + SetKeyword("_GIMMICK_LETTER_GRID_2", enabled); + + if (!enabled) { + return; + } + + EditorGUI.indentLevel += 1; + + bc = FindProperty("_Gimmick_Letter_Grid_2_Texture"); + TexturePropertySingleLine( + MakeLabel(bc, "Texture"), + bc); + + bc = FindProperty("_Gimmick_Letter_Grid_2_Tex_Res_X"); + FloatProperty(bc, "Number of glyphs in texture (X)"); + bc = FindProperty("_Gimmick_Letter_Grid_2_Tex_Res_Y"); + FloatProperty(bc, "Number of glyphs in texture (Y)"); + + MaterialProperty rows = FindProperty("_Gimmick_Letter_Grid_2_Res_X"); + RangeProperty(rows, "Number of glyphs in grid (X)"); + MaterialProperty cols = FindProperty("_Gimmick_Letter_Grid_2_Res_Y"); + RangeProperty(cols, "Number of glyphs in grid (Y)"); + + for (int i = 0; i < rows.floatValue; i++) { + EditorGUI.indentLevel += 1; + bc = FindProperty($"_Gimmick_Letter_Grid_2_Data_Row_{i}"); + VectorProperty(bc, $"Letter grid data row {i}"); + EditorGUI.indentLevel -= 1; + } + + bc = FindProperty("_Gimmick_Letter_Grid_2_UV_Scale_Offset"); + VectorProperty(bc, "UV scale & offset"); + bc = FindProperty("_Gimmick_Letter_Grid_2_Padding"); + FloatProperty(bc, "Padding"); + + bc = FindProperty("_Gimmick_Letter_Grid_2_Color"); + ColorProperty(bc, "Color"); + bc = FindProperty("_Gimmick_Letter_Grid_2_Metallic"); + RangeProperty(bc, "Metallic"); + bc = FindProperty("_Gimmick_Letter_Grid_2_Roughness"); + RangeProperty(bc, "Roughness"); + bc = FindProperty("_Gimmick_Letter_Grid_2_Emission"); + FloatProperty(bc, "Emission"); + + bc = FindProperty("_Gimmick_Letter_Grid_2_Mask"); + TexturePropertySingleLine(MakeLabel(bc, "Mask"), bc); + + bc = FindProperty("_Gimmick_Letter_Grid_2_Global_Offset"); + FloatProperty(bc, "Global offset"); + + EditorGUI.indentLevel -= 1; + } + void DoGimmickAudiolinkChroma00() { MaterialProperty bc; bc = FindProperty("_Gimmick_AL_Chroma_00_Enable_Static"); @@ -2305,6 +2366,7 @@ public class ToonerGUI : ShaderGUI { DoGimmickRorschach(); DoGimmickMirrorUVFlip(); DoGimmickLetterGrid(); + DoGimmickLetterGrid2(); DoGimmickAudiolinkChroma00(); DoGimmickFog0(); DoGimmickAurora(); diff --git a/Third_Party/gen_atlas b/Third_Party/gen_atlas index dfb0e61..b880ac8 100644 --- a/Third_Party/gen_atlas +++ b/Third_Party/gen_atlas @@ -10,7 +10,7 @@ from PIL import Image CHAR_RANGES = [ (32, 126), # Printable ASCII # Add more ranges here as needed, e.g.: - # (160, 255), # Extended Latin + (160, 255), # Extended Latin ] def calculate_grid_size(char_ranges): @@ -32,21 +32,18 @@ def generate_atlas(font_path, resolution, draw_grid=False): cmd = [ "msdf-atlas-gen/build/bin/Debug/msdf-atlas-gen.exe", "-font", font_path, - "-type", "mtsdf", + "-type", "msdf", "-format", "png", "-imageout", "atlas.png", - "-json", "atlas.json", - "-size", "32", + "-size", "28", "-pxrange", "2", "-dimensions", str(resolution), str(resolution), "-chars", chars_str, "-uniformgrid", "-uniformcols", str(grid_size), "-uniformcell", str(cell_size), str(cell_size), - "-uniformorigin", "on", - "-coloringstrategy", "inktrap", +# "-uniformorigin", "on", "-errorcorrection", "auto", - "-miterlimit", "1.0", "-scanline" ] @@ -89,7 +86,7 @@ def draw_grid_lines(image, resolution): def rearrange_atlas(resolution, cell_width, cell_height, draw_grid=False): """Rearrange the atlas to include gaps for non-printable characters""" original = Image.open("atlas.png") - new_atlas = Image.new('RGBA', (resolution, resolution), (0, 0, 0, 255)) + new_atlas = Image.new('RGB', (resolution, resolution), (0, 0, 0)) grid_size = calculate_grid_size(CHAR_RANGES) cell_size = resolution // grid_size diff --git a/disinfo.cginc b/disinfo.cginc index c5cc19c..8a6a162 100644 --- a/disinfo.cginc +++ b/disinfo.cginc @@ -87,9 +87,7 @@ float4 renderInBox(int c, float2 uv, float2 cell_uv, texture2D font, int2 font_r 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))); + float4 font_color = font.Sample(linear_clamp_s, letter_uv); #else float4 font_color = font.SampleLevel(linear_clamp_s, letter_uv, 0); #endif diff --git a/feature_macros.cginc b/feature_macros.cginc index c0637c4..277f159 100644 --- a/feature_macros.cginc +++ b/feature_macros.cginc @@ -212,6 +212,8 @@ #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 +#pragma shader_feature_local _ _GIMMICK_LETTER_GRID_2 +#pragma shader_feature_local _ _GIMMICK_LETTER_GRID_2_MASK #pragma shader_feature_local _ _REFLECTION_STRENGTH_TEX #pragma shader_feature_local _ _GIMMICK_AL_CHROMA_00 #pragma shader_feature_local _ _GIMMICK_AL_CHROMA_00_HUE_SHIFT diff --git a/globals.cginc b/globals.cginc index 45d2b58..8432b8e 100644 --- a/globals.cginc +++ b/globals.cginc @@ -739,6 +739,26 @@ float _Gimmick_Letter_Grid_Rim_Lighting_Mask_UV_Select; float _Gimmick_Letter_Grid_Rim_Lighting_Mask_Invert; #endif +#if defined(_GIMMICK_LETTER_GRID_2) +texture2D _Gimmick_Letter_Grid_2_Texture; +float _Gimmick_Letter_Grid_2_Res_X; +float _Gimmick_Letter_Grid_2_Res_Y; +float4 _Gimmick_Letter_Grid_2_Data_Row_0; +float4 _Gimmick_Letter_Grid_2_Data_Row_1; +float4 _Gimmick_Letter_Grid_2_Data_Row_2; +float4 _Gimmick_Letter_Grid_2_Data_Row_3; +float _Gimmick_Letter_Grid_2_Tex_Res_X; +float _Gimmick_Letter_Grid_2_Tex_Res_Y; +float4 _Gimmick_Letter_Grid_2_UV_Scale_Offset; +float _Gimmick_Letter_Grid_2_Padding; +float4 _Gimmick_Letter_Grid_2_Color; +float _Gimmick_Letter_Grid_2_Metallic; +float _Gimmick_Letter_Grid_2_Roughness; +float _Gimmick_Letter_Grid_2_Emission; +texture2D _Gimmick_Letter_Grid_2_Mask; +float _Gimmick_Letter_Grid_2_Global_Offset; +#endif + #if defined(_GIMMICK_AL_CHROMA_00) float _Gimmick_AL_Chroma_00_Forward_Pass; float _Gimmick_AL_Chroma_00_Forward_Blend; diff --git a/tooner.shader b/tooner.shader index 91dffec..f2afa77 100644 --- a/tooner.shader +++ b/tooner.shader @@ -255,6 +255,25 @@ Shader "yum_food/tooner" _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 + _Gimmick_Letter_Grid_2_Enable_Static("Enable letter grid 2 (static)", Float) = 0 + _Gimmick_Letter_Grid_2_Texture("Letter grid texture", 2D) = "black" {} + _Gimmick_Letter_Grid_2_Tex_Res_X("Texture letter grid X resolution", Float) = 16 + _Gimmick_Letter_Grid_2_Tex_Res_Y("Texture letter grid Y resolution", Float) = 8 + _Gimmick_Letter_Grid_2_Res_X("Letter grid X resolution", Range(1, 4)) = 1 + _Gimmick_Letter_Grid_2_Res_Y("Letter grid Y resolution", Range(1, 4)) = 1 + _Gimmick_Letter_Grid_2_Data_Row_0("Letter grid data row 0", Vector) = (0, 0, 0, 0) + _Gimmick_Letter_Grid_2_Data_Row_1("Letter grid data row 1", Vector) = (0, 0, 0, 0) + _Gimmick_Letter_Grid_2_Data_Row_2("Letter grid data row 2", Vector) = (0, 0, 0, 0) + _Gimmick_Letter_Grid_2_Data_Row_3("Letter grid data row 3", Vector) = (0, 0, 0, 0) + _Gimmick_Letter_Grid_2_UV_Scale_Offset("Letter grid UV bounds", Vector) = (1, 1, 0, 0) + _Gimmick_Letter_Grid_2_Padding("Padding", Float) = 0.02 + _Gimmick_Letter_Grid_2_Color("Color", Color) = (1, 1, 1, 1) + _Gimmick_Letter_Grid_2_Metallic("Metallic", Range(0, 1)) = 0 + _Gimmick_Letter_Grid_2_Roughness("Roughness", Range(0 ,1)) = 0.5 + _Gimmick_Letter_Grid_2_Emission("Emission", Range(0 ,1)) = 0.0 + _Gimmick_Letter_Grid_2_Mask("Mask", 2D) = "white" {} + _Gimmick_Letter_Grid_2_Global_Offset("Global offset", 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 45de66c..92bd069 100644 --- a/tooner_lighting.cginc +++ b/tooner_lighting.cginc @@ -2309,6 +2309,68 @@ float4 effect(inout v2f i, out float depth) } #endif // _GIMMICK_LETTER_GRID +#if defined(_GIMMICK_LETTER_GRID_2) + float3 gimmick_letter_grid_2_emission = 0; +#if defined(_GIMMICK_LETTER_GRID_2_MASK) + float mask = _Gimmick_Letter_Grid_2_Mask.SampleLevel(linear_repeat_s, get_uv_by_channel(i, 0), 0); +#else + float mask = 1; +#endif + { + int2 cell_pos; + int2 font_res = int2(round(_Gimmick_Letter_Grid_2_Tex_Res_X), round(_Gimmick_Letter_Grid_2_Tex_Res_Y)); + int2 grid_res = int2(round(_Gimmick_Letter_Grid_2_Res_X), round(_Gimmick_Letter_Grid_2_Res_Y)); + float2 cell_uv; // uv within each letter cell + + float4 scoff = _Gimmick_Letter_Grid_2_UV_Scale_Offset; + float2 uv = ((get_uv_by_channel(i, 0) - 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_2_Padding, + cell_pos, cell_uv); + + // Extract char from _Gimmick_Letter_Grid_2_Data_Row_0 et al using cell_pos. + cell_pos.y = (grid_res.y - cell_pos.y) - 1; + float c = lerp( + lerp( + _Gimmick_Letter_Grid_2_Data_Row_0[cell_pos.x], + _Gimmick_Letter_Grid_2_Data_Row_1[cell_pos.x], + cell_pos.y), + lerp( + _Gimmick_Letter_Grid_2_Data_Row_2[cell_pos.x], + _Gimmick_Letter_Grid_2_Data_Row_3[cell_pos.x], + cell_pos.y - 2), + cell_pos.y/2); + c += _Gimmick_Letter_Grid_2_Global_Offset; + + float3 msd = renderInBox(c, uv, cell_uv, _Gimmick_Letter_Grid_2_Texture, font_res).rgb; + float sd = median(msd); + // screenPxRange() + float screen_px_range; + { + float px_range = 2; // determined by msdf-atlas-gen.exe; 2 is default + float texture_res = 512; + // Implementation detail from gen_atlas. + float2 real_cell_size = floor(texture_res / grid_res); + float2 unit_range = px_range / real_cell_size; + float2 screen_tex_size = 1 / fwidth(cell_uv); + screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), 2.0); + } + float screen_px_distance = screen_px_range * (sd - 0.5); + float op = saturate(screen_px_distance + 0.5); + op *= mask; + op = floor(op); + + albedo = lerp(albedo, _Gimmick_Letter_Grid_2_Color, op * in_box); + metallic = lerp(metallic, _Gimmick_Letter_Grid_2_Metallic, op * in_box); + roughness = lerp(roughness, _Gimmick_Letter_Grid_2_Roughness, op * in_box); + gimmick_letter_grid_2_emission = _Gimmick_Letter_Grid_2_Color * _Gimmick_Letter_Grid_2_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 @@ -2511,6 +2573,9 @@ float4 effect(inout v2f i, out float depth) #if defined(_GIMMICK_LETTER_GRID) result.rgb += gimmick_letter_grid_emission; #endif +#if defined(_GIMMICK_LETTER_GRID_2) + result.rgb += gimmick_letter_grid_2_emission; +#endif #if defined(_EXPLODE) && defined(_AUDIOLINK) if (AudioLinkIsAvailable() && _Explode_Phase > 1E-6) { |
