yum/3ner

A toon shader for Unity's BIRP.

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

yumPull in letter grid gimmick from 2nere19bf2d

master
2.6 KiB98 linesraw
1#include "globals.cginc"
2
3#ifndef __DISINFO_INC
4#define __DISINFO_INC
5
6/*
7 * A small font rendering library.
8 *
9 * Sample usage:
10 *
11 * fixed4 frag(v2f i) : SV_Target
12 * {
13 *   float2 uv = i.uv;
14 *   int2 cell_pos;
15 *   float2 cell_uv;
16 *   float2 res = int2(4, 4);
17 *   if (!getBoxLoc(uv, 0.1, 0.9, res, cell_pos, cell_uv)) {
18 *     return float4(0, 0, 0, 1);
19 *   }
20 *   float2 duv = float2(ddx(i.uv.x), ddy(i.uv.y)) / 4;
21 *   float4 font_color = renderInBox(67, cell_uv, duv);
22 *
23 *   return font_color;
24 * }
25 */
26
27// Returns false if `uv` does not fall within `bounds`.
28bool remapUVSmaller(float2 uv, float2 bottom_left, float2 top_right,
29    out float2 uvr) {
30  if (!(uv.x > bottom_left.x && uv.x < top_right.x &&
31      uv.y > bottom_left.y && uv.y < top_right.y)) {
32    return false;
33  }
34
35  uvr = uv - bottom_left;
36  uvr = uvr / (top_right - bottom_left);
37
38  return true;
39}
40
41// bounds: the left/right/top/bottom bounds of the inner UV region,
42//     respectively.
43// Always returns true.
44bool remapUVBigger(float2 uv, float2 bottom_left, float2 top_right,
45    out float2 uvr) {
46  uvr = uv * (top_right - bottom_left) + bottom_left;
47
48  return true;
49}
50
51bool getBoxLoc(float2 uv, float2 bottom_left, float2 top_right,
52    int2 res, float padding, out int2 cell_pos, out float2 cell_uv)
53{
54  float2 box_uv;
55  if (!remapUVSmaller(uv, bottom_left, top_right, box_uv)) {
56    return false;
57  }
58
59  // The integer index of the cell pointed to by `uv`, on the interval
60  // [0, res.x - 1] * [0, res.y - 1]
61  cell_pos = fmod(floor(box_uv * res), res);
62
63  float2 box_sz = 1.0 / float2(res);
64  float2 cell_bot_left = (cell_pos - padding) * box_sz;
65  float2 cell_top_right = (cell_pos + 1 + padding) * box_sz;
66  if (!remapUVSmaller(box_uv, cell_bot_left, cell_top_right, cell_uv)) {
67    // This should never happen Clueless
68    return true;
69  }
70
71  return true;
72}
73
74// `c` is a character encoded as ASCII.
75float4 renderInBox(int c, float2 uv, float2 cell_uv, texture2D font, int2 font_res)
76{
77  int letter_idx = c;
78  int2 letter_pos = int2(
79      font_res.x - (letter_idx % font_res.x),
80      letter_idx / font_res.x);
81  letter_pos.x = font_res.x - letter_pos.x;
82  letter_pos.y = (font_res.y - 1) - letter_pos.y;
83  float2 letter_box_sz = 1.0 / float2(font_res);
84  float2 letter_bot_left = letter_pos * letter_box_sz;
85  float2 letter_top_right = (letter_pos + 1) * letter_box_sz;
86  float2 letter_uv;
87  remapUVBigger(cell_uv, letter_bot_left, letter_top_right, letter_uv);
88
89#if 0
90  float4 font_color = font.Sample(linear_clamp_s, letter_uv);
91#else
92  float4 font_color = font.SampleLevel(linear_repeat_s, letter_uv, 0);
93#endif
94  return font_color;
95}
96
97#endif  // __DISINFO_INC
98