yum-archive/2ner

A toon shader for Unity's BIRP.

git clone https://git.yummers.dev/yum-archive/2ner

yumRemove worldPos interpolator4885fb4

master
7.0 KiB210 linesraw
1#ifndef __TESSELLATION_INC
2#define __TESSELLATION_INC
3
4#include "globals.cginc"
5#include "interpolators.cginc"
6#include "math.cginc"
7#include "shatter_wave.cginc"
8#include "trochoid.cginc"
9
10//ifex _Tessellation_Enabled==0
11
12struct tess_factors {
13  float edge[3] : SV_TessFactor;
14  float inside : SV_InsideTessFactor;
15};
16
17bool cullPatch(float4 p0, float4 p1, float4 p2, float bias) {
18  return
19    (p0.x < -p0.w - bias && p1.x < -p1.w - bias && p2.x < -p2.w - bias) ||
20    (p0.x > p0.w + bias && p1.x > p1.w + bias && p2.x > p2.w + bias) ||
21    (p0.y < -p0.w - bias && p1.y < -p1.w - bias && p2.y < -p2.w - bias) ||
22    (p0.y > p0.w + bias && p1.y > p1.w + bias && p2.y > p2.w + bias) ||
23    (p0.z < -p0.w - bias && p1.z < -p1.w - bias && p2.z < -p2.w - bias) ||
24    (p0.z > p0.w + bias && p1.z > p1.w + bias && p2.z > p2.w + bias);
25}
26
27#if defined(_TESSELLATION_HEIGHTMAP_0) || defined(_TESSELLATION_HEIGHTMAP_1) || defined(_TESSELLATION_HEIGHTMAP_2) || defined(_TESSELLATION_HEIGHTMAP_3) || defined(_TESSELLATION_HEIGHTMAP_4) || defined(_TESSELLATION_HEIGHTMAP_5) || defined(_TESSELLATION_HEIGHTMAP_6) || defined(_TESSELLATION_HEIGHTMAP_7)
28#define _TESSELLATION_HEIGHTMAP
29#endif
30
31float4 applyHeightmap(float4 objPos, float2 uv, float3 normal, float3 tangent) {
32#if defined(_TESSELLATION) && defined(_TESSELLATION_HEIGHTMAP)
33  float3 height = 0;
34#if defined(_TESSELLATION_HEIGHTMAP_0)
35  float3 heightmap_0_sample = _Tessellation_Heightmap_0.SampleLevel(bilinear_repeat_s,
36      uv * _Tessellation_Heightmap_0_ST.xy, 0);
37  height += heightmap_0_sample * _Tessellation_Heightmap_0_Scale + _Tessellation_Heightmap_0_Offset;
38#endif
39#if defined(_TESSELLATION_HEIGHTMAP_1)
40  float3 heightmap_1_sample = _Tessellation_Heightmap_1.SampleLevel(bilinear_repeat_s,
41      uv * _Tessellation_Heightmap_1_ST.xy, 0);
42  height += heightmap_1_sample * _Tessellation_Heightmap_1_Scale + _Tessellation_Heightmap_1_Offset;
43#endif
44#if defined(_TESSELLATION_HEIGHTMAP_2)
45  float3 heightmap_2_sample = _Tessellation_Heightmap_2.SampleLevel(bilinear_repeat_s,
46      uv * _Tessellation_Heightmap_2_ST.xy, 0);
47  height += heightmap_2_sample * _Tessellation_Heightmap_2_Scale + _Tessellation_Heightmap_2_Offset;
48#endif
49#if defined(_TESSELLATION_HEIGHTMAP_3)
50  float3 heightmap_3_sample = _Tessellation_Heightmap_3.SampleLevel(bilinear_repeat_s,
51      uv * _Tessellation_Heightmap_3_ST.xy, 0);
52  height += heightmap_3_sample * _Tessellation_Heightmap_3_Scale + _Tessellation_Heightmap_3_Offset;
53#endif
54#if defined(_TESSELLATION_HEIGHTMAP_4)
55  float3 heightmap_4_sample = _Tessellation_Heightmap_4.SampleLevel(bilinear_repeat_s,
56      uv * _Tessellation_Heightmap_4_ST.xy, 0);
57  height += heightmap_4_sample * _Tessellation_Heightmap_4_Scale + _Tessellation_Heightmap_4_Offset;
58#endif
59#if defined(_TESSELLATION_HEIGHTMAP_5)
60  float3 heightmap_5_sample = _Tessellation_Heightmap_5.SampleLevel(bilinear_repeat_s,
61      uv * _Tessellation_Heightmap_5_ST.xy, 0);
62  height += heightmap_5_sample * _Tessellation_Heightmap_5_Scale + _Tessellation_Heightmap_5_Offset;
63#endif
64#if defined(_TESSELLATION_HEIGHTMAP_6)
65  float3 heightmap_6_sample = _Tessellation_Heightmap_6.SampleLevel(bilinear_repeat_s,
66      uv * _Tessellation_Heightmap_6_ST.xy, 0);
67  height += heightmap_6_sample * _Tessellation_Heightmap_6_Scale + _Tessellation_Heightmap_6_Offset;
68#endif
69#if defined(_TESSELLATION_HEIGHTMAP_7)
70  float3 heightmap_7_sample = _Tessellation_Heightmap_7.SampleLevel(bilinear_repeat_s,
71      uv * _Tessellation_Heightmap_7_ST.xy, 0);
72  height += heightmap_7_sample * _Tessellation_Heightmap_7_Scale + _Tessellation_Heightmap_7_Offset;
73#endif
74
75#if defined(_TESSELLATION_HEIGHTMAP_WORLD_SPACE)
76  objPos.xyz += mul(unity_WorldToObject, height).xyz;
77#else
78#if defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL)
79  float3 binormal = cross(tangent, normal);
80  float3 heightmap_direction = normalize(
81    normalize(normal) * _Tessellation_Heightmap_Direction_Control_Vector.x +
82    normalize(tangent) * _Tessellation_Heightmap_Direction_Control_Vector.y +
83    normalize(binormal) * _Tessellation_Heightmap_Direction_Control_Vector.z
84  );
85#else
86  float3 heightmap_direction = normal;
87#endif
88  objPos.xyz += heightmap_direction * height;
89#endif
90#endif  // _TESSELLATION_HEIGHTMAP
91  return objPos;
92}
93
94tess_factors patch_constant(InputPatch<v2f, 3> patch) {
95  tess_factors f;
96
97#if defined(_TESSELLATION)
98  float4 p0 = patch[0].pos;
99  float4 p1 = patch[1].pos;
100  float4 p2 = patch[2].pos;
101
102  [branch]
103  if (cullPatch(p0, p1, p2, _Tessellation_Frustum_Culling_Bias)) {
104    f.edge[0] = 1;
105    f.edge[1] = 1;
106    f.edge[2] = 1;
107    f.inside = 1;
108    return f;
109  }
110
111  // https://catlikecoding.com/unity/tutorials/advanced-rendering/tessellation/
112  float2 p0_clip = p0.xy / p0.w;
113  float2 p1_clip = p1.xy / p1.w;
114  float2 p2_clip = p2.xy / p2.w;
115
116  float l01 = distance(p0_clip, p1_clip);
117  float l12 = distance(p1_clip, p2_clip);
118  float l20 = distance(p2_clip, p0_clip);
119
120  float edgeLength = _Tessellation_Factor;
121
122  float edge01 = l01 * edgeLength;
123  float edge12 = l12 * edgeLength;
124  float edge20 = l20 * edgeLength;
125
126  float k = _Tessellation_Falloff_Factor;
127  f.edge[0] = min(_Tessellation_Factor, k * edge12);
128  f.edge[1] = min(_Tessellation_Factor, k * edge20);
129  f.edge[2] = min(_Tessellation_Factor, k * edge01);
130
131  f.inside = (f.edge[0] + f.edge[1] + f.edge[2]) * 0.333333f;
132#else
133  f.edge[0] = 1;
134  f.edge[1] = 1;
135  f.edge[2] = 1;
136  f.inside = 1;
137#endif
138
139  return f;
140}
141
142[UNITY_domain("tri")]
143[UNITY_outputcontrolpoints(3)]
144[UNITY_outputtopology("triangle_cw")]
145[UNITY_partitioning("fractional_odd")]
146[UNITY_patchconstantfunc("patch_constant")]
147v2f hull(
148    InputPatch<v2f, 3> patch,
149    uint id : SV_OutputControlPointID)
150{
151  return patch[id];
152}
153
154[UNITY_domain("tri")]
155v2f domain(
156    tess_factors factors,
157    OutputPatch<v2f, 3> patch,
158    float3 baryc : SV_DomainLocation)
159{
160  v2f o = (v2f) 0;
161#define DOMAIN_INTERP(fieldName) \
162  patch[0].fieldName * baryc.x + \
163  patch[1].fieldName * baryc.y + \
164  patch[2].fieldName * baryc.z
165#if defined(_TESSELLATION)
166  o.objPos   = DOMAIN_INTERP(tpos);
167#else
168  o.objPos   = DOMAIN_INTERP(objPos);
169#endif
170  o.normal   = DOMAIN_INTERP(normal);
171  o.tangent  = DOMAIN_INTERP(tangent);
172  o.uv01     = DOMAIN_INTERP(uv01);
173  o.uv23     = DOMAIN_INTERP(uv23);
174  o.vertexLight     = DOMAIN_INTERP(vertexLight);
175#if defined(V2F_COLOR)
176  o.color     = DOMAIN_INTERP(color);
177#endif
178#if defined(V2F_ORIG_POS)
179  o.orig_pos = DOMAIN_INTERP(orig_pos);
180#endif
181
182#if defined(_TESSELLATION) && defined(_TROCHOID)
183  o.objPos.xyz = trochoid_map(o.orig_pos.xyz);
184#endif
185
186#if defined(_TESSELLATION) && defined(_SHATTER_WAVE)
187#if defined(OUTLINE_PASS)
188  shatterWaveVert(o.objPos.xyz, -o.normal, o.tangent);
189#else
190  shatterWaveVert(o.objPos.xyz, o.normal, o.tangent);
191#endif
192#endif
193
194  o.objPos = applyHeightmap(o.objPos, o.uv01.xy, o.normal, o.tangent);
195
196  o.pos      = UnityObjectToClipPos(o.objPos);
197
198  //UNITY_TRANSFER_LIGHTING(o, v);
199  UNITY_TRANSFER_INSTANCE_ID(patch[0], o);
200  UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
201#if defined(SHADOW_CASTER_PASS)
202	TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
203#endif
204  return o;
205}
206
207//endex
208
209#endif  // __TESSELLATION_INC
210