yum/3ner

A toon shader for Unity's BIRP.

git clone https://git.yummers.dev/yum/3ner

yumPort ssfd feature from 2ner043de4d

master
3.1 KiB91 linesraw
1#ifndef __LETTER_GRID_INC
2#define __LETTER_GRID_INC
3
4#include "disinfo.cginc"
5#include "features.cginc"
6#include "globals.cginc"
7#include "interpolators.cginc"
8#include "math.cginc"
9#include "texture_utils.cginc"
10
11#if defined(_LETTER_GRID)
12
13struct LetterGridOutput {
14  float4 albedo;
15  float metallic;
16  float roughness;
17  float3 emission;
18};
19
20LetterGridOutput LetterGrid(v2f i) {
21    LetterGridOutput output;
22
23    int2 font_res = int2(round(_Letter_Grid_Tex_Res_X), round(_Letter_Grid_Tex_Res_Y));
24    int2 grid_res = int2(round(_Letter_Grid_Res_X), round(_Letter_Grid_Res_Y));
25
26    float4 scoff = _Letter_Grid_UV_Scale_Offset;
27    float2 base_uv = get_uv_by_channel(i, _Letter_Grid_UV_Channel);
28    float2 uv = ((base_uv - 0.5) - scoff.zw) * scoff.xy + 0.5;
29
30    int2 cell_pos;
31    float2 cell_uv;  // uv within each letter cell
32    bool in_box = getBoxLoc(uv, 0, 1, grid_res, _Letter_Grid_Padding, cell_pos, cell_uv);
33
34    // Extract char from _Letter_Grid_Data_Row_0 et al using cell_pos.
35    cell_pos.y = (grid_res.y - cell_pos.y) - 1;
36    float c = lerp(
37        lerp(
38        _Letter_Grid_Data_Row_0[cell_pos.x],
39        _Letter_Grid_Data_Row_1[cell_pos.x],
40        cell_pos.y),
41        lerp(
42        _Letter_Grid_Data_Row_2[cell_pos.x],
43        _Letter_Grid_Data_Row_3[cell_pos.x],
44        cell_pos.y - 2),
45        cell_pos.y/2);
46    c += _Letter_Grid_Global_Offset;
47#if defined(_LETTER_GRID_ANIMATE)
48    // Sweep cells left-to-right, then top-to-bottom. One full sweep takes
49    // _Letter_Grid_Animate_Speed seconds, so each slot updates once per sweep.
50    int slot_count = max(grid_res.x * grid_res.y, 1);
51    int slot_index = cell_pos.y * grid_res.x + cell_pos.x;
52    int sweep_step = (int)floor((_Time.y * _Letter_Grid_Animate_Speed) * slot_count);
53    int slot_change_count = (sweep_step + slot_count - slot_index) / slot_count;
54
55    int glyph_count = max(font_res.x * font_res.y, 1);
56    int base_char = (int)round(c);
57    uint rand_u = hash31_u32(uint3(
58        (uint)slot_index,
59        (uint)slot_change_count,
60        asuint(base_char)));
61    c = (float)(rand_u % glyph_count);
62#endif
63
64    float3 msd = renderInBox(c, uv, cell_uv, _Letter_Grid_Texture, font_res).rgb;
65    float sd = median(msd);
66
67    float screen_px_range;
68    {
69        float2 tex_size = float2(_Letter_Grid_Texture_TexelSize.zw);
70        float2 glyph_tex_size = tex_size / float2(font_res);
71        float2 unit_range = _Letter_Grid_Screen_Px_Range / glyph_tex_size;
72        float2 screen_tex_size = 1.0 / max(fwidth(cell_uv), float2(1e-4, 1e-4));
73        screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), _Letter_Grid_Min_Screen_Px_Range);
74    }
75
76    float screen_px_distance = screen_px_range * (sd - _Letter_Grid_Alpha_Threshold);
77    float edge_softness = max(exp2((_Letter_Grid_Blurriness - 0.5) * 2.0), 1e-4);
78    float op = saturate(screen_px_distance / edge_softness + 0.5);
79
80    // Apply blending to output
81    output.albedo = float4(_Letter_Grid_Color.rgb, op * in_box);
82    output.metallic = _Letter_Grid_Metallic;
83    output.roughness = _Letter_Grid_Roughness;
84    output.emission = _Letter_Grid_Color.rgb * _Letter_Grid_Emission;
85
86    return output;
87}
88
89#endif  // _LETTER_GRID
90
91#endif  // __LETTER_GRID_INC