diff options
| author | yum <yum.food.vr@gmail.com> | 2024-12-01 18:00:57 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2024-12-01 18:00:57 -0800 |
| commit | a116fda8c034ab13bf8b1cf1b4cbdc4ba9eba6b0 (patch) | |
| tree | 7e6bcd3a9ea57694ce607ad702077ee254b1a50d | |
| parent | 3089bd2ea6a3952e3ea0f31d8fc5eca1864cefab (diff) | |
Add smoothness control to msdf font renderer
Also rescale atlas so we can use texture sizes that are not a perfect
multiple of the grid size.
| -rw-r--r-- | Editor/tooner.cs | 7 | ||||
| -rw-r--r-- | Third_Party/gen_atlas | 24 | ||||
| -rw-r--r-- | disinfo.cginc | 2 | ||||
| -rw-r--r-- | globals.cginc | 4 | ||||
| -rw-r--r-- | tooner.shader | 3 | ||||
| -rw-r--r-- | tooner_lighting.cginc | 36 |
6 files changed, 59 insertions, 17 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs index fca422b..9f444d4 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -2045,6 +2045,13 @@ public class ToonerGUI : ShaderGUI { bc = FindProperty("_Gimmick_Letter_Grid_2_Global_Offset"); FloatProperty(bc, "Global offset"); + bc = FindProperty("_Gimmick_Letter_Grid_2_Screen_Px_Range"); + FloatProperty(bc, "Screen px range (from msdfgen)"); + bc = FindProperty("_Gimmick_Letter_Grid_2_Min_Screen_Px_Range"); + FloatProperty(bc, "Minimum screen px range"); + bc = FindProperty("_Gimmick_Letter_Grid_2_Blurriness"); + FloatProperty(bc, "Blurriness"); + EditorGUI.indentLevel -= 1; } diff --git a/Third_Party/gen_atlas b/Third_Party/gen_atlas index b880ac8..b3a8eff 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): @@ -35,16 +35,17 @@ def generate_atlas(font_path, resolution, draw_grid=False): "-type", "msdf", "-format", "png", "-imageout", "atlas.png", - "-size", "28", - "-pxrange", "2", + "-size", "72", + "-pxrange", "5", "-dimensions", str(resolution), str(resolution), "-chars", chars_str, "-uniformgrid", "-uniformcols", str(grid_size), "-uniformcell", str(cell_size), str(cell_size), -# "-uniformorigin", "on", - "-errorcorrection", "auto", - "-scanline" + "-errorcorrection", "auto-full", + "-scanline", + #"-angle", "15d", + "-edgecoloring", "distance" ] try: @@ -57,6 +58,7 @@ def generate_atlas(font_path, resolution, draw_grid=False): print(result.stdout) # Rearrange the atlas to include gaps for non-printable characters + print("Rearranging atlas...") rearrange_atlas(resolution, cell_size, cell_size, draw_grid) return True except subprocess.CalledProcessError as e: @@ -91,7 +93,7 @@ def rearrange_atlas(resolution, cell_width, cell_height, draw_grid=False): grid_size = calculate_grid_size(CHAR_RANGES) cell_size = resolution // grid_size - # Track current position in the source atlas + # Track current position in the source atlas source_index = 0 # Process each character range @@ -118,9 +120,15 @@ def rearrange_atlas(resolution, cell_width, cell_height, draw_grid=False): # Draw the grid lines only if requested if draw_grid: draw_grid_lines(new_atlas, resolution) + + # Calculate actual used dimensions + used_resolution = cell_size * grid_size + # Crop to used dimensions and resize back to requested resolution + used_atlas = new_atlas.crop((0, 0, used_resolution, used_resolution)) + final_atlas = used_atlas.resize((resolution, resolution), Image.LANCZOS) # Save the rearranged atlas, overwriting the original - new_atlas.save("atlas.png") + final_atlas.save("atlas.png") print("Atlas rearranged successfully!") def main(): diff --git a/disinfo.cginc b/disinfo.cginc index 8a6a162..faa9489 100644 --- a/disinfo.cginc +++ b/disinfo.cginc @@ -89,7 +89,7 @@ float4 renderInBox(int c, float2 uv, float2 cell_uv, texture2D font, int2 font_r #if 0 float4 font_color = font.Sample(linear_clamp_s, letter_uv); #else - float4 font_color = font.SampleLevel(linear_clamp_s, letter_uv, 0); + float4 font_color = font.SampleLevel(linear_repeat_s, letter_uv, 0); #endif return font_color; } diff --git a/globals.cginc b/globals.cginc index 8432b8e..09bb36b 100644 --- a/globals.cginc +++ b/globals.cginc @@ -741,6 +741,7 @@ float _Gimmick_Letter_Grid_Rim_Lighting_Mask_Invert; #if defined(_GIMMICK_LETTER_GRID_2) texture2D _Gimmick_Letter_Grid_2_Texture; +float4 _Gimmick_Letter_Grid_2_Texture_TexelSize; float _Gimmick_Letter_Grid_2_Res_X; float _Gimmick_Letter_Grid_2_Res_Y; float4 _Gimmick_Letter_Grid_2_Data_Row_0; @@ -757,6 +758,9 @@ 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; +float _Gimmick_Letter_Grid_2_Screen_Px_Range; +float _Gimmick_Letter_Grid_2_Min_Screen_Px_Range; +float _Gimmick_Letter_Grid_2_Blurriness; #endif #if defined(_GIMMICK_AL_CHROMA_00) diff --git a/tooner.shader b/tooner.shader index f2afa77..abbf57f 100644 --- a/tooner.shader +++ b/tooner.shader @@ -273,6 +273,9 @@ Shader "yum_food/tooner" _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 + _Gimmick_Letter_Grid_2_Screen_Px_Range("Screen px range (from msdfgen)", Float) = 10 + _Gimmick_Letter_Grid_2_Min_Screen_Px_Range("Minimum screen px range", Float) = 1 + _Gimmick_Letter_Grid_2_Blurriness("Blurriness", Float) = 0.5 [MaterialToggle] _Explode_Toggle("Explode toggle", Float) = 0 _Explode_Phase("Explode phase", Range(0, 1)) = 0 diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc index 92bd069..9b0388f 100644 --- a/tooner_lighting.cginc +++ b/tooner_lighting.cginc @@ -2351,18 +2351,38 @@ float4 effect(inout v2f i, out float depth) // 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 tex_size = float2(_Gimmick_Letter_Grid_2_Texture_TexelSize.zw); + float2 real_cell_size = floor(tex_size / grid_res); // size of cell in texels + float2 unit_range = _Gimmick_Letter_Grid_2_Screen_Px_Range / real_cell_size; + // fwidth(x) = abs(abs(ddx(x)) + abs(ddy(x))) + // 1 / fwidth(cell_uv) + // = 1 / abs(abs(ddx(cell_uv)) + abs(ddy(cell_uv))) + // This is just the manhattan length of the triangle with edges + // ddx(cell_uv.x) and ddy(cell_uv.x). + // In other words, an approximation of the gradient of cell_uv.x. + #if 1 + // fwidth is an approximation showing how much cell_uv changes per pixel. + // By inverting it, we get an approximation of how many pixels are + // spanned by the whole texture, if it was rendered with this pixel's + // properties. float2 screen_tex_size = 1 / fwidth(cell_uv); - screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), 2.0); + #else + float2 cell_uv_x = float2(ddx(cell_uv.x), ddy(cell_uv.x)); + float2 cell_uv_y = float2(ddx(cell_uv.y), ddy(cell_uv.y)); + float2 screen_tex_size = float2( + 1 / length(cell_uv_x), + 1 / length(cell_uv_y) + ); + #endif + screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), _Gimmick_Letter_Grid_2_Min_Screen_Px_Range); } float screen_px_distance = screen_px_range * (sd - 0.5); - float op = saturate(screen_px_distance + 0.5); + + // Calculate smoothstep range based on screen size + float smooth_range = (length(grid_res) / sqrt(screen_px_range)) * _Gimmick_Letter_Grid_2_Blurriness; + float op = smoothstep(-smooth_range, smooth_range, screen_px_distance); op *= mask; - op = floor(op); + //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); |
