yum-archive/2ner
A toon shader for Unity's BIRP.
git clone https://git.yummers.dev/yum-archive/2ner
4885fb4
master
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