#ifndef __LETTER_GRID_INC #define __LETTER_GRID_INC #include "disinfo.cginc" #include "features.cginc" #include "globals.cginc" #include "interpolators.cginc" #include "math.cginc" #include "texture_utils.cginc" #if defined(_LETTER_GRID) struct LetterGridOutput { float4 albedo; float metallic; float roughness; float3 emission; }; LetterGridOutput LetterGrid(v2f i) { LetterGridOutput output; int2 font_res = int2(round(_Letter_Grid_Tex_Res_X), round(_Letter_Grid_Tex_Res_Y)); int2 grid_res = int2(round(_Letter_Grid_Res_X), round(_Letter_Grid_Res_Y)); float4 scoff = _Letter_Grid_UV_Scale_Offset; float2 base_uv = get_uv_by_channel(i, _Letter_Grid_UV_Channel); float2 uv = ((base_uv - 0.5) - scoff.zw) * scoff.xy + 0.5; int2 cell_pos; float2 cell_uv; // uv within each letter cell bool in_box = getBoxLoc(uv, 0, 1, grid_res, _Letter_Grid_Padding, cell_pos, cell_uv); // Extract char from _Letter_Grid_Data_Row_0 et al using cell_pos. cell_pos.y = (grid_res.y - cell_pos.y) - 1; float c = lerp( lerp( _Letter_Grid_Data_Row_0[cell_pos.x], _Letter_Grid_Data_Row_1[cell_pos.x], cell_pos.y), lerp( _Letter_Grid_Data_Row_2[cell_pos.x], _Letter_Grid_Data_Row_3[cell_pos.x], cell_pos.y - 2), cell_pos.y/2); c += _Letter_Grid_Global_Offset; #if defined(_LETTER_GRID_ANIMATE) // Sweep cells left-to-right, then top-to-bottom. One full sweep takes // _Letter_Grid_Animate_Speed seconds, so each slot updates once per sweep. int slot_count = max(grid_res.x * grid_res.y, 1); int slot_index = cell_pos.y * grid_res.x + cell_pos.x; int sweep_step = (int)floor((_Time.y * _Letter_Grid_Animate_Speed) * slot_count); int slot_change_count = (sweep_step + slot_count - slot_index) / slot_count; int glyph_count = max(font_res.x * font_res.y, 1); int base_char = (int)round(c); uint rand_u = hash31_u32(uint3( (uint)slot_index, (uint)slot_change_count, asuint(base_char))); c = (float)(rand_u % glyph_count); #endif float3 msd = renderInBox(c, uv, cell_uv, _Letter_Grid_Texture, font_res).rgb; float sd = median(msd); float screen_px_range; { float2 tex_size = float2(_Letter_Grid_Texture_TexelSize.zw); float2 glyph_tex_size = tex_size / float2(font_res); float2 unit_range = _Letter_Grid_Screen_Px_Range / glyph_tex_size; float2 screen_tex_size = 1.0 / max(fwidth(cell_uv), float2(1e-4, 1e-4)); screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), _Letter_Grid_Min_Screen_Px_Range); } float screen_px_distance = screen_px_range * (sd - _Letter_Grid_Alpha_Threshold); float edge_softness = max(exp2((_Letter_Grid_Blurriness - 0.5) * 2.0), 1e-4); float op = saturate(screen_px_distance / edge_softness + 0.5); // Apply blending to output output.albedo = float4(_Letter_Grid_Color.rgb, op * in_box); output.metallic = _Letter_Grid_Metallic; output.roughness = _Letter_Grid_Roughness; output.emission = _Letter_Grid_Color.rgb * _Letter_Grid_Emission; return output; } #endif // _LETTER_GRID #endif // __LETTER_GRID_INC