yum-archive/Tooner
A toon shader for Unity's BIRP.
git clone https://git.yummers.dev/yum-archive/Tooner
9b52e08
master
1#include "UnityCG.cginc" 2#include "AutoLight.cginc" 3#include "UnityPBSLighting.cginc" 4 5#include "audiolink.cginc" 6#include "aurora.cginc" 7#include "clones.cginc" 8#include "cnlohr.cginc" 9#include "disinfo.cginc" 10#include "downstairs_02.cginc" 11#include "eyes.cginc" 12#include "fog.cginc" 13#include "gerstner.cginc" 14#include "globals.cginc" 15#include "halos.cginc" 16#include "interpolators.cginc" 17#include "iq_sdf.cginc" 18#include "macros.cginc" 19#include "math.cginc" 20#include "motion.cginc" 21#include "oklab.cginc" 22#include "pbr.cginc" 23#include "pbr_overlay.cginc" 24#include "poi.cginc" 25#include "shear_math.cginc" 26#include "tone.cginc" 27#include "tooner_scroll.cginc" 28#include "trochoid_math.cginc" 29#include "zwrite_abomination.cginc" 30 31#ifndef TOONER_LIGHTING 32#define TOONER_LIGHTING 33 34float3 Shade4PointLightsWrapped( 35 float4 lightPosX, float4 lightPosY, float4 lightPosZ, 36 float3 lightColor0, float3 lightColor1, float3 lightColor2, float3 lightColor3, 37 float4 lightAttenSq, 38 float3 pos, float3 normal, 39 float wrapFactor) 40{ 41 float4 toLightX = lightPosX - pos.x; 42 float4 toLightY = lightPosY - pos.y; 43 float4 toLightZ = lightPosZ - pos.z; 44 45 float4 lengthSq = 0; 46 lengthSq += toLightX * toLightX; 47 lengthSq += toLightY * toLightY; 48 lengthSq += toLightZ * toLightZ; 49 50 float4 ndotl = 0; 51 ndotl += toLightX * normal.x; 52 ndotl += toLightY * normal.y; 53 ndotl += toLightZ * normal.z; 54 55 // Apply wrapped lighting correction 56 float4 wrapped = wrapNoL(ndotl, wrapFactor); 57 float4 corr = rsqrt(lengthSq); 58 ndotl = max(0, wrapped) * corr; 59 60 float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq); 61 float4 diff = ndotl * atten; 62 63 return diff.x * lightColor0 + 64 diff.y * lightColor1 + 65 diff.z * lightColor2 + 66 diff.w * lightColor3; 67} 68 69void getVertexLightColor(inout v2f i) 70{ 71 #if defined(VERTEXLIGHT_ON) 72 float3 view_dir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos); 73 uint normals_mode = round(_Mesh_Normals_Mode); 74 bool flat = (normals_mode == 0); 75 float3 flat_normal = normalize( 76 (1.0 / _Flatten_Mesh_Normals_Str) * i.normal + 77 _Flatten_Mesh_Normals_Str * view_dir); 78 i.vertexLightColor = Shade4PointLightsWrapped( 79 unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, 80 unity_LightColor[0].rgb, 81 unity_LightColor[1].rgb, 82 unity_LightColor[2].rgb, 83 unity_LightColor[3].rgb, 84 unity_4LightAtten0, i.worldPos, flat ? flat_normal : i.normal, 85 1 86 ); 87 #endif 88} 89 90v2f vert(appdata v) 91{ 92#if defined(_DISCARD) 93 if (_Discard_Enable_Dynamic) { 94 return (v2f) (0.0 / 0.0); 95 } 96#endif 97 98 v2f o; 99 100 UNITY_INITIALIZE_OUTPUT(v2f, o); 101 UNITY_SETUP_INSTANCE_ID(v); 102 UNITY_TRANSFER_INSTANCE_ID(v, o); 103 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); 104 //UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(v, o); 105 106#if defined(_GIMMICK_BOX_DISCARD) 107 if (_Gimmick_Box_Discard_Enable_Static) { 108 float3 p = getCenterCamPos(); 109 float3 c1 = _Gimmick_Box_Discard_Corner_1; 110 float3 c2 = _Gimmick_Box_Discard_Corner_2; 111 bool inside = (p.x >= c1.x && p.x <= c2.x && 112 p.y >= c1.y && p.y <= c2.y && 113 p.z >= c1.z && p.z <= c2.z); 114 if (_Gimmick_Box_Discard_Invert && !inside || 115 !_Gimmick_Box_Discard_Invert && inside) { 116 return (v2f) (0.0 / 0.0); 117 } 118 } 119#endif 120 121 o.centerCamPos = getCenterCamPos(); 122 123#if defined(_GIMMICK_QUANTIZE_LOCATION) 124 if (_Gimmick_Quantize_Location_Enable_Dynamic) { 125 float q = _Gimmick_Quantize_Location_Precision / 126 _Gimmick_Quantize_Location_Multiplier; 127#if defined(_GIMMICK_QUANTIZE_LOCATION_AUDIOLINK) 128 // christ what a fucking variable name 129 if (_Gimmick_Quantize_Location_Audiolink_Enable_Dynamic && 130 AudioLinkIsAvailable()) { 131 // x is lowest frequency, w is highest 132 float4 bands = AudioLinkData(ALPASS_AUDIOLINK).xyzw; 133 134 float e = q *= 1 + (bands.x + bands.y * 0.5) * 135 _Gimmick_Quantize_Location_Audiolink_Strength * 0.1; 136 } 137#endif 138 float3 v_new0 = floor(v.vertex * q) / q; 139 float3 d = v_new0 - v.vertex; 140 float3 v_new1 = v.vertex - d; 141 bool flip_dir = (sign(dot(d, v.normal)) != 142 sign(_Gimmick_Quantize_Location_Direction)); 143 float3 v_q = lerp(v_new0, v_new1, flip_dir); 144 float mask = _Gimmick_Quantize_Location_Mask.SampleLevel(linear_repeat_s, 145 v.uv0.xy, /*lod=*/0); 146 v.vertex.xyz = lerp(v.vertex.xyz, v_q, mask); 147 } 148#endif 149 150#if defined(_TROCHOID) 151 { 152 o.objPos_pre_trochoid = v.vertex.xyz; 153 v.vertex.xyz = cart_to_troch_map(v.vertex.xyz); 154 } 155#endif // _TROCHOID 156#if defined(_GIMMICK_ZWRITE_ABOMINATION) 157 v.vertex.xyz *= _Gimmick_ZWrite_Abomination_Vertex_Expansion_Factor; 158#endif 159#if defined(_FACE_ME_WORLD_Y) 160 [branch] 161 if (_FaceMeWorldY_Enable_Dynamic) { 162 float3 object_center = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)); 163 // Get forward axis of object coordinate system, i.e. the orientation of 164 // the hip bone. 165 // Then project it onto the xz plane. 166 float3 forward_axis = mul(unity_ObjectToWorld, float3(0, 0, 1)); 167 forward_axis.y = 0; 168 forward_axis = normalize(forward_axis); 169 float4 worldPos = mul(unity_ObjectToWorld, v.vertex); 170 float3 rd = normalize((worldPos - object_center) - getCenterCamPos()); 171 // We apply a factor of -1 to shift the result forward by a phase shift of pi. 172 float cos_t = -dot(normalize(rd.xz), forward_axis.xz); 173 // We want to get sin(t) using the identity: 174 // || a x b || = || a || || b || sin(t) 175 // For normal vectors, this simplifies to: 176 // || a x b || = sin(t) 177 // The issue is that the norm operator loses the sign. 178 // We can estimate the sign by assuming that `rd` and `forward_axis` are on 179 // the xz plane. 180 // If that's the case, then the cross product is necessarily constrained to 181 // the y axis. 182 float sin_t_sign = sign(cross(rd, forward_axis).y); 183 // Here we use the identity: 184 // sin(t) = sqrt(1 - cos(t)^2) 185 // We simply apply the sign correction `sin_t_sign` to the result. 186 // We then invert it, since the goal is not to amplify the rotation, but 187 // to negate it. 188 // Finally, we add a phase correction to make the abomination face us. 189 float sin_t = -sqrt(1 - cos_t * cos_t) * sin_t_sign; 190 float2x2 face_me_rot = float2x2(cos_t, -sin_t, sin_t, cos_t); 191 float2x2 face_me_rot_inv = float2x2(cos_t, sin_t, -sin_t, cos_t); 192 worldPos.xz = mul(face_me_rot, (worldPos.xz - object_center.xz)) + object_center.xz; 193 v.vertex = mul(unity_WorldToObject, worldPos); 194 float3 world_normal = UnityObjectToWorldNormal(v.normal); 195 world_normal.xz = mul(face_me_rot_inv, world_normal.xz); 196 v.normal = normalize(mul(unity_WorldToObject, world_normal)); 197 } 198#endif 199 200#if !defined(_SCROLL) && defined(_GIMMICK_SPHERIZE_LOCATION) 201 if (_Gimmick_Spherize_Location_Enable_Dynamic) { 202 float3 p = v.vertex.xyz; 203 float r = _Gimmick_Spherize_Location_Radius; 204 float s = _Gimmick_Spherize_Location_Strength; 205 float l = length(p); 206 p *= lerp(1, (r / l), s); 207 v.vertex.xyz = p; 208 } 209#endif 210#if !defined(_SCROLL) && defined(_GIMMICK_SHEAR_LOCATION) 211 if (_Gimmick_Shear_Location_Enable_Dynamic) { 212 float3 p = v.vertex.xyz; 213 float3 sc = _Gimmick_Shear_Location_Strength.xyz; 214 float3x3 shear_matrix = float3x3( 215 sc.x, 0, 0, 216 0, sc.y, 0, 217 0, 0, sc.z); 218 p = mul(shear_matrix, p); 219 v.vertex.xyz = p; 220 } 221#endif 222#if defined(_GIMMICK_GERSTNER_WATER) 223 { 224 GerstnerParams p = getGerstnerParams(); 225 v.vertex.xyz = gerstner_vert(v.vertex.xyz, p); 226 } 227#endif 228 229 o.pos = UnityObjectToClipPos(v.vertex); 230 o.worldPos = mul(unity_ObjectToWorld, v.vertex); 231 o.objPos = v.vertex; 232 o.normal = UnityObjectToWorldNormal(v.normal); 233 o.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); 234 o.uv0 = v.uv0; 235#if !defined(_OPTIMIZE_INTERPOLATORS) 236 o.uv1 = v.uv1; 237#if defined(LIGHTMAP_ON) 238 o.uv2 = v.uv2 * unity_LightmapST.xy + unity_LightmapST.zw; 239 UNITY_TRANSFER_LIGHTING(o, v.uv2); 240#else 241 o.uv2 = v.uv2; 242 o.uv3 = v.uv3; 243 o.uv4 = v.uv4; 244 o.uv5 = v.uv5; 245 o.uv6 = v.uv6; 246 o.uv7 = v.uv7; 247#endif 248#endif // _OPTIMIZE_INTERPOLATORS 249#if defined(_MIRROR_UV_FLIP) 250 if (_Mirror_UV_Flip_Enable_Dynamic) { 251 bool in_mirror = isInMirror(); 252 o.uv0.x = lerp(o.uv0.x, 1 - o.uv0.x, in_mirror); 253#if !defined(_OPTIMIZE_INTERPOLATORS) 254 o.uv1.x = lerp(o.uv1.x, 1 - o.uv1.x, in_mirror); 255 o.uv2.x = lerp(o.uv2.x, 1 - o.uv2.x, in_mirror); 256 o.uv3.x = lerp(o.uv3.x, 1 - o.uv3.x, in_mirror); 257 o.uv4.x = lerp(o.uv4.x, 1 - o.uv4.x, in_mirror); 258 o.uv5.x = lerp(o.uv5.x, 1 - o.uv5.x, in_mirror); 259 o.uv6.x = lerp(o.uv6.x, 1 - o.uv6.x, in_mirror); 260 o.uv7.x = lerp(o.uv7.x, 1 - o.uv7.x, in_mirror); 261#endif 262 } 263#endif 264#if defined(SHADOWS_SCREEN) 265 TRANSFER_SHADOW(o); 266#endif 267 268 float2 suv = o.pos * float2(0.5, 0.5 * _ProjectionParams.x); 269 o.screenPos = TransformStereoScreenSpaceTex(suv + 0.5 * o.pos.w, o.pos.w); 270 o.grabPos = ComputeGrabScreenPos(o.pos); 271 272 getVertexLightColor(o); 273 UNITY_TRANSFER_FOG(o, o.pos); 274 275 return o; 276} 277 278// maxvertexcount == the number of vertices we create 279#if defined(_CLONES) 280[maxvertexcount(21)] 281#else 282[maxvertexcount(3)] 283#endif 284void geom(triangle v2f tri_in[3], 285 uint pid: SV_PrimitiveID, 286 inout TriangleStream<v2f> tri_out) 287{ 288 v2f v0 = tri_in[0]; 289 v2f v1 = tri_in[1]; 290 v2f v2 = tri_in[2]; 291 292 float3 v0_objPos; 293 float3 v1_objPos; 294 float3 v2_objPos; 295 296 const float pid_rand = rand((int) pid); 297 298 float explode_phase = 0; 299#if defined(_EXPLODE) 300 float3 n = normalize(cross(v1.worldPos - v0.worldPos, v2.worldPos - v0.worldPos)); 301 float3 avg_pos; 302 303 float3 n0 = v0.normal; 304 float3 n1 = v1.normal; 305 float3 n2 = v2.normal; 306 307 explode_phase = _Explode_Phase; 308 explode_phase = smoothstep(0, 1, explode_phase); 309 explode_phase *= explode_phase; 310 explode_phase *= 4; 311 312 if (explode_phase > 1E-6) { 313 float3 axis = normalize(float3( 314 rand((int) ((v0.uv0.x + v0.uv0.y) * 1E9)) * 2 - 1, 315 rand((int) ((v1.uv0.x + v1.uv0.y) * 1E9)) * 2 - 1, 316 rand((int) ((v2.uv0.x + v2.uv0.y) * 1E9)) * 2 - 1)); 317 float3 np = BlendNormals(n, axis * explode_phase); 318 319 v0.worldPos += np * explode_phase * pid_rand; 320 v1.worldPos += np * explode_phase * pid_rand; 321 v2.worldPos += np * explode_phase * pid_rand; 322 323 v0_objPos = mul(unity_WorldToObject, float4(v0.worldPos, 1)); 324 v1_objPos = mul(unity_WorldToObject, float4(v1.worldPos, 1)); 325 v2_objPos = mul(unity_WorldToObject, float4(v2.worldPos, 1)); 326 327 float chrono = 0; 328#if defined(_AUDIOLINK) 329 if (AudioLinkIsAvailable()) { 330 chrono = (AudioLinkDecodeDataAsUInt( ALPASS_CHRONOTENSITY + uint2( 2, 1 ) ) % 1000000) / 1000000.0; 331 } 332#endif 333 v0.worldPos += n * explode_phase * sin(_Time[2] + length(v0_objPos)*6 + chrono) * .01 + chrono * n * explode_phase * .2; 334 v1.worldPos += n * explode_phase * sin(_Time[2] + length(v1_objPos)*6 + chrono) * .01 + chrono * n * explode_phase * .2; 335 v2.worldPos += n * explode_phase * sin(_Time[2] + length(v2_objPos)*6 + chrono) * .01 + chrono * n * explode_phase * .2; 336 337 avg_pos = (v0.worldPos + v1.worldPos + v2.worldPos) / 3; 338 v0.worldPos -= avg_pos; 339 v1.worldPos -= avg_pos; 340 v2.worldPos -= avg_pos; 341 342 v0.worldPos *= 1 + 2 * pid_rand; 343 v1.worldPos *= 1 + 2 * pid_rand; 344 v2.worldPos *= 1 + 2 * pid_rand; 345 346 float theta = explode_phase * 3.14159 * 4 + explode_phase * (sin(_Time[1] * (1 + pid_rand) / 2.0 + pid_rand) + cos(_Time[1] * (1 + pid_rand) / 6.1 + pid_rand) * 2) * pid_rand * 2; 347 float4 quat = get_quaternion(axis, theta); 348 v0.worldPos = rotate_vector(v0.worldPos, quat); 349 v1.worldPos = rotate_vector(v1.worldPos, quat); 350 v2.worldPos = rotate_vector(v2.worldPos, quat); 351 352 v0.worldPos += avg_pos; 353 v1.worldPos += avg_pos; 354 v2.worldPos += avg_pos; 355 356 n = normalize(cross(v1.worldPos - v0.worldPos, v2.worldPos - v0.worldPos)); 357 v0.normal = n; 358 v1.normal = n; 359 v2.normal = n; 360 361 // Omit geometry that's too close when exploded. 362 /* 363 if (_Explode_Phase > .05 && length(v0.worldPos - _WorldSpaceCameraPos) < .2) { 364 return; 365 } 366 */ 367 368 v0_objPos = mul(unity_WorldToObject, float4(v0.worldPos, 1)); 369 v1_objPos = mul(unity_WorldToObject, float4(v1.worldPos, 1)); 370 v2_objPos = mul(unity_WorldToObject, float4(v2.worldPos, 1)); 371 372 // Apply transformed worldPos to other coordinate systems. 373 if (_Explode_Phase > 1E-6) { 374 v0.pos = UnityObjectToClipPos(v0_objPos); 375 v1.pos = UnityObjectToClipPos(v1_objPos); 376 v2.pos = UnityObjectToClipPos(v2_objPos); 377 } 378 } 379#endif // __EXPLODE 380#if defined(_SCROLL) 381 { 382 float3 n = normalize(cross(v1.worldPos - v0.worldPos, v2.worldPos - v0.worldPos)); 383 float3 avg_pos = (v0.worldPos + v1.worldPos + v2.worldPos) / 3; 384 v0.worldPos = applyScroll(v0.worldPos, n, avg_pos); 385 v1.worldPos = applyScroll(v1.worldPos, n, avg_pos); 386 v2.worldPos = applyScroll(v2.worldPos, n, avg_pos); 387 388 float3 v0_objPos = mul(unity_WorldToObject, float4(v0.worldPos, 1)); 389 float3 v1_objPos = mul(unity_WorldToObject, float4(v1.worldPos, 1)); 390 float3 v2_objPos = mul(unity_WorldToObject, float4(v2.worldPos, 1)); 391 392#if defined(_GIMMICK_SPHERIZE_LOCATION) 393 if (_Gimmick_Spherize_Location_Enable_Dynamic) { 394 float r = _Gimmick_Spherize_Location_Radius; 395 float s = _Gimmick_Spherize_Location_Strength; 396 float l0 = length(v0_objPos); 397 float l1 = length(v1_objPos); 398 float l2 = length(v2_objPos); 399 v0_objPos *= lerp(1, (r / l0), s); 400 v1_objPos *= lerp(1, (r / l1), s); 401 v2_objPos *= lerp(1, (r / l2), s); 402 } 403#endif 404#if defined(_GIMMICK_SHEAR_LOCATION) 405 if (_Gimmick_Shear_Location_Enable_Dynamic) { 406 v0_objPos = mul(float3x3( 407 _Gimmick_Shear_Location_Strength.x, 0, 0, 408 0, _Gimmick_Shear_Location_Strength.y, 0, 409 0, 0, _Gimmick_Shear_Location_Strength.z), 410 v0_objPos); 411 v1_objPos = mul(float3x3( 412 _Gimmick_Shear_Location_Strength.x, 0, 0, 413 0, _Gimmick_Shear_Location_Strength.y, 0, 414 0, 0, _Gimmick_Shear_Location_Strength.z), 415 v1_objPos); 416 v2_objPos = mul(float3x3( 417 _Gimmick_Shear_Location_Strength.x, 0, 0, 418 0, _Gimmick_Shear_Location_Strength.y, 0, 419 0, 0, _Gimmick_Shear_Location_Strength.z), 420 v2_objPos); 421 } 422#endif 423#if defined(_GIMMICK_SHEAR_LOCATION) || defined(_GIMMICK_SPHERIZE_LOCATION) 424 v0.worldPos.xyz = mul(unity_ObjectToWorld, v0_objPos); 425 v1.worldPos.xyz = mul(unity_ObjectToWorld, v1_objPos); 426 v2.worldPos.xyz = mul(unity_ObjectToWorld, v2_objPos); 427#endif 428 429 v0.pos = UnityObjectToClipPos(v0_objPos); 430 v1.pos = UnityObjectToClipPos(v1_objPos); 431 v2.pos = UnityObjectToClipPos(v2_objPos); 432 } 433#endif 434#if defined(_CLONES) 435 v2f clone_verts[3] = {v0, v1, v2}; 436 add_clones(clone_verts, tri_out, pid_rand, explode_phase); 437#endif // _CLONES 438 439 // Output transformed geometry. 440 tri_out.Append(v0); 441 tri_out.Append(v1); 442 tri_out.Append(v2); 443 tri_out.RestartStrip(); 444} 445 446#if defined(_LENS00) 447 448#endif 449 450 451#if defined(_RORSCHACH) || defined(_GLITTER) || defined(_RIM_LIGHTING0_GLITTER) || defined(_RIM_LIGHTING1_GLITTER) || defined(_RIM_LIGHTING2_GLITTER) || defined(_RIM_LIGHTING3_GLITTER) 452struct RorschachPBR { 453 float4 albedo; 454}; 455float rorschach_map_sdf(float3 p, float2 e, float3 period, float center_randomization, float speed) 456{ 457 float r = _Rorschach_Radius * min(period.x, min(period.y, period.z)); 458 float st = sin(_Time[1] * speed * e.y * e.y + e.x * 3.14159265 * 2); 459 r *= st; 460 float3 o = float3( 461 (e.x - 0.5) * period.x, 462 (e.y - 0.5) * period.y, 463 0); 464 o *= center_randomization; 465 return distance_from_sphere(p + o, r); 466} 467 468float rorschach_map_dr( 469 float3 p, 470 float3 period, 471 float3 count, 472 float center_randomization, 473 float speed, 474 out float3 which 475 ) 476{ 477 which = round(p / period); 478 // Direction to nearest neighboring cell. 479 float3 min_d = p - period * which; 480 float3 o = sign(min_d); 481 482 float d = 1E9; 483 float3 which_tmp = which; 484 for (uint xi = 0; xi < 4; xi++) 485 for (uint yi = 0; yi < 4; yi++) 486 { 487 float3 rid = which + float3(((float) xi) - 1, ((float) yi) - 1, 0) * o; 488 float3 r = p - period * rid; 489 float2 e = float2( 490 rand3(rid / 100.0), 491 rand3(rid / 100.0 + 1)); 492 float cur_d = rorschach_map_sdf(r, e, period, center_randomization, speed); 493 which_tmp = cur_d < d ? rid : which; 494 d = min(d, cur_d); 495 } 496 497 which = which_tmp; 498 return d; 499} 500 501struct RorschachParams { 502 float4 color; 503 float count_x, count_y; 504 float mask; 505 float mask_invert; 506 float quantization; 507 float alpha_cutoff; 508 float center_randomization; 509 float speed; 510}; 511 512RorschachPBR get_rorschach(float2 uv, RorschachParams p) 513{ 514 RorschachPBR result; 515 result.albedo = float4(0, 0, 0, 1); 516 517 float3 ro = float3(uv.x - 0.5, uv.y - 0.5, 0); 518 float3 rd = float3(0, 0, 1); 519 520 float3 which; 521 float3 period = float3(1 / (p.count_x+1), 1 / (p.count_y+1), 1); 522 float3 count = float3(p.count_x, p.count_y, 1); 523 float d = rorschach_map_dr(ro, period, count, p.center_randomization, p.speed, which); 524 525 d *= max(p.count_x + 1, p.count_y + 1); 526 527 d = 1 - d; 528 d = saturate(d); 529 530 // This also quantizes alpha. It isn't exactly intended, but it looks nice. 531 if (p.quantization > 0) { 532 d = round(d * p.quantization) / p.quantization; 533 } 534 535 float4 col = p.color * d; 536 result.albedo = lerp(0, col, d > p.alpha_cutoff); 537 538 float mask = p.mask; 539 mask = p.mask_invert ? 1 - mask : mask; 540 result.albedo *= mask; 541 542 return result; 543} 544 545float get_glitter(float2 uv, float3 worldPos, float3 centerCamPos, 546 float3 normal, float density, float amount, float speed, 547 float mask, float angle, float power) 548{ 549 // To increase amount: make count_{x,y} closer to each other 550 // To increase density: make both numbers larger 551 RorschachParams p; 552 p.color = 1; 553 p.count_x = density * amount; 554 p.count_y = density * rcp(amount); 555 p.mask = mask; 556 p.mask_invert = 0; 557 p.quantization = 1; 558 p.alpha_cutoff = 0.5; 559 p.center_randomization = 1; 560 p.speed = speed; 561 RorschachPBR result = get_rorschach(uv, p); 562 563 float glitter = result.albedo.r; 564 if (angle < 90) { 565 float ndotl = abs(dot(normal, normalize(centerCamPos - worldPos))); 566 float cutoff = cos((angle / 180) * 3.14159); 567 568 glitter *= saturate(pow(ndotl / cutoff, power)); 569 } 570 if (_Glitter_Vector_Mask_Enabled) { 571 float3 mask_vector = _Glitter_Vector_Mask_Vector; 572 float power = _Glitter_Vector_Mask_Power; 573 float invert = _Glitter_Vector_Mask_Invert; 574 float vector_mask = dot(normal, normalize(mask_vector)); 575 // Wrap ndotl 576 vector_mask = (vector_mask + 1) / 2; 577 vector_mask *= vector_mask; 578 vector_mask = max(vector_mask, 0); 579 vector_mask = invert ? 1 - vector_mask : vector_mask; 580 glitter *= pow(vector_mask, power); 581 } 582 583 return glitter; 584 585 /* 586 // A regular divide here causes flickering. The leading guess is that NVIDIA 587 // hardware implements the divide instruction slightly differently on 588 // different cores. 589 precise float idensity = rcp(density); 590 float glitter = rand2(floor(uv * density) * idensity); 591 592 float thresh = 1 - amount / 100; 593 glitter = lerp(0, glitter, glitter > thresh); 594 glitter = (glitter - thresh) / (1 - thresh); 595 596 float b = sin(_Time[2] * speed / 2 + glitter*100); 597 b = speed > 1E-6 ? b : 1; 598 glitter = max(glitter, 0)*max(b, 0); 599 600 glitter *= mask; 601 602 glitter = clamp(glitter, 0, 1); 603 604 if (angle < 90) { 605 float ndotl = abs(dot(normal, normalize(_WorldSpaceCameraPos.xyz - worldPos))); 606 float cutoff = cos((angle / 180) * 3.14159); 607 608 glitter *= saturate(pow(ndotl / cutoff, power)); 609 } 610 611 return glitter; 612 */ 613} 614#endif // _GLITTER 615 616float3 CreateBinormal(float3 normal, float3 tangent, float binormalSign) { 617 return cross(normal, tangent) * (binormalSign * unity_WorldTransformParams.w); 618} 619 620float2 matcap_distortion0(float2 matcap_uv) { 621 float3 qvec = float3(matcap_uv * 2 - 1, 0); 622 float t = _Time[0]; 623 float e = .4; 624 float3 qaxis = normalize(float3(sin(t * 2.3) * e, sin(t * 2.9) * e * 1.2, 1)); 625 float qtheta = t; 626 float4 quat = get_quaternion(qaxis, qtheta); 627 matcap_uv *= ((rotate_vector(qvec, quat) + 1) / 2).xy * 1.3; 628 return matcap_uv; 629} 630 631struct DecalParams { 632 float4 color; 633 texture2D tex; 634 float4 tex_texelsize; 635 float4 tex_st; 636 texture2D roughness_tex; 637 texture2D metallic_tex; 638 float emission_strength; 639 float angle; 640 bool do_roughness; 641 bool do_metallic; 642 float alpha_multiplier; 643 float round_alpha_multiplier; 644 float mask; 645 float uv_select; 646 float tiling_mode; 647 float base_color_mode; 648 float sdf_threshold; 649 float sdf_invert; 650 float sdf_softness; 651 float sdf_px_range; 652 bool domain_warping; 653 texture2D domain_warping_noise; 654 float domain_warping_strength; 655 float domain_warping_speed; 656 float domain_warping_octaves; 657 float domain_warping_scale; 658}; 659 660void applyDecalImpl( 661 inout float4 albedo, 662 inout float3 decal_emission, 663 inout float roughness, 664 inout float metallic, 665 v2f i, 666 DecalParams p) 667{ 668 float2 d0_uv = 669 ((get_uv_by_channel(i, p.uv_select) - 0.5) - p.tex_st.zw) * p.tex_st.xy + 0.5; 670 671 [branch] 672 if (abs(p.angle) > 1E-6) { 673 float theta = p.angle * 2.0 * 3.14159265; 674 float2x2 rot = float2x2( 675 cos(theta), -sin(theta), 676 sin(theta), cos(theta)); 677 d0_uv = mul(rot, d0_uv - 0.5) + 0.5; 678 } 679 d0_uv = (p.tiling_mode == 0) ? saturate(d0_uv) : d0_uv; 680 681 float d0_uv_fwidth = -1; 682 [branch] 683 if (p.domain_warping) { 684 p.domain_warping_octaves = min(p.domain_warping_octaves, 10); 685 for (uint ii = 0; ii < p.domain_warping_octaves; ii++) { 686 float2 warping_speed_vector = normalize(float2(97, 101)); 687 float2 noise = p.domain_warping_noise.SampleLevel(linear_repeat_s, d0_uv * p.domain_warping_scale + _Time[0] * p.domain_warping_speed * warping_speed_vector, 0); 688 d0_uv += noise * p.domain_warping_strength; 689 } 690 d0_uv_fwidth = length(fwidth(d0_uv)); 691 } 692 693 float4 d0_c = 0; 694 [branch] 695 if (p.base_color_mode == 0) { 696 d0_c = p.tex.SampleBias( 697 linear_repeat_s, 698 d0_uv, _Global_Sample_Bias); 699 } else if (p.base_color_mode == 1) { 700 float sd = p.tex.SampleLevel(linear_repeat_s, d0_uv, 0); 701 sd = p.sdf_invert ? 1 - sd : sd; 702 703 float2 screen_tex_size = 1 / fwidth(d0_uv); 704 float2 cell_size_texels = p.tex_texelsize.zw; 705 float2 unit_range = p.sdf_px_range / cell_size_texels; 706 float screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), p.sdf_px_range); 707 708 float screen_px_distance = screen_px_range * (sd - p.sdf_threshold); 709 float2 grid_res = p.tex_st.xy; 710 float smooth_range = (sqrt(2) / sqrt(screen_px_range)) * p.sdf_softness; 711 float op = smoothstep(-smooth_range, smooth_range, screen_px_distance); 712 d0_c = saturate(op); 713 // TODO mip-like filtering? 714 } 715 716 d0_c *= p.color; 717 d0_c.a *= p.round_alpha_multiplier ? round(p.alpha_multiplier) : p.alpha_multiplier; 718 // Manually apply tiling/clamping correction. 719 float d0_in_range = 1; 720 d0_in_range *= d0_uv.x > 0; 721 d0_in_range *= d0_uv.x < 1; 722 d0_in_range *= d0_uv.y > 0; 723 d0_in_range *= d0_uv.y < 1; 724 d0_in_range = (p.tiling_mode == 0) ? d0_in_range : 1; 725 d0_c *= d0_in_range; 726 d0_c *= p.mask; 727 728 albedo.rgb = lerp(albedo.rgb, d0_c.rgb, d0_c.a); 729 albedo.a = max(albedo.a, d0_c.a); 730 decal_emission = d0_c.rgb * p.emission_strength * d0_c.a + decal_emission * (1 - d0_c.a); 731 732 if (p.do_roughness) { 733 float4 d0_r = p.roughness_tex.SampleBias(linear_clamp_s, saturate(d0_uv), _Global_Sample_Bias); 734 d0_r *= d0_in_range; 735 roughness = lerp(roughness, d0_r, d0_r.a); 736 } 737 if (p.do_metallic) { 738 float4 d0_m = p.metallic_tex.SampleBias(linear_clamp_s, saturate(d0_uv), _Global_Sample_Bias); 739 d0_m *= d0_in_range; 740 metallic = lerp(metallic, d0_m, d0_m.a); 741 } 742} 743 744#define DECAL_PARAMS(n) \ 745 MERGE(d,n,_params).do_roughness = false; \ 746 MERGE(d,n,_params).do_metallic = false; \ 747 MERGE(d,n,_params).mask = 1; \ 748 MERGE(d,n,_params).color = MERGE(_Decal,n,_Color); \ 749 MERGE(d,n,_params).tex = MERGE(_Decal,n,_BaseColor); \ 750 MERGE(d,n,_params).tex_texelsize = MERGE(_Decal,n,_BaseColor_TexelSize); \ 751 MERGE(d,n,_params).tex_st = MERGE(_Decal,n,_BaseColor_ST); \ 752 MERGE(d,n,_params).roughness_tex = MERGE(_Decal,n,_Roughness); \ 753 MERGE(d,n,_params).metallic_tex = MERGE(_Decal,n,_Metallic); \ 754 MERGE(d,n,_params).emission_strength = MERGE(_Decal,n,_Emission_Strength); \ 755 MERGE(d,n,_params).angle = MERGE(_Decal,n,_Angle); \ 756 MERGE(d,n,_params).alpha_multiplier = MERGE(_Decal,n,_Alpha_Multiplier); \ 757 MERGE(d,n,_params).round_alpha_multiplier = MERGE(_Decal,n,_Round_Alpha_Multiplier); \ 758 MERGE(d,n,_params).uv_select = MERGE(_Decal,n,_UV_Select); \ 759 MERGE(d,n,_params).tiling_mode = MERGE(_Decal,n,_Tiling_Mode); \ 760 MERGE(d,n,_params).base_color_mode = MERGE(_Decal,n,_BaseColor_Mode); \ 761 MERGE(d,n,_params).sdf_threshold = MERGE(_Decal,n,_SDF_Threshold); \ 762 MERGE(d,n,_params).sdf_invert = MERGE(_Decal,n,_SDF_Invert); \ 763 MERGE(d,n,_params).sdf_softness = MERGE(_Decal,n,_SDF_Softness); \ 764 MERGE(d,n,_params).sdf_px_range = MERGE(_Decal,n,_SDF_Px_Range); \ 765 MERGE(d,n,_params).domain_warping = MERGE(_Decal,n,_Domain_Warping_Enable_Static); \ 766 MERGE(d,n,_params).domain_warping_noise = MERGE(_Decal,n,_Domain_Warping_Noise); \ 767 MERGE(d,n,_params).domain_warping_strength = MERGE(_Decal,n,_Domain_Warping_Strength); \ 768 MERGE(d,n,_params).domain_warping_speed = MERGE(_Decal,n,_Domain_Warping_Speed); \ 769 MERGE(d,n,_params).domain_warping_octaves = MERGE(_Decal,n,_Domain_Warping_Octaves); \ 770 MERGE(d,n,_params).domain_warping_scale = MERGE(_Decal,n,_Domain_Warping_Scale); 771 772#define SETUP_DECAL_BASE(n) \ 773 DecalParams MERGE(d,n,_params); \ 774 DECAL_PARAMS(n) 775 776#define SETUP_DECAL_ROUGHNESS(n) \ 777 MERGE(d,n,_params).do_roughness = true; 778 779#define SETUP_DECAL_METALLIC(n) \ 780 MERGE(d,n,_params).do_metallic = true; 781 782#define SETUP_DECAL_MASK(n) \ 783 MERGE(d,n,_params).mask = MERGE(_Decal,n,_Mask).SampleLevel(linear_repeat_s, \ 784 get_uv_by_channel(i, MERGE(_Decal,n,_UV_Select)), 0); \ 785 MERGE(d,n,_params).mask = MERGE(_Decal,n,_Mask_Invert) ? 1.0 - MERGE(d,n,_params).mask : MERGE(d,n,_params).mask; 786 787#define SETUP_DECAL_FINISH(n) \ 788 applyDecalImpl(albedo, decal_emission, roughness, metallic, i, MERGE(d,n,_params)); 789 790void applyDecal(inout float4 albedo, 791 inout float roughness, 792 inout float metallic, 793 inout float3 decal_emission, 794 v2f i) 795{ 796#if defined(_DECAL0) 797 SETUP_DECAL_BASE(0) 798 #if defined(_DECAL0_ROUGHNESS) 799 SETUP_DECAL_ROUGHNESS(0) 800 #endif 801 #if defined(_DECAL0_METALLIC) 802 SETUP_DECAL_METALLIC(0) 803 #endif 804 #if defined(_DECAL0_MASK) 805 SETUP_DECAL_MASK(0) 806 #endif 807 SETUP_DECAL_FINISH(0) 808#endif 809 810#if defined(_DECAL1) 811 SETUP_DECAL_BASE(1) 812 #if defined(_DECAL1_ROUGHNESS) 813 SETUP_DECAL_ROUGHNESS(1) 814 #endif 815 #if defined(_DECAL1_METALLIC) 816 SETUP_DECAL_METALLIC(1) 817 #endif 818 #if defined(_DECAL1_MASK) 819 SETUP_DECAL_MASK(1) 820 #endif 821 SETUP_DECAL_FINISH(1) 822#endif 823 824#if defined(_DECAL2) 825 SETUP_DECAL_BASE(2) 826 #if defined(_DECAL2_ROUGHNESS) 827 SETUP_DECAL_ROUGHNESS(2) 828 #endif 829 #if defined(_DECAL2_METALLIC) 830 SETUP_DECAL_METALLIC(2) 831 #endif 832 #if defined(_DECAL2_MASK) 833 SETUP_DECAL_MASK(2) 834 #endif 835 SETUP_DECAL_FINISH(2) 836#endif 837 838#if defined(_DECAL3) 839 SETUP_DECAL_BASE(3) 840 #if defined(_DECAL3_ROUGHNESS) 841 SETUP_DECAL_ROUGHNESS(3) 842 #endif 843 #if defined(_DECAL3_METALLIC) 844 SETUP_DECAL_METALLIC(3) 845 #endif 846 #if defined(_DECAL3_MASK) 847 SETUP_DECAL_MASK(3) 848 #endif 849 SETUP_DECAL_FINISH(3) 850#endif 851 852#if defined(_DECAL4) 853 SETUP_DECAL_BASE(4) 854 #if defined(_DECAL4_ROUGHNESS) 855 SETUP_DECAL_ROUGHNESS(4) 856 #endif 857 #if defined(_DECAL4_METALLIC) 858 SETUP_DECAL_METALLIC(4) 859 #endif 860 #if defined(_DECAL4_MASK) 861 SETUP_DECAL_MASK(4) 862 #endif 863 SETUP_DECAL_FINISH(4) 864#endif 865 866#if defined(_DECAL5) 867 SETUP_DECAL_BASE(5) 868 #if defined(_DECAL5_ROUGHNESS) 869 SETUP_DECAL_ROUGHNESS(5) 870 #endif 871 #if defined(_DECAL5_METALLIC) 872 SETUP_DECAL_METALLIC(5) 873 #endif 874 #if defined(_DECAL5_MASK) 875 SETUP_DECAL_MASK(5) 876 #endif 877 SETUP_DECAL_FINISH(5) 878#endif 879 880#if defined(_DECAL6) 881 SETUP_DECAL_BASE(6) 882 #if defined(_DECAL6_ROUGHNESS) 883 SETUP_DECAL_ROUGHNESS(6) 884 #endif 885 #if defined(_DECAL6_METALLIC) 886 SETUP_DECAL_METALLIC(6) 887 #endif 888 #if defined(_DECAL6_MASK) 889 SETUP_DECAL_MASK(6) 890 #endif 891 SETUP_DECAL_FINISH(6) 892#endif 893 894#if defined(_DECAL7) 895 SETUP_DECAL_BASE(7) 896 #if defined(_DECAL7_ROUGHNESS) 897 SETUP_DECAL_ROUGHNESS(7) 898 #endif 899 #if defined(_DECAL7_METALLIC) 900 SETUP_DECAL_METALLIC(7) 901 #endif 902 #if defined(_DECAL7_MASK) 903 SETUP_DECAL_MASK(7) 904 #endif 905 SETUP_DECAL_FINISH(7) 906#endif 907 908#if defined(_DECAL8) 909 SETUP_DECAL_BASE(8) 910 #if defined(_DECAL8_ROUGHNESS) 911 SETUP_DECAL_ROUGHNESS(8) 912 #endif 913 #if defined(_DECAL8_METALLIC) 914 SETUP_DECAL_METALLIC(8) 915 #endif 916 #if defined(_DECAL8_MASK) 917 SETUP_DECAL_MASK(8) 918 #endif 919 SETUP_DECAL_FINISH(8) 920#endif 921 922#if defined(_DECAL9) 923 SETUP_DECAL_BASE(9) 924 #if defined(_DECAL9_ROUGHNESS) 925 SETUP_DECAL_ROUGHNESS(9) 926 #endif 927 #if defined(_DECAL9_METALLIC) 928 SETUP_DECAL_METALLIC(9) 929 #endif 930 #if defined(_DECAL9_MASK) 931 SETUP_DECAL_MASK(9) 932 #endif 933 SETUP_DECAL_FINISH(9) 934#endif 935} 936 937#if defined(_PIXELLATE) 938float2 pixellate_uv(int2 px_res, float2 uv) 939{ 940 return floor(uv * px_res) / px_res; 941} 942 943float4 pixellate_color(int2 px_res, float2 uv, float4 c) 944{ 945 float2 px_intra_uv = fmod(uv * px_res, 1.0); 946 float2 px_extra_uv = floor(uv * px_res) / px_res; 947 948 float2 px_uv = floor(uv * px_res) / px_res; 949 if (px_intra_uv.y > 0.1 && px_intra_uv.y < 0.9) { 950 if (px_intra_uv.x < 0.333) { 951 c.xyz = float3(1, 0, 0); 952 } else if (px_intra_uv.x < 0.666) { 953 c.yxz = float3(1, 0, 0); 954 } else { 955 c.zxy = float3(1, 0, 0); 956 } 957 c *= 3; 958 } else { 959 c = 0; 960 } 961 962 return c; 963} 964#endif 965 966#if defined(_GIMMICK_EPILEPSY_MODE) 967float4 map_color_epilepsy(float4 color) { 968 [branch] 969 if (_Gimmick_Epilepsy_Mode_Enable_Dynamic) { 970 color.rgb = saturate(color.rgb); 971 972 color.rgb = LRGBtoOKLCH(color.rgb); 973 color.rgb[0] = dmin(color.rgb[0], _Gimmick_Epilepsy_Mode_Luminance_Cutoff, _Gimmick_Epilepsy_Mode_Rolloff_Power); 974 color.rgb = OKLCHtoLRGB(color.rgb); 975 976 color.rgb = RGBtoHSV(color.rgb); 977 color.rgb[1] = dmin(color.rgb[1], _Gimmick_Epilepsy_Mode_Saturation_Cutoff, _Gimmick_Epilepsy_Mode_Rolloff_Power); 978 color.rgb = HSVtoRGB(color.rgb); 979 } 980 981 return color; 982} 983#define FILTER_COLOR(color) map_color_epilepsy(color) 984#else 985#define FILTER_COLOR(color) color 986#endif 987 988float ssfd(float2 uv, float scale, float max_fwidth, float2 uv_offset, texture3D noise) 989{ 990 //float uv_fw = fwidth(uv.x) + fwidth(uv.y); 991 // Original paper uses SVD instead of fwidth. 992 float2x2 M = float2x2(ddx(uv), ddy(uv)); 993 float2x2 MtM = mul(transpose(M), M); 994 float trace = MtM[0][0] + MtM[1][1]; 995 float det = determinant(MtM); 996 // Calculate eigenvalues using quadratic formula. 997 float tmp = sqrt(trace * trace - 4 * det); 998 float e1 = (trace + tmp) * 0.5; 999 float e2 = (trace - tmp) * 0.5; 1000 float2 singular_values = sqrt(float2(e1, e2)); 1001 // Logic from original paper: the smaller eigenvalue corresponds to the 1002 // largest amount of stretching, so we use it to determine when to 1003 // subdivide. 1004 float uv_fw = singular_values.y; 1005 uv_fw *= scale; 1006 1007 uint width, height, depth; 1008 noise.GetDimensions(width, height, depth); 1009 float bayer_res = sqrt(depth); 1010 1011 // Suppose max_fwidth is 1. 1012 // uv_fw is 16. That means UV is changing a lot per pixel. That means we want to shrink the scale of the UV. 1013 // Factor is 16. 1014 // log_2(factor) is 4. 1015 // Divide original by 16. 1016 float fw_factor = uv_fw / max_fwidth; 1017 // log_b(x) = log_a(x) / log_a(b) 1018 float fractal_level = log2(fw_factor) / log2(bayer_res); 1019 float fractal_level_floor = floor(fractal_level); 1020 float fractal_remainder = fractal_level - fractal_level_floor; 1021 1022 uv *= pow(bayer_res, -fractal_level_floor); 1023 uv += uv_offset * pow(bayer_res, -fractal_level_floor); 1024 1025 float n_layers = depth; 1026 float not_used_lo = 1/(n_layers*2); 1027 float not_used_hi = 1 - not_used_lo; 1028 1029 float uvw = (not_used_hi - not_used_lo) * (1 - fractal_remainder) + not_used_lo; 1030 1031 float3 uv_3d = float3(uv, uvw); 1032 1033 float dither = noise.SampleLevel(bilinear_repeat_s, uv_3d, 0); 1034 1035 return dither; 1036} 1037 1038float4 effect(inout v2f i, out float depth) 1039{ 1040 ToonerData tdata; 1041 { 1042 float3 full_vec_eye_to_geometry = i.worldPos - _WorldSpaceCameraPos; 1043 float3 world_dir = normalize(i.worldPos - _WorldSpaceCameraPos); 1044 float perspective_divide = 1.0 / i.pos.w; 1045 float perspective_factor = length(full_vec_eye_to_geometry * perspective_divide); 1046 tdata.screen_uv = i.screenPos.xy * perspective_divide; 1047 tdata.screen_uv_round = floor(tdata.screen_uv * _ScreenParams.xy); 1048 } 1049 1050#if defined(EXPERIMENT__CUSTOM_DEPTH) 1051 { 1052 float4 clip_pos = mul(UNITY_MATRIX_VP, float4(i.worldPos, 1.0)); 1053 depth = clip_pos.z / clip_pos.w; 1054 } 1055#else 1056 depth = 0; 1057#endif 1058 1059#if defined(_GIMMICK_UV_DOMAIN_WARPING) 1060 { 1061 float2 uv = i.uv0; 1062 for (uint ii = 0; ii < _Gimmick_UV_Domain_Warping_Octaves; ii++) { 1063 uv += 1064 (_Gimmick_UV_Domain_Warping_Noise.SampleLevel( 1065 linear_repeat_s, 1066 (uv + _Time[0] * _Gimmick_UV_Domain_Warping_Speed) * 1067 _Gimmick_UV_Domain_Warping_Scale, 0) - 0.5) * 1068 _Gimmick_UV_Domain_Warping_Strength; 1069 } 1070 i.uv0 = uv; 1071 } 1072#endif 1073 1074#if defined(_TROCHOID) 1075 { 1076 float3 my_pos; 1077 [branch] 1078 if (_Trochoid_Enable_Fragment_Normals) { 1079 my_pos = cart_to_troch_map(i.objPos_pre_trochoid.xyz); 1080 } else { 1081 my_pos = i.objPos.xyz; 1082 } 1083 float3 tan1 = ddx(my_pos); 1084 float3 tan2 = ddy(my_pos); 1085 float3 normal = cross(tan1, tan2); 1086 i.normal = -UnityObjectToWorldNormal(normal); 1087 i.tangent.xyz = UnityObjectToWorldDir(tan1); 1088 } 1089#endif 1090 1091 const float3 view_dir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos); 1092 const float3 view_dir_c = normalize(i.centerCamPos - i.worldPos); 1093#define VIEW_DIR(center_eye_fix) (center_eye_fix == 1 ? view_dir_c : view_dir) 1094#define CAM_POS(center_eye_fix) (center_eye_fix == 1 ? i.centerCamPos : _WorldSpaceCameraPos.xyz) 1095 1096 // Not necessarily normalized after interpolation. 1097 i.normal = normalize(i.normal); 1098 i.tangent.xyz = normalize(i.tangent.xyz - i.normal * dot(i.tangent.xyz, i.normal)); 1099 //i.tangent.xyz = normalize(i.tangent.xyz); 1100 1101#if defined(_UVSCROLL) 1102 float2 orig_uv = i.uv0; 1103 float uv_scroll_mask = round(_UVScroll_Mask.SampleBias(linear_repeat_s, i.uv0, _Global_Sample_Bias)); 1104 i.uv0 += _Time[0] * float2(_UVScroll_U_Speed, _UVScroll_V_Speed) * uv_scroll_mask; 1105#endif 1106 1107#if defined(_BASECOLOR_MAP) 1108 float4 albedo = _MainTex.SampleBias(GET_SAMPLER_PBR, UV_SCOFF(i, _MainTex_ST, 0), _Global_Sample_Bias); 1109 albedo *= _Color; 1110#else 1111 float4 albedo = _Color; 1112#endif // _BASECOLOR_MAP 1113 1114#if defined(_FRAME_COUNTER) 1115 const float frame = floor(_Frame_Counter); 1116#elif defined(TOONER_AUDIOLINK_AVAILABLE) 1117 const float frame = ((float) AudioLinkData(ALPASS_GENERALVU + int2(1, 0)).x); 1118#else 1119 const float frame = 0; 1120#endif // _FRAME_COUNTER 1121 1122#if defined(_GIMMICK_GERSTNER_WATER) 1123#if defined(_EXPLODE) 1124 1125 if (_Explode_Phase < 1E-6) 1126#endif 1127 { 1128 GerstnerParams p = getGerstnerParams(); 1129 GerstnerFragResult r = gerstner_frag(i.objPos.xyz, p); 1130 i.normal = UnityObjectToWorldNormal(r.normal); 1131 i.tangent = float4(UnityObjectToWorldDir(r.tangent.xyz), r.tangent.w); 1132#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP) 1133 albedo.xyz *= r.color; 1134 albedo.w = 1; 1135#endif 1136 } 1137#endif 1138 1139#if defined(_UVSCROLL) 1140 if (uv_scroll_mask) { 1141 float uv_scroll_alpha = _UVScroll_Alpha.SampleBias(linear_repeat_s, orig_uv, _Global_Sample_Bias); 1142 albedo.a *= uv_scroll_alpha; 1143 } 1144#endif 1145 1146#if defined(_PIXELLATE) 1147 { 1148 const int2 px_res = int2( 1149 _Gimmick_Pixellate_Resolution_U, 1150 _Gimmick_Pixellate_Resolution_V); 1151 1152 float2 uv = pixellate_uv(px_res, i.uv0); 1153 const float2 duv = float2(ddx(i.uv0.x), ddy(i.uv0.y)) / 16; 1154 float4 color = _Gimmick_Pixellate_Effect_Mask.SampleGrad(linear_clamp_s, uv, duv.x, duv.y); 1155 float2 fw = float2(fwidth(i.uv0.x), fwidth(i.uv0.y)); 1156 float fwm = max(fw.x, fw.y); 1157 color.rgb *= albedo; 1158 float4 px_color = pixellate_color(px_res, i.uv0, color); 1159 albedo = lerp(albedo, px_color, pow(0.9, fwm * 100)); 1160 } 1161#endif 1162 1163#if defined(_RORSCHACH) 1164 float4 rorschach_albedo = 0; 1165 if (_Rorschach_Enable_Dynamic) { 1166 RorschachParams p; 1167 p.color = _Rorschach_Color; 1168 p.count_x = _Rorschach_Count_X; 1169 p.count_y = _Rorschach_Count_Y; 1170#if defined(_RORSCHACH_MASK) 1171 p.mask = _Rorschach_Mask.SampleLevel(linear_repeat_s, i.uv0.xy, /*lod=*/0); 1172 p.mask_invert = _Rorschach_Mask_Invert; 1173#else 1174 p.mask = 1; 1175 p.mask_invert = 0; 1176#endif 1177 p.quantization = _Rorschach_Quantization; 1178 p.alpha_cutoff = _Rorschach_Alpha_Cutoff; 1179 p.center_randomization = _Rorschach_Center_Randomization; 1180 p.speed = _Rorschach_Speed; 1181 rorschach_albedo = get_rorschach(i.uv0, p).albedo; 1182 albedo.rgb = rorschach_albedo.rgb * rorschach_albedo.a + albedo.rgb * (1 - rorschach_albedo.a); 1183 albedo.a = saturate(rorschach_albedo.a + albedo.a * (1 - rorschach_albedo.a)); 1184 } 1185#endif 1186 1187 PbrOverlay ov; 1188 getOverlayAlbedoRoughnessMetallic(ov, i); 1189 1190#if defined(_NORMAL_MAP) 1191 // Use UVs to smoothly blend between fully detailed normals when close up and 1192 // flat normals when far away. If we don't do this, then we see moire effects 1193 // on e.g. striped normal maps. 1194 float3 raw_normal = UnpackScaleNormal(_BumpMap.SampleBias(GET_SAMPLER_PBR, 1195 UV_SCOFF(i, _BumpMap_ST, 0), _Global_Sample_Bias), 1196 _Tex_NormalStr); 1197#else 1198 float3 raw_normal = UnpackNormal(float4(0.5, 0.5, 1, 1)); 1199#endif // _NORMAL_MAP 1200 1201 applyOverlayNormal(raw_normal, albedo, ov, i); 1202 1203 float3 binormal = CreateBinormal(i.normal, i.tangent.xyz, i.tangent.w); 1204 // normalize is not necessary; result is already normalized 1205 float3 normal = float3( 1206 raw_normal.x * normalize(i.tangent) + 1207 raw_normal.y * normalize(binormal) + 1208 raw_normal.z * i.normal 1209 ); 1210 1211#if defined(_GIMMICK_HALO_00) 1212 { 1213 Halo00PBR pbr = halo00_march(i.worldPos, i.uv0); 1214 albedo = pbr.albedo; 1215 normal = pbr.normal; 1216 } 1217#endif 1218 1219#if defined(_METALLIC_MAP) 1220 float metallic = _MetallicTex.SampleBias(GET_SAMPLER_PBR, 1221 UV_SCOFF(i, _MetallicTex_ST, 0), _Global_Sample_Bias)[round(_MetallicTexChannel)]; 1222#else 1223 float metallic = _Metallic; 1224#endif 1225#if defined(_ROUGHNESS_MAP) 1226 float roughness = _RoughnessTex.SampleBias(GET_SAMPLER_PBR, 1227 UV_SCOFF(i, _RoughnessTex_ST, 0), _Global_Sample_Bias)[round(_RoughnessTexChannel)]; 1228 if (_Roughness_Invert) { 1229 roughness = 1 - roughness; 1230 } 1231 roughness *= _Roughness; 1232#else 1233 float roughness = _Roughness; 1234#endif 1235 1236#if defined(_GIMMICK_ZWRITE_ABOMINATION) && defined(FORWARD_BASE_PASS) 1237 { 1238 ZWriteAbominationPBR pbr = zwrite_abomination(i); 1239 i.worldPos = pbr.worldPos; 1240 albedo = pbr.albedo; 1241 metallic = pbr.metallic; 1242 roughness = pbr.roughness; 1243 normal = pbr.normal; 1244 depth = pbr.depth; 1245#if 0 1246 float3 c = 1; 1247 c *= saturate(dot(normal, float3(0, -1, 1))); 1248 return float4(c, albedo.a); 1249#endif 1250 } 1251#endif 1252 1253#if defined(VERTEXLIGHT_ON) 1254 float4 vertex_light_color = float4(i.vertexLightColor, 1); 1255#else 1256 float4 vertex_light_color = float4(0, 0, 0, 1); 1257#endif 1258 1259#if defined(_GIMMICK_EYES_00) 1260 { 1261 float3 eyes_normal = 0; 1262 float3 eyes_albedo = eyes00_march(i.uv0, eyes_normal).rgb; 1263 bool is_ray_hit = (eyes_albedo.r > 0 || eyes_albedo.g > 0 || eyes_albedo.b > 0); 1264 if (is_ray_hit) { 1265 float mask = _Gimmick_Eyes00_Effect_Mask.SampleBias(linear_repeat_s, i.uv0, _Global_Sample_Bias); 1266 albedo.rgb = lerp(eyes_albedo * 1.5, albedo.rgb * 20.0, mask); 1267 normal = eyes_normal; 1268 } 1269 } 1270#endif 1271 1272#if defined(_GIMMICK_EYES_01) 1273 { 1274 Eyes01PBR pbr = eyes01_march(i); 1275 albedo = pbr.albedo; 1276 } 1277#endif 1278 1279 1280#if defined(_GIMMICK_EYES_02) 1281 float3 eyes02_normal = i.normal; 1282 bool eyes02_hit = eyes02_march(i.uv0, eyes02_normal); 1283 { 1284 albedo.rgb += eyes02_hit * _Gimmick_Eyes02_Albedo.rgb; 1285 normal = lerp(normal, eyes02_normal, eyes02_hit); 1286 roughness = lerp(roughness, _Gimmick_Eyes02_Roughness, eyes02_hit); 1287 metallic = lerp(metallic, _Gimmick_Eyes02_Metallic, eyes02_hit); 1288 } 1289#endif 1290 1291#if defined(_MATCAP0) || defined(_MATCAP1) || defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1) || defined(_RIM_LIGHTING2) || defined(_RIM_LIGHTING3) 1292 float3 matcap_emission = 0; 1293 float2 matcap_uv; 1294 { 1295 const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(normal, 0))); 1296 const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(view_dir, 0))); 1297 const float3 cam_refl = -reflect(cam_view_dir, cam_normal); 1298 float m = 2.0 * sqrt( 1299 cam_refl.x * cam_refl.x + 1300 cam_refl.y * cam_refl.y + 1301 (cam_refl.z + 1) * (cam_refl.z + 1)); 1302 matcap_uv = cam_refl.xy / m + 0.5; 1303 } 1304 float2 matcap_uv_center; 1305 { 1306 const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(normal, 0))); 1307 const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(view_dir_c, 0))); 1308 const float3 cam_refl = -reflect(cam_view_dir, cam_normal); 1309 float m = 2.0 * sqrt( 1310 cam_refl.x * cam_refl.x + 1311 cam_refl.y * cam_refl.y + 1312 (cam_refl.z + 1) * (cam_refl.z + 1)); 1313 matcap_uv_center = cam_refl.xy / m + 0.5; 1314 } 1315#endif 1316 1317 float4 matcap_overwrite_mask = 0; 1318#if defined(_MATCAP0) || defined(_MATCAP1) 1319 { 1320#if defined(_MATCAP0) 1321 { 1322#if defined(_MATCAP0_MASK) 1323 float4 matcap_mask_raw = _Matcap0_Mask.SampleLevel(linear_repeat_s, 1324 get_uv_by_channel(i, _Matcap0_Mask_UV_Select), 0); 1325 float matcap_mask = matcap_mask_raw.r; 1326 matcap_mask = (bool) round(_Matcap0_Mask_Invert) ? 1 - matcap_mask : matcap_mask; 1327 matcap_mask *= matcap_mask_raw.a; 1328#else 1329 float matcap_mask = 1; 1330#endif 1331#if defined(_MATCAP0_MASK2) 1332 { 1333 float4 matcap_mask2_raw = _Matcap0_Mask2.SampleLevel(linear_repeat_s, 1334 get_uv_by_channel(i, _Matcap0_Mask2_UV_Select), 0); 1335 float matcap_mask2 = matcap_mask2_raw.r; 1336 matcap_mask2 = _Matcap0_Mask2_Invert_Colors ? 1 - matcap_mask2 : matcap_mask2; 1337 matcap_mask2 *= _Matcap0_Mask2_Invert_Alpha ? 1 - matcap_mask2_raw.a : matcap_mask2_raw.a; 1338 matcap_mask *= matcap_mask2; 1339 } 1340#endif 1341#if defined(_MATCAP0_NORMAL) 1342 float3 matcap_normal = UnpackScaleNormal( 1343 _Matcap0Normal.SampleBias(linear_repeat_s, 1344 UV_SCOFF(i, _Matcap0Normal_ST, _Matcap0Normal_UV_Select), 1345 _Global_Sample_Bias + _Matcap0Normal_Mip_Bias), 1346 _Matcap0Normal_Str * _Matcap0MixFactor); 1347 raw_normal = MY_BLEND_NORMALS(raw_normal, matcap_normal, matcap_mask * _Matcap0MixFactor); 1348 normal = float3( 1349 raw_normal.x * i.tangent + 1350 raw_normal.y * binormal + 1351 raw_normal.z * i.normal 1352 ); 1353 { 1354 const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(normal, 0))); 1355 const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(VIEW_DIR(_Matcap0_Center_Eye_Fix), 0))); 1356 const float3 cam_refl = -reflect(cam_view_dir, cam_normal); 1357 float m = 2.0 * sqrt( 1358 cam_refl.x * cam_refl.x + 1359 cam_refl.y * cam_refl.y + 1360 (cam_refl.z + 1) * (cam_refl.z + 1)); 1361 matcap_uv = cam_refl.xy / m + 0.5; 1362 } 1363#endif 1364 1365#if defined(_MATCAP0_DISTORTION0) 1366 float2 distort_uv = matcap_distortion0(matcap_uv); 1367 float2 matcap_uv = distort_uv; 1368#endif 1369 float3 matcap = _Matcap0.SampleBias(linear_repeat_s, matcap_uv, _Global_Sample_Bias) * _Matcap0Str; 1370 1371 float q = _Matcap0Quantization; 1372 if (q > 0) { 1373 matcap = floor(matcap * q) / q; 1374 } 1375 1376 int mode = round(_Matcap0Mode); 1377 switch (mode) { 1378 case 0: 1379 albedo.rgb += lerp(0, matcap, matcap_mask); 1380 matcap_emission += lerp(0, matcap, matcap_mask) * _Matcap0Emission; 1381 break; 1382 case 1: 1383 matcap_emission += lerp(0, matcap, matcap_mask) * _Matcap0Emission; 1384 albedo.rgb *= lerp(1, matcap, matcap_mask); 1385 break; 1386 case 2: 1387 matcap_overwrite_mask[0] = max(matcap_mask, matcap_overwrite_mask[0]); 1388 albedo.rgb = lerp(albedo.rgb, matcap, matcap_mask); 1389 matcap_emission = lerp(albedo.rgb, matcap, matcap_mask) * _Matcap0Emission; 1390 break; 1391 case 3: 1392 albedo.rgb -= lerp(0, matcap, matcap_mask); 1393 matcap_emission -= lerp(0, matcap, matcap_mask) * _Matcap0Emission; 1394 break; 1395 case 4: 1396 albedo.rgb = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask); 1397 matcap_emission = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask) * _Matcap0Emission; 1398 break; 1399 case 5: 1400 albedo.rgb = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask); 1401 matcap_emission = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask) * _Matcap0Emission; 1402 break; 1403 default: 1404 break; 1405 } 1406 } 1407#endif // _MATCAP0 1408#if defined(_MATCAP1) 1409 { 1410#if defined(_MATCAP1_MASK) 1411 float4 matcap_mask_raw = _Matcap1_Mask.SampleLevel(linear_repeat_s, 1412 get_uv_by_channel(i, _Matcap1_Mask_UV_Select), 0); 1413 float matcap_mask = matcap_mask_raw.r; 1414 matcap_mask = (bool) round(_Matcap1_Mask_Invert) ? 1 - matcap_mask : matcap_mask; 1415 matcap_mask *= matcap_mask_raw.a; 1416#else 1417 float matcap_mask = 1; 1418#endif 1419#if defined(_MATCAP1_MASK2) 1420 { 1421 float4 matcap_mask2_raw = _Matcap1_Mask2.SampleLevel(linear_repeat_s, 1422 get_uv_by_channel(i, _Matcap1_Mask2_UV_Select), 0); 1423 float matcap_mask2 = matcap_mask2_raw.r; 1424 matcap_mask2 = _Matcap1_Mask2_Invert_Colors ? 1 - matcap_mask2 : matcap_mask2; 1425 matcap_mask2 *= _Matcap1_Mask2_Invert_Alpha ? 1 - matcap_mask2_raw.a : matcap_mask2_raw.a; 1426 matcap_mask *= matcap_mask2; 1427 } 1428#endif 1429#if defined(_MATCAP1_NORMAL) 1430 float3 matcap_normal = UnpackScaleNormal( 1431 _Matcap1Normal.SampleBias(linear_repeat_s, 1432 UV_SCOFF(i, _Matcap1Normal_ST, _Matcap1Normal_UV_Select), 1433 _Global_Sample_Bias + _Matcap1Normal_Mip_Bias), 1434 _Matcap1Normal_Str * _Matcap1MixFactor); 1435 raw_normal = MY_BLEND_NORMALS(raw_normal, matcap_normal, matcap_mask * _Matcap1MixFactor); 1436 normal = float3( 1437 raw_normal.x * i.tangent + 1438 raw_normal.y * binormal + 1439 raw_normal.z * i.normal 1440 ); 1441 { 1442 const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(normal, 0))); 1443 const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(VIEW_DIR(_Matcap1_Center_Eye_Fix), 0))); 1444 const float3 cam_refl = -reflect(cam_view_dir, cam_normal); 1445 float m = 2.0 * sqrt( 1446 cam_refl.x * cam_refl.x + 1447 cam_refl.y * cam_refl.y + 1448 (cam_refl.z + 1) * (cam_refl.z + 1)); 1449 matcap_uv = cam_refl.xy / m + 0.5; 1450 } 1451#endif 1452#if defined(_MATCAP1_DISTORTION0) 1453 float2 distort_uv = matcap_distortion0(matcap_uv); 1454 float2 matcap_uv = distort_uv; 1455#endif 1456 float3 matcap = _Matcap1.SampleBias(linear_repeat_s, matcap_uv, _Global_Sample_Bias) * _Matcap1Str; 1457 1458 float q = _Matcap1Quantization; 1459 if (q > 0) { 1460 matcap = floor(matcap * q) / q; 1461 } 1462 1463 matcap_mask *= _Matcap1MixFactor; 1464 1465 int mode = round(_Matcap1Mode); 1466 switch (mode) { 1467 case 0: 1468 albedo.rgb += lerp(0, matcap, matcap_mask); 1469 matcap_emission += lerp(0, matcap, matcap_mask) * _Matcap1Emission; 1470 break; 1471 case 1: 1472 matcap_emission += lerp(0, matcap, matcap_mask) * _Matcap1Emission; 1473 albedo.rgb *= lerp(1, matcap, matcap_mask); 1474 break; 1475 case 2: 1476 matcap_overwrite_mask[1] = max(matcap_mask, matcap_overwrite_mask[1]); 1477 albedo.rgb = lerp(albedo.rgb, matcap, matcap_mask); 1478 matcap_emission = lerp(albedo.rgb, matcap, matcap_mask) * _Matcap1Emission; 1479 break; 1480 case 3: 1481 albedo.rgb -= lerp(0, matcap, matcap_mask); 1482 matcap_emission -= lerp(0, matcap, matcap_mask) * _Matcap1Emission; 1483 break; 1484 case 4: 1485 albedo.rgb = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask); 1486 matcap_emission = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask) * _Matcap1Emission; 1487 break; 1488 case 5: 1489 albedo.rgb = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask); 1490 matcap_emission = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask) * _Matcap1Emission; 1491 break; 1492 default: 1493 break; 1494 } 1495 } 1496#endif // _MATCAP1 1497 } 1498#endif // _MATCAP0 || _MATCAP1 1499 matcap_overwrite_mask = 1 - matcap_overwrite_mask; 1500 1501 // TODO get rid of the pow. It's a hack to make matcap replace mode look 1502 // better with overlay tattoos. 1503 float overlay_glitter_mask; 1504 mixOverlayAlbedoRoughnessMetallic(albedo, roughness, metallic, ov, 1505 1 - pow((1 - min(matcap_overwrite_mask[0], matcap_overwrite_mask[1])), 8), 1506 overlay_glitter_mask); 1507#if defined(_DECAL0) || defined(_DECAL1) || defined(_DECAL2) || defined(_DECAL3) || defined(_DECAL4) || defined(_DECAL5) || defined(_DECAL6) || defined(_DECAL7) || defined(_DECAL8) || defined(_DECAL9) 1508 float3 decal_emission = 0; 1509 applyDecal(albedo, roughness, metallic, decal_emission, i); 1510#endif 1511 1512#if defined(_RENDERING_CUTOUT) 1513#if defined(_RENDERING_CUTOUT_STOCHASTIC) 1514 float ar = rand2(i.uv0); 1515 clip(albedo.a - ar); 1516#elif defined(_RENDERING_CUTOUT_IGN) 1517 float ar = ign(floor(tdata.screen_uv_round * _Rendering_Cutout_Noise_Scale) + _Rendering_Cutout_Ign_Seed); 1518 ar = frac(ar + frame * PHI * _Rendering_Cutout_Speed); 1519 clip(albedo.a - ar); 1520#elif defined(_RENDERING_CUTOUT_NOISE_MASK) 1521 float ar = _Rendering_Cutout_Noise_Mask.SampleLevel(point_repeat_s, 1522 tdata.screen_uv * _ScreenParams.xy * 1523 _Rendering_Cutout_Noise_Mask_TexelSize.xy, 0); 1524 ar = frac(ar + frame * PHI * _Rendering_Cutout_Speed); 1525 clip(albedo.a - ar); 1526#elif defined(_RENDERING_CUTOUT_SSFD) 1527 float ar = 1.0 - ssfd(i.uv0, _Rendering_Cutout_SSFD_Scale, _Rendering_Cutout_SSFD_Max_Fwidth, 0, _Rendering_Cutout_SSFD_Noise); 1528 ar = ar > albedo.a ? 1 : 0; 1529 clip(albedo.a - ar); 1530#else 1531 clip(albedo.a - _Alpha_Cutoff); 1532#endif 1533 1534 albedo.a = 1; 1535#endif // _RENDERING_CUTOUT 1536 1537#if defined(_GIMMICK_AL_CHROMA_00) 1538 if (_Gimmick_AL_Chroma_00_Forward_Pass && AudioLinkIsAvailable()) { 1539 float3 c = AudioLinkData(ALPASS_CCSTRIP + uint2(0, 0)).rgb; 1540#if defined(_GIMMICK_AL_CHROMA_00_HUE_SHIFT) 1541 c = LRGBtoOKLCH(c); 1542 c[2] += _Gimmick_AL_Chroma_00_Hue_Shift_Theta * 2.0 * 3.14159265; 1543 c = OKLCHtoLRGB(c); 1544#endif 1545 albedo.rgb = lerp(albedo.rgb, c, _Gimmick_AL_Chroma_00_Forward_Blend); 1546 } 1547#endif 1548 1549#if defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1) || defined(_RIM_LIGHTING2) || defined(_RIM_LIGHTING3) 1550 { 1551#if defined(_RIM_LIGHTING0) 1552 { 1553 float3 rl_view_dir = VIEW_DIR(_Rim_Lighting0_Center_Eye_Fix); 1554#if defined(_RIM_LIGHTING0_CUSTOM_VIEW_VECTOR) 1555 rl_view_dir.xz = normalize(_Rim_Lighting0_Custom_View_Vector).xz; 1556#endif 1557 float2 rl_uv; 1558 { 1559#if defined(_RIM_LIGHTING0_REFLECT_IN_WORLD) 1560 const float3 cam_normal = _Rim_Lighting0_Use_Texture_Normals ? normal : i.normal; 1561 const float3 cam_view_dir = rl_view_dir; 1562#else 1563 const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(_Rim_Lighting0_Use_Texture_Normals ? normal : i.normal, 0))); 1564 const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(rl_view_dir, 0))); 1565#endif 1566 const float3 cam_refl = -reflect(cam_view_dir, cam_normal); 1567 float m = 2.0 * sqrt( 1568 cam_refl.x * cam_refl.x + 1569 cam_refl.y * cam_refl.y + 1570 (cam_refl.z + 1) * (cam_refl.z + 1)); 1571 rl_uv = cam_refl.xy / m + 0.5; 1572 } 1573 float rl = length(rl_uv - 0.5); 1574 rl = pow(2, -_Rim_Lighting0_Power * abs(rl - _Rim_Lighting0_Center)); 1575 float q = _Rim_Lighting0_Quantization; 1576 if (q > 0) { 1577 rl = floor(rl * q) / q; 1578 } 1579 float3 matcap = rl * _Rim_Lighting0_Color * _Rim_Lighting0_Strength; 1580#if defined(_RIM_LIGHTING0_MASK) 1581 float4 matcap_mask_raw = _Rim_Lighting0_Mask.SampleBias(GET_SAMPLER_RL0, 1582 get_uv_by_channel(i, _Rim_Lighting0_Mask_UV_Select), _Global_Sample_Bias); 1583 float matcap_mask = matcap_mask_raw.r; 1584 matcap_mask = (bool) round(_Rim_Lighting0_Mask_Invert) ? 1 - matcap_mask : matcap_mask; 1585 matcap_mask *= matcap_mask_raw.a; 1586#else 1587 float matcap_mask = 1; 1588#endif 1589#if defined(_RIM_LIGHTING0_MASK2) 1590 float4 matcap_mask2_raw = _Rim_Lighting0_Mask2.SampleBias(GET_SAMPLER_RL0, 1591 get_uv_by_channel(i, _Rim_Lighting0_Mask2_UV_Select), _Global_Sample_Bias); 1592 float matcap_mask2 = matcap_mask2_raw.r; 1593 matcap_mask2 = _Rim_Lighting0_Mask2_Invert_Colors ? 1 - matcap_mask2 : matcap_mask2; 1594 matcap_mask2 *= _Rim_Lighting0_Mask2_Invert_Alpha ? 1 - matcap_mask2_raw.a : matcap_mask2_raw.a; 1595 matcap_mask *= matcap_mask2; 1596#endif 1597#if defined(_MATCAP0) 1598 if (_Matcap0_Overwrite_Rim_Lighting_0) { 1599 matcap_mask *= matcap_overwrite_mask[0]; 1600 } 1601#endif 1602#if defined(_MATCAP1) 1603 if (_Matcap1_Overwrite_Rim_Lighting_0) { 1604 matcap_mask *= matcap_overwrite_mask[1]; 1605 } 1606#endif 1607#if defined(_RIM_LIGHTING0_POLAR_MASK) 1608 if (_Rim_Lighting0_PolarMask_Enabled) { 1609 float theta = atan2(rl_uv.y - 0.5, rl_uv.x - 0.5); 1610 float pmask_theta = _Rim_Lighting0_PolarMask_Theta; 1611 float pmask_pow = _Rim_Lighting0_PolarMask_Power; 1612 float d = glsl_mod((theta - pmask_theta) - PI, 2 * PI) - PI; 1613 float f = abs(1.0 / (1.0 + pow(abs(d), pmask_pow))); 1614 if (_Rim_Lighting0_Quantization > 0) { 1615 f = floor(f * _Rim_Lighting0_Quantization) / _Rim_Lighting0_Quantization; 1616 } 1617 matcap_mask *= f; 1618 } 1619#endif 1620#if defined(_RIM_LIGHTING0_GLITTER) 1621 float rl_glitter = get_glitter( 1622 get_uv_by_channel(i, round(_Rim_Lighting0_Glitter_UV_Select)), 1623 i.worldPos, CAM_POS(_Rim_Lighting0_Center_Eye_Fix), normal, 1624 _Rim_Lighting0_Glitter_Density, 1625 _Rim_Lighting0_Glitter_Amount, _Rim_Lighting0_Glitter_Speed, 1626 /*mask=*/1, /*angle=*/91, /*power=*/1); 1627 rl_glitter = floor(rl_glitter * _Rim_Lighting0_Glitter_Quantization) / _Rim_Lighting0_Glitter_Quantization; 1628 matcap_mask *= rl_glitter; 1629#endif 1630 int mode = round(_Rim_Lighting0_Mode); 1631 switch (mode) { 1632 case 0: 1633 albedo.rgb += lerp(0, matcap, matcap_mask); 1634 matcap_emission += lerp(0, matcap, matcap_mask) * _Rim_Lighting0_Emission; 1635 break; 1636 case 1: 1637 matcap_emission += albedo.rgb * lerp(0, matcap, matcap_mask) * _Rim_Lighting0_Emission; 1638 albedo.rgb *= lerp(1, matcap, matcap_mask); 1639 break; 1640 case 2: 1641 albedo.rgb = lerp(albedo.rgb, matcap, matcap_mask); 1642 matcap_emission = lerp(albedo.rgb, matcap, matcap_mask) * _Rim_Lighting0_Emission; 1643 break; 1644 case 3: 1645 albedo.rgb -= lerp(0, matcap, matcap_mask); 1646 matcap_emission -= lerp(0, matcap, matcap_mask) * _Rim_Lighting0_Emission; 1647 break; 1648 case 4: 1649 albedo.rgb = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask); 1650 matcap_emission = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask) * _Rim_Lighting0_Emission; 1651 break; 1652 case 5: 1653 albedo.rgb = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask); 1654 matcap_emission = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask) * _Rim_Lighting0_Emission; 1655 break; 1656 default: 1657 break; 1658 } 1659 } 1660#endif // _RIM_LIGHTING0 1661#if defined(_RIM_LIGHTING1) 1662 { 1663 float3 rl_view_dir = VIEW_DIR(_Rim_Lighting1_Center_Eye_Fix); 1664#if defined(_RIM_LIGHTING1_CUSTOM_VIEW_VECTOR) 1665 rl_view_dir.xz = normalize(_Rim_Lighting1_Custom_View_Vector).xz; 1666#endif 1667 float2 rl_uv; 1668 { 1669#if defined(_RIM_LIGHTING1_REFLECT_IN_WORLD) 1670 const float3 cam_normal = normal; 1671 const float3 cam_view_dir = rl_view_dir; 1672#else 1673 const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(normal, 0))); 1674 const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(rl_view_dir, 0))); 1675#endif 1676 const float3 cam_refl = -reflect(cam_view_dir, cam_normal); 1677 float m = 2.0 * sqrt( 1678 cam_refl.x * cam_refl.x + 1679 cam_refl.y * cam_refl.y + 1680 (cam_refl.z + 1) * (cam_refl.z + 1)); 1681 rl_uv = cam_refl.xy / m + 0.5; 1682 } 1683 float rl = length(rl_uv - 0.5); 1684 rl = pow(2, -_Rim_Lighting1_Power * abs(rl - _Rim_Lighting1_Center)); 1685 float q = _Rim_Lighting1_Quantization; 1686 if (q > 0) { 1687 rl = floor(rl * q) / q; 1688 } 1689 float3 matcap = rl * _Rim_Lighting1_Color * _Rim_Lighting1_Strength; 1690#if defined(_RIM_LIGHTING1_MASK) 1691 float4 matcap_mask_raw = _Rim_Lighting1_Mask.SampleBias(GET_SAMPLER_RL1, 1692 get_uv_by_channel(i, _Rim_Lighting1_Mask_UV_Select), _Global_Sample_Bias); 1693 float matcap_mask = matcap_mask_raw.r; 1694 matcap_mask = (bool) round(_Rim_Lighting1_Mask_Invert) ? 1 - matcap_mask : matcap_mask; 1695 matcap_mask *= matcap_mask_raw.a; 1696#else 1697 float matcap_mask = 1; 1698#endif 1699#if defined(_RIM_LIGHTING1_MASK2) 1700 float4 matcap_mask2_raw = _Rim_Lighting1_Mask2.SampleBias(GET_SAMPLER_RL1, 1701 get_uv_by_channel(i, _Rim_Lighting1_Mask2_UV_Select), _Global_Sample_Bias); 1702 float matcap_mask2 = matcap_mask2_raw.r; 1703 matcap_mask2 = _Rim_Lighting1_Mask2_Invert_Colors ? 1 - matcap_mask2 : matcap_mask2; 1704 matcap_mask2 *= _Rim_Lighting1_Mask2_Invert_Alpha ? 1 - matcap_mask2_raw.a : matcap_mask2_raw.a; 1705 matcap_mask *= matcap_mask2; 1706#endif 1707#if defined(_MATCAP0) 1708 if (_Matcap0_Overwrite_Rim_Lighting_1) { 1709 matcap_mask *= matcap_overwrite_mask[0]; 1710 } 1711#endif 1712#if defined(_MATCAP1) 1713 if (_Matcap1_Overwrite_Rim_Lighting_1) { 1714 matcap_mask *= matcap_overwrite_mask[1]; 1715 } 1716#endif 1717#if defined(_RIM_LIGHTING1_POLAR_MASK) 1718 if (_Rim_Lighting1_PolarMask_Enabled) { 1719 float theta = atan2(rl_uv.y - 0.5, rl_uv.x - 0.5); 1720 float pmask_theta = _Rim_Lighting1_PolarMask_Theta; 1721 float pmask_pow = _Rim_Lighting1_PolarMask_Power; 1722 float d = glsl_mod((theta - pmask_theta) - PI, 2 * PI) - PI; 1723 float f = abs(1.0 / (1.0 + pow(abs(d), pmask_pow))); 1724 if (_Rim_Lighting1_Quantization > 0) { 1725 f = floor(f * _Rim_Lighting1_Quantization) / _Rim_Lighting1_Quantization; 1726 } 1727 matcap_mask *= f; 1728 } 1729#endif 1730#if defined(_RIM_LIGHTING1_GLITTER) 1731 float rl_glitter = get_glitter( 1732 get_uv_by_channel(i, round(_Rim_Lighting1_Glitter_UV_Select)), 1733 i.worldPos, CAM_POS(_Rim_Lighting1_Center_Eye_Fix), normal, 1734 _Rim_Lighting1_Glitter_Density, 1735 _Rim_Lighting1_Glitter_Amount, _Rim_Lighting1_Glitter_Speed, 1736 /*mask=*/1, /*angle=*/91, /*power=*/1); 1737 rl_glitter = floor(rl_glitter * _Rim_Lighting1_Glitter_Quantization) / _Rim_Lighting1_Glitter_Quantization; 1738 matcap_mask *= rl_glitter; 1739#endif 1740 int mode = round(_Rim_Lighting1_Mode); 1741 switch (mode) { 1742 case 0: 1743 albedo.rgb += lerp(0, matcap, matcap_mask); 1744 matcap_emission += lerp(0, matcap, matcap_mask) * _Rim_Lighting1_Emission; 1745 break; 1746 case 1: 1747 matcap_emission += albedo.rgb * lerp(0, matcap, matcap_mask) * _Rim_Lighting1_Emission; 1748 albedo.rgb *= lerp(1, matcap, matcap_mask); 1749 break; 1750 case 2: 1751 albedo.rgb = lerp(albedo.rgb, matcap, matcap_mask); 1752 matcap_emission = lerp(albedo.rgb, matcap, matcap_mask) * _Rim_Lighting1_Emission; 1753 break; 1754 case 3: 1755 albedo.rgb -= lerp(0, matcap, matcap_mask); 1756 matcap_emission -= lerp(0, matcap, matcap_mask) * _Rim_Lighting1_Emission; 1757 break; 1758 case 4: 1759 albedo.rgb = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask); 1760 matcap_emission = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask) * _Rim_Lighting1_Emission; 1761 break; 1762 case 5: 1763 albedo.rgb = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask); 1764 matcap_emission = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask) * _Rim_Lighting1_Emission; 1765 break; 1766 default: 1767 break; 1768 } 1769 } 1770#endif // _RIM_LIGHTING1 1771#if defined(_RIM_LIGHTING2) 1772 { 1773 float3 rl_view_dir = VIEW_DIR(_Rim_Lighting2_Center_Eye_Fix); 1774#if defined(_RIM_LIGHTING2_CUSTOM_VIEW_VECTOR) 1775 rl_view_dir.xz = normalize(_Rim_Lighting2_Custom_View_Vector).xz; 1776#endif 1777 float2 rl_uv; 1778 { 1779#if defined(_RIM_LIGHTING2_REFLECT_IN_WORLD) 1780 const float3 cam_normal = normal; 1781 const float3 cam_view_dir = rl_view_dir; 1782#else 1783 const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(normal, 0))); 1784 const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(rl_view_dir, 0))); 1785#endif 1786 const float3 cam_refl = -reflect(cam_view_dir, cam_normal); 1787 float m = 2.0 * sqrt( 1788 cam_refl.x * cam_refl.x + 1789 cam_refl.y * cam_refl.y + 1790 (cam_refl.z + 1) * (cam_refl.z + 1)); 1791 rl_uv = cam_refl.xy / m + 0.5; 1792 } 1793 float rl = length(rl_uv - 0.5); 1794 rl = pow(2, -_Rim_Lighting2_Power * abs(rl - _Rim_Lighting2_Center)); 1795 float q = _Rim_Lighting2_Quantization; 1796 if (q > 0) { 1797 rl = floor(rl * q) / q; 1798 } 1799 float3 matcap = rl * _Rim_Lighting2_Color * _Rim_Lighting2_Strength; 1800#if defined(_RIM_LIGHTING2_MASK) 1801 float4 matcap_mask_raw = _Rim_Lighting2_Mask.SampleBias(GET_SAMPLER_RL2, 1802 get_uv_by_channel(i, _Rim_Lighting2_Mask_UV_Select), _Global_Sample_Bias); 1803 float matcap_mask = matcap_mask_raw.r; 1804 matcap_mask = (bool) round(_Rim_Lighting2_Mask_Invert) ? 1 - matcap_mask : matcap_mask; 1805 matcap_mask *= matcap_mask_raw.a; 1806#else 1807 float matcap_mask = 1; 1808#endif 1809#if defined(_RIM_LIGHTING2_MASK2) 1810 float4 matcap_mask2_raw = _Rim_Lighting2_Mask2.SampleBias(GET_SAMPLER_RL2, 1811 get_uv_by_channel(i, _Rim_Lighting2_Mask2_UV_Select), _Global_Sample_Bias); 1812 float matcap_mask2 = matcap_mask2_raw.r; 1813 matcap_mask2 = _Rim_Lighting2_Mask2_Invert_Colors ? 1 - matcap_mask2 : matcap_mask2; 1814 matcap_mask2 *= _Rim_Lighting2_Mask2_Invert_Alpha ? 1 - matcap_mask2_raw.a : matcap_mask2_raw.a; 1815 matcap_mask *= matcap_mask2; 1816#endif 1817#if defined(_MATCAP0) 1818 if (_Matcap0_Overwrite_Rim_Lighting_2) { 1819 matcap_mask *= matcap_overwrite_mask[0]; 1820 } 1821#endif 1822#if defined(_MATCAP1) 1823 if (_Matcap1_Overwrite_Rim_Lighting_2) { 1824 matcap_mask *= matcap_overwrite_mask[1]; 1825 } 1826#endif 1827#if defined(_RIM_LIGHTING2_POLAR_MASK) 1828 if (_Rim_Lighting2_PolarMask_Enabled) { 1829 float theta = atan2(rl_uv.y - 0.5, rl_uv.x - 0.5); 1830 float pmask_theta = _Rim_Lighting2_PolarMask_Theta; 1831 float pmask_pow = _Rim_Lighting2_PolarMask_Power; 1832 float d = glsl_mod((theta - pmask_theta) - PI, 2 * PI) - PI; 1833 float f = abs(1.0 / (1.0 + pow(abs(d), pmask_pow))); 1834 if (_Rim_Lighting2_Quantization > 0) { 1835 f = floor(f * _Rim_Lighting2_Quantization) / _Rim_Lighting2_Quantization; 1836 } 1837 matcap_mask *= f; 1838 } 1839#endif 1840#if defined(_RIM_LIGHTING2_GLITTER) 1841 float rl_glitter = get_glitter( 1842 get_uv_by_channel(i, round(_Rim_Lighting2_Glitter_UV_Select)), 1843 i.worldPos, CAM_POS(_Rim_Lighting2_Center_Eye_Fix), normal, 1844 _Rim_Lighting2_Glitter_Density, 1845 _Rim_Lighting2_Glitter_Amount, _Rim_Lighting2_Glitter_Speed, 1846 /*mask=*/1, /*angle=*/91, /*power=*/1); 1847 rl_glitter = floor(rl_glitter * _Rim_Lighting2_Glitter_Quantization) / _Rim_Lighting2_Glitter_Quantization; 1848 matcap_mask *= rl_glitter; 1849#endif 1850 int mode = round(_Rim_Lighting2_Mode); 1851 switch (mode) { 1852 case 0: 1853 albedo.rgb += lerp(0, matcap, matcap_mask); 1854 matcap_emission += lerp(0, matcap, matcap_mask) * _Rim_Lighting2_Emission; 1855 break; 1856 case 1: 1857 matcap_emission += albedo.rgb * lerp(0, matcap, matcap_mask) * _Rim_Lighting2_Emission; 1858 albedo.rgb *= lerp(1, matcap, matcap_mask); 1859 break; 1860 case 2: 1861 albedo.rgb = lerp(albedo.rgb, matcap, matcap_mask); 1862 matcap_emission = lerp(albedo.rgb, matcap, matcap_mask) * _Rim_Lighting2_Emission; 1863 break; 1864 case 3: 1865 albedo.rgb -= lerp(0, matcap, matcap_mask); 1866 matcap_emission -= lerp(0, matcap, matcap_mask) * _Rim_Lighting2_Emission; 1867 break; 1868 case 4: 1869 albedo.rgb = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask); 1870 matcap_emission = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask) * _Rim_Lighting2_Emission; 1871 break; 1872 case 5: 1873 albedo.rgb = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask); 1874 matcap_emission = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask) * _Rim_Lighting2_Emission; 1875 break; 1876 default: 1877 break; 1878 } 1879 } 1880#endif // _RIM_LIGHTING2 1881#if defined(_RIM_LIGHTING3) 1882 { 1883 float3 rl_view_dir = VIEW_DIR(_Rim_Lighting3_Center_Eye_Fix); 1884#if defined(_RIM_LIGHTING3_CUSTOM_VIEW_VECTOR) 1885 rl_view_dir.xz = normalize(_Rim_Lighting3_Custom_View_Vector).xz; 1886#endif 1887 float2 rl_uv; 1888 { 1889#if defined(_RIM_LIGHTING3_REFLECT_IN_WORLD) 1890 const float3 cam_normal = normal; 1891 const float3 cam_view_dir = rl_view_dir; 1892#else 1893 const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(normal, 0))); 1894 const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(rl_view_dir, 0))); 1895#endif 1896 const float3 cam_refl = -reflect(cam_view_dir, cam_normal); 1897 float m = 2.0 * sqrt( 1898 cam_refl.x * cam_refl.x + 1899 cam_refl.y * cam_refl.y + 1900 (cam_refl.z + 1) * (cam_refl.z + 1)); 1901 rl_uv = cam_refl.xy / m + 0.5; 1902 } 1903 float rl = length(rl_uv - 0.5); 1904 rl = pow(2, -_Rim_Lighting3_Power * abs(rl - _Rim_Lighting3_Center)); 1905 float q = _Rim_Lighting3_Quantization; 1906 if (q > 0) { 1907 rl = floor(rl * q) / q; 1908 } 1909 float3 matcap = rl * _Rim_Lighting3_Color * _Rim_Lighting3_Strength; 1910#if defined(_RIM_LIGHTING3_MASK) 1911 float4 matcap_mask_raw = _Rim_Lighting3_Mask.SampleBias(GET_SAMPLER_RL3, 1912 get_uv_by_channel(i, _Rim_Lighting3_Mask_UV_Select), _Global_Sample_Bias); 1913 float matcap_mask = matcap_mask_raw.r; 1914 matcap_mask = (bool) round(_Rim_Lighting3_Mask_Invert) ? 1 - matcap_mask : matcap_mask; 1915 matcap_mask *= matcap_mask_raw.a; 1916#else 1917 float matcap_mask = 1; 1918#endif 1919#if defined(_RIM_LIGHTING3_MASK2) 1920 float4 matcap_mask2_raw = _Rim_Lighting3_Mask2.SampleBias(GET_SAMPLER_RL3, 1921 get_uv_by_channel(i, _Rim_Lighting3_Mask2_UV_Select), _Global_Sample_Bias); 1922 float matcap_mask2 = matcap_mask2_raw.r; 1923 matcap_mask2 = _Rim_Lighting3_Mask2_Invert_Colors ? 1 - matcap_mask2 : matcap_mask2; 1924 matcap_mask2 *= _Rim_Lighting3_Mask2_Invert_Alpha ? 1 - matcap_mask2_raw.a : matcap_mask2_raw.a; 1925 matcap_mask *= matcap_mask2; 1926#endif 1927#if defined(_MATCAP0) 1928 if (_Matcap0_Overwrite_Rim_Lighting_3) { 1929 matcap_mask *= matcap_overwrite_mask[0]; 1930 } 1931#endif 1932#if defined(_MATCAP1) 1933 if (_Matcap1_Overwrite_Rim_Lighting_3) { 1934 matcap_mask *= matcap_overwrite_mask[1]; 1935 } 1936#endif 1937#if defined(_RIM_LIGHTING3_POLAR_MASK) 1938 if (_Rim_Lighting3_PolarMask_Enabled) { 1939 float theta = atan2(rl_uv.y - 0.5, rl_uv.x - 0.5); 1940 float pmask_theta = _Rim_Lighting3_PolarMask_Theta; 1941 float pmask_pow = _Rim_Lighting3_PolarMask_Power; 1942 float d = glsl_mod((theta - pmask_theta) - PI, 2 * PI) - PI; 1943 float f = abs(1.0 / (1.0 + pow(abs(d), pmask_pow))); 1944 if (_Rim_Lighting3_Quantization > 0) { 1945 f = floor(f * _Rim_Lighting3_Quantization) / _Rim_Lighting3_Quantization; 1946 } 1947 matcap_mask *= f; 1948 } 1949#endif 1950#if defined(_RIM_LIGHTING3_GLITTER) 1951 float rl_glitter = get_glitter( 1952 get_uv_by_channel(i, round(_Rim_Lighting3_Glitter_UV_Select)), 1953 i.worldPos, CAM_POS(_Rim_Lighting3_Center_Eye_Fix), normal, 1954 _Rim_Lighting3_Glitter_Density, 1955 _Rim_Lighting3_Glitter_Amount, _Rim_Lighting3_Glitter_Speed, 1956 /*mask=*/1, /*angle=*/91, /*power=*/1); 1957 rl_glitter = floor(rl_glitter * _Rim_Lighting3_Glitter_Quantization) / _Rim_Lighting3_Glitter_Quantization; 1958 matcap_mask *= rl_glitter; 1959#endif 1960 int mode = round(_Rim_Lighting3_Mode); 1961 switch (mode) { 1962 case 0: 1963 albedo.rgb += lerp(0, matcap, matcap_mask); 1964 matcap_emission += lerp(0, matcap, matcap_mask) * _Rim_Lighting3_Emission; 1965 break; 1966 case 1: 1967 matcap_emission += albedo.rgb * lerp(0, matcap, matcap_mask) * _Rim_Lighting3_Emission; 1968 albedo.rgb *= lerp(1, matcap, matcap_mask); 1969 break; 1970 case 2: 1971 albedo.rgb = lerp(albedo.rgb, matcap, matcap_mask); 1972 matcap_emission = lerp(albedo.rgb, matcap, matcap_mask) * _Rim_Lighting3_Emission; 1973 break; 1974 case 3: 1975 albedo.rgb -= lerp(0, matcap, matcap_mask); 1976 matcap_emission -= lerp(0, matcap, matcap_mask) * _Rim_Lighting3_Emission; 1977 break; 1978 case 4: 1979 albedo.rgb = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask); 1980 matcap_emission = lerp(albedo.rgb, min(albedo.rgb, matcap), matcap_mask) * _Rim_Lighting3_Emission; 1981 break; 1982 case 5: 1983 albedo.rgb = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask); 1984 matcap_emission = lerp(albedo.rgb, max(albedo.rgb, matcap), matcap_mask) * _Rim_Lighting3_Emission; 1985 break; 1986 default: 1987 break; 1988 } 1989 } 1990#endif // _RIM_LIGHTING3 1991 } 1992#endif // _RIM_LIGHTING0 || _RIM_LIGHTING1 || _RIM_LIGHTING2 || _RIM_LIGHTING3 1993 1994#if defined(_GIMMICK_LETTER_GRID) 1995 float3 gimmick_letter_grid_emission = 0; 1996 { 1997 int2 cell_pos; 1998 int2 font_res = int2(round(_Gimmick_Letter_Grid_Tex_Res_X), round(_Gimmick_Letter_Grid_Tex_Res_Y)); 1999 int2 grid_res = int2(round(_Gimmick_Letter_Grid_Res_X), round(_Gimmick_Letter_Grid_Res_Y)); 2000 float2 cell_uv; // uv within each letter cell 2001 2002 float4 scoff = _Gimmick_Letter_Grid_UV_Scale_Offset; 2003 float2 uv = ((get_uv_by_channel(i, _Gimmick_Letter_Grid_UV_Select) - 0.5) - scoff.zw) * scoff.xy + 0.5; 2004 bool in_box = getBoxLoc(uv, 2005 /*bottom_left=*/0, 2006 /*top_right=*/1, 2007 /*res=*/grid_res, 2008 /*padding=*/_Gimmick_Letter_Grid_Padding, 2009 cell_pos, cell_uv); 2010 2011 float n_glyphs = font_res.x * font_res.y; 2012 float cell_rand = rand2(cell_pos); 2013 float c = glsl_mod(cell_pos.y * grid_res.x + cell_pos.x + cell_rand * n_glyphs + _Time[3], n_glyphs); 2014 float3 msd = renderInBox(c, uv, cell_uv, _Gimmick_Letter_Grid_Texture, font_res).rgb; 2015 float sd = median(msd); 2016 float px_range = 2; // determined by msdf-atlas-gen.exe; 2 is default 2017 float2 unit_range = px_range / 1024; 2018 float2 screen_tex_size = 1 / fwidth(cell_uv); 2019 float screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), 1.0); 2020 float screen_px_distance = screen_px_range * (sd - 0.5); 2021 float op = saturate(screen_px_distance + 0.5); 2022 op = saturate(floor(op * 4)); 2023 2024 float4 grid_color = _Gimmick_Letter_Grid_Color; 2025 2026#if defined(_GIMMICK_LETTER_GRID_COLOR_WAVE) 2027 { 2028 float2 c = grid_res/2; 2029 float d = floor(length(cell_pos - c)); 2030 d *= _Gimmick_Letter_Grid_Color_Wave_Frequency; 2031 2032 float3 col = LRGBtoOKLCH(grid_color.rgb); 2033 col[2] += d - _Time[3] * _Gimmick_Letter_Grid_Color_Wave_Speed; 2034 col = OKLCHtoLRGB(col); 2035 grid_color.rgb = col; 2036 } 2037#endif // _GIMMICK_LETTER_GRID_COLOR_WAVE 2038#if defined(_GIMMICK_LETTER_GRID_RIM_LIGHTING) 2039 { 2040 float theta = atan2(length(cross(MATCAP_VIEW_DIR(), normal)), dot(MATCAP_VIEW_DIR(), normal)); 2041 float rl = abs(theta) / PI; // on [0, 1] 2042 rl = pow(2, -_Gimmick_Letter_Grid_Rim_Lighting_Power * abs(rl - _Gimmick_Letter_Grid_Rim_Lighting_Center)); 2043 float q = _Gimmick_Letter_Grid_Rim_Lighting_Quantization; 2044 if (q > 0) { 2045 rl = floor(rl * q) / q; 2046 } 2047 2048 float4 matcap_mask_raw = _Gimmick_Letter_Grid_Rim_Lighting_Mask.SampleBias(GET_SAMPLER_RL3, 2049 get_uv_by_channel(i, _Gimmick_Letter_Grid_Rim_Lighting_Mask_UV_Select), _Global_Sample_Bias); 2050 float matcap_mask = matcap_mask_raw.r; 2051 matcap_mask = (bool) round(_Gimmick_Letter_Grid_Rim_Lighting_Mask_Invert) ? 1 - matcap_mask : matcap_mask; 2052 matcap_mask *= matcap_mask_raw.a; 2053 2054 op *= rl * matcap_mask; 2055 } 2056#endif // GIMMICK_LETTER_GRID_RIM_LIGHTING 2057 2058 albedo = lerp(albedo, grid_color, op * in_box); 2059 metallic = lerp(metallic, _Gimmick_Letter_Grid_Metallic, op * in_box); 2060 //metallic = lerp(metallic, glsl_mod(_Time[3], 1.0), op * in_box); 2061 roughness = lerp(roughness, _Gimmick_Letter_Grid_Roughness, op * in_box); 2062 gimmick_letter_grid_emission = _Gimmick_Letter_Grid_Color * _Gimmick_Letter_Grid_Emission * op * in_box; 2063 } 2064#endif // _GIMMICK_LETTER_GRID 2065 2066#if defined(_GIMMICK_LETTER_GRID_2) 2067 float3 gimmick_letter_grid_2_emission = 0; 2068#if defined(_GIMMICK_LETTER_GRID_2_MASK) 2069 float mask = _Gimmick_Letter_Grid_2_Mask.SampleLevel(linear_repeat_s, get_uv_by_channel(i, 0), 0); 2070#else 2071 float mask = 1; 2072#endif 2073 { 2074 int2 cell_pos; 2075 int2 font_res = int2(round(_Gimmick_Letter_Grid_2_Tex_Res_X), round(_Gimmick_Letter_Grid_2_Tex_Res_Y)); 2076 int2 grid_res = int2(round(_Gimmick_Letter_Grid_2_Res_X), round(_Gimmick_Letter_Grid_2_Res_Y)); 2077 float2 cell_uv; // uv within each letter cell 2078 2079 float4 scoff = _Gimmick_Letter_Grid_2_UV_Scale_Offset; 2080 float2 uv = ((get_uv_by_channel(i, 0) - 0.5) - scoff.zw) * scoff.xy + 0.5; 2081 2082 bool in_box = getBoxLoc(uv, 2083 /*bottom_left=*/0, 2084 /*top_right=*/1, 2085 /*res=*/grid_res, 2086 /*padding=*/_Gimmick_Letter_Grid_2_Padding, 2087 cell_pos, cell_uv); 2088 2089 // Extract char from _Gimmick_Letter_Grid_2_Data_Row_0 et al using cell_pos. 2090 cell_pos.y = (grid_res.y - cell_pos.y) - 1; 2091 float c = lerp( 2092 lerp( 2093 _Gimmick_Letter_Grid_2_Data_Row_0[cell_pos.x], 2094 _Gimmick_Letter_Grid_2_Data_Row_1[cell_pos.x], 2095 cell_pos.y), 2096 lerp( 2097 _Gimmick_Letter_Grid_2_Data_Row_2[cell_pos.x], 2098 _Gimmick_Letter_Grid_2_Data_Row_3[cell_pos.x], 2099 cell_pos.y - 2), 2100 cell_pos.y/2); 2101 c += _Gimmick_Letter_Grid_2_Global_Offset; 2102 2103 float3 msd = renderInBox(c, uv, cell_uv, _Gimmick_Letter_Grid_2_Texture, font_res).rgb; 2104 float sd = median(msd); 2105 // screenPxRange() 2106 float screen_px_range; 2107 { 2108 float2 tex_size = float2(_Gimmick_Letter_Grid_2_Texture_TexelSize.zw); 2109 float2 real_cell_size = floor(tex_size / grid_res); // size of cell in texels 2110 float2 unit_range = _Gimmick_Letter_Grid_2_Screen_Px_Range / real_cell_size; 2111 // fwidth(x) = abs(abs(ddx(x)) + abs(ddy(x))) 2112 // 1 / fwidth(cell_uv) 2113 // = 1 / abs(abs(ddx(cell_uv)) + abs(ddy(cell_uv))) 2114 // This is just the manhattan length of the triangle with edges 2115 // ddx(cell_uv.x) and ddy(cell_uv.x). 2116 // In other words, an approximation of the gradient of cell_uv.x. 2117 2118 // fwidth is an approximation showing how much cell_uv changes per pixel. 2119 // By inverting it, we get an approximation of how many pixels are 2120 // spanned by the whole texture, if it was rendered with this pixel's 2121 // properties. 2122 float2 screen_tex_size = 1 / fwidth(cell_uv); 2123 2124 screen_px_range = max(0.5 * dot(unit_range, screen_tex_size), _Gimmick_Letter_Grid_2_Min_Screen_Px_Range); 2125 } 2126 float screen_px_distance = screen_px_range * (sd - _Gimmick_Letter_Grid_2_Alpha_Threshold); 2127 float smooth_range = (length(grid_res) / sqrt(screen_px_range)) * _Gimmick_Letter_Grid_2_Blurriness; 2128 float op = smoothstep(-smooth_range, smooth_range, screen_px_distance); 2129 op *= mask; 2130 //op = floor(op); 2131 2132 albedo = lerp(albedo, _Gimmick_Letter_Grid_2_Color, op * in_box); 2133 metallic = lerp(metallic, _Gimmick_Letter_Grid_2_Metallic, op * in_box); 2134 roughness = lerp(roughness, _Gimmick_Letter_Grid_2_Roughness, op * in_box); 2135 gimmick_letter_grid_2_emission = _Gimmick_Letter_Grid_2_Color * _Gimmick_Letter_Grid_2_Emission * op * in_box; 2136 } 2137#endif // _GIMMICK_LETTER_GRID 2138 2139 2140#if defined(_OKLAB) 2141 // Do hue shift in perceptually uniform color space so it doesn't look like 2142 // shit. 2143 float oklab_mask = _OKLAB_Mask.SampleBias(linear_repeat_s, i.uv0, _Global_Sample_Bias); 2144 if (_OKLAB_Mask_Invert) { 2145 oklab_mask = 1 - oklab_mask; 2146 } 2147 if (oklab_mask > 0.01 && 2148 (_OKLAB_Hue_Shift > 1E-6 || 2149 abs(_OKLAB_Chroma_Shift) > 1E-6 || 2150 abs(_OKLAB_Lightness_Shift) > 1E-6)) { 2151 float3 c = albedo.rgb; 2152 c = LRGBtoOKLCH(c); 2153 c.x += _OKLAB_Lightness_Shift; 2154 c.y += _OKLAB_Chroma_Shift; 2155 c.z += _OKLAB_Hue_Shift; 2156 c = OKLCHtoLRGB(c); 2157 albedo.rgb = c; 2158 } 2159#endif 2160 2161#if defined(_HSV0) 2162 { 2163 float hsv_mask = _HSV0_Mask.SampleBias(linear_repeat_s, i.uv0, _Global_Sample_Bias); 2164 if (_HSV0_Mask_Invert) { 2165 hsv_mask = 1 - hsv_mask; 2166 } 2167 if (hsv_mask > 0.01 && 2168 (_HSV0_Hue_Shift > 1E-6 || 2169 abs(_HSV0_Sat_Shift) > 1E-6 || 2170 abs(_HSV0_Val_Shift) > 1E-6)) { 2171 float3 c = albedo.rgb; 2172 c = RGBtoHSV(c); 2173 c += float3(_HSV0_Hue_Shift, _HSV0_Sat_Shift, _HSV0_Val_Shift); 2174 c.x = glsl_mod(c.x, 1.0); 2175 c.yz = saturate(c.yz); 2176 c = HSVtoRGB(c); 2177 albedo.rgb = c; 2178 } 2179 } 2180#endif 2181 2182#if defined(_HSV1) 2183 { 2184 float hsv_mask = _HSV1_Mask.SampleBias(linear_repeat_s, i.uv0, _Global_Sample_Bias); 2185 if (_HSV1_Mask_Invert) { 2186 hsv_mask = 1 - hsv_mask; 2187 } 2188 if (hsv_mask > 0.01 && 2189 (_HSV1_Hue_Shift > 1E-6 || 2190 abs(_HSV1_Sat_Shift) > 1E-6 || 2191 abs(_HSV1_Val_Shift) > 1E-6)) { 2192 float3 c = albedo.rgb; 2193 c = RGBtoHSV(c); 2194 c += float3(_HSV1_Hue_Shift, _HSV1_Sat_Shift, _HSV1_Val_Shift); 2195 c.x = glsl_mod(c.x, 1.0); 2196 c.yz = saturate(c.yz); 2197 c = HSVtoRGB(c); 2198 albedo.rgb = c; 2199 } 2200 } 2201#endif 2202 2203#if defined(_HSV2) 2204 { 2205 float hsv_mask = _HSV2_Mask.SampleBias(linear_repeat_s, i.uv0, _Global_Sample_Bias); 2206 if (_HSV2_Mask_Invert) { 2207 hsv_mask = 1 - hsv_mask; 2208 } 2209 if (hsv_mask > 0.01 && 2210 (_HSV2_Hue_Shift > 1E-6 || 2211 abs(_HSV2_Sat_Shift) > 1E-6 || 2212 abs(_HSV2_Val_Shift) > 1E-6)) { 2213 float3 c = albedo.rgb; 2214 c = RGBtoHSV(c); 2215 c += float3(_HSV2_Hue_Shift, _HSV2_Sat_Shift, _HSV2_Val_Shift); 2216 c.x = glsl_mod(c.x, 1.0); 2217 c.yz = saturate(c.yz); 2218 c = HSVtoRGB(c); 2219 albedo.rgb = c; 2220 } 2221 } 2222#endif 2223 2224#if defined(_AMBIENT_OCCLUSION) 2225 float ao = _Ambient_Occlusion.SampleBias(linear_repeat_s, 2226 UV_SCOFF(i, _Ambient_Occlusion_ST, /*uv_channel=*/0), 2227 _Global_Sample_Bias); 2228 ao = 1 - (1 - ao) * _Ambient_Occlusion_Strength; 2229#else 2230 float ao = 1; 2231#endif 2232 2233#if defined(_GIMMICK_FLAT_COLOR) 2234 if (round(_Gimmick_Flat_Color_Enable_Dynamic)) { 2235 albedo = _Gimmick_Flat_Color_Color; 2236 normal = i.normal; 2237 } 2238#endif 2239#if defined(_GLITTER) 2240 float3 glitter_color_unlit; 2241 { 2242 float glitter_mask = 2243 _Glitter_Mask.SampleLevel(linear_repeat_s, i.uv0, /*lod=*/0); 2244 glitter_mask *= min(matcap_overwrite_mask[0], matcap_overwrite_mask[1]); 2245 glitter_mask *= overlay_glitter_mask; 2246 float glitter = get_glitter( 2247 get_uv_by_channel(i, round(_Glitter_UV_Select)), 2248 i.worldPos, i.centerCamPos, normal, 2249 _Glitter_Density, _Glitter_Amount, _Glitter_Speed, 2250 glitter_mask, _Glitter_Angle, _Glitter_Power); 2251 glitter_color_unlit = glitter * _Glitter_Color; 2252 } 2253 albedo.rgb += glitter_color_unlit * _Glitter_Brightness_Lit; 2254#endif 2255 2256#if defined(_GIMMICK_DS2) 2257 Gimmick_DS2_Output ds2 = (Gimmick_DS2_Output)0; 2258 // TODO if these remain mutually exclusive, we should use an enum + switch 2259 switch (round(_Gimmick_DS2_Choice)) { 2260 case 0: 2261 ds2 = Gimmick_DS2_00(i); 2262 break; 2263 case 1: 2264 ds2 = Gimmick_DS2_01(i); 2265 break; 2266 case 2: 2267 ds2 = Gimmick_DS2_02(i); 2268 break; 2269 case 3: 2270 ds2 = Gimmick_DS2_03(i); 2271 break; 2272 case 10: 2273 ds2 = Gimmick_DS2_10(i); 2274 break; 2275 case 11: 2276 ds2 = Gimmick_DS2_11(i, tdata); 2277 break; 2278 default: 2279 ds2 = (Gimmick_DS2_Output)0; 2280 break; 2281 } 2282 float ds2_mask = _Gimmick_DS2_Mask.SampleLevel(linear_clamp_s, i.uv0, 0); 2283 albedo = ds2.albedo * _Gimmick_DS2_Albedo_Factor * ds2_mask; 2284 normal = ds2.normal; 2285 metallic = ds2.metallic * ds2_mask; 2286 roughness = ds2.roughness; 2287 i.worldPos = ds2.worldPos; 2288 { 2289 float4 clip_pos = mul(UNITY_MATRIX_VP, float4(ds2.worldPos, 1.0)); 2290 depth = clip_pos.z / clip_pos.w; 2291 } 2292#endif 2293 2294 float3 diffuse_contrib = 0; 2295 // TODO restore this 2296 // For some dumb fucking dipshit reason, this is incompatible with clearcoat 2297 // in worlds. Probably the compiler optimizer shitting the bed. 2298#if 0 && defined(_GIMMICK_FOG_01) 2299 [branch] 2300 if (!_Gimmick_Fog_01_Overlay_Mode) { 2301 Fog01PBR fog_01_pbr = getFog01(i, tdata); 2302 albedo = fog_01_pbr.albedo; 2303 //depth = fog_01_pbr.depth; 2304#if defined(_RENDERING_TRANSPARENT) || defined(_RENDERING_TRANSCLIPPING) 2305 albedo.rgb *= albedo.a; 2306#endif 2307 return albedo; 2308 } 2309#endif 2310#if defined(_GIMMICK_AURORA) 2311 { 2312 AuroraPBR pbr = getAurora(i); 2313 albedo = pbr.albedo; 2314 depth = pbr.depth; 2315 diffuse_contrib += pbr.diffuse; 2316 } 2317#endif 2318 2319 float4 lit = getLitColor(vertex_light_color, albedo, i.worldPos, normal, 2320 metallic, 1.0 - roughness, i.uv0, ao, /*enable_direct=*/true, 2321 diffuse_contrib, i, tdata); 2322 2323#if defined(_GIMMICK_FOG_00) 2324 { 2325 if (round(_Gimmick_Fog_00_Overlay_Mode)) { 2326 Fog00PBR pbr = __getFog00(i, tdata, mul(unity_WorldToObject, float4(i.worldPos, 1.0)).xyz, tdata.screen_uv); 2327 lit = pbr.albedo + lit * (1 - pbr.albedo.a); 2328 } else { 2329 Fog00PBR pbr = getFog00(i, tdata); 2330 albedo = pbr.albedo; 2331 depth = pbr.depth; 2332#if defined(_RENDERING_TRANSPARENT) || defined(_RENDERING_TRANSCLIPPING) 2333 albedo.rgb *= albedo.a; 2334#endif 2335 return albedo; 2336 } 2337 } 2338#endif 2339 2340#if defined(_GIMMICK_LENS_00) 2341 { 2342 // Use tdata.screen_uv to sample 8x8 Bayer matrix. 2343 //uint2 screen_uv_round = floor(tdata.screen_uv * _ScreenParams.xy * _Gimmick_Lens_00_Scale); 2344 //uint2 screen_uv_round = floor(tdata.screen_uv * _ScreenParams.xy * _Gimmick_Lens_00_Scale); 2345 uint2 glasses_uv_round = floor(i.uv0 * _ScreenParams.xy * _Gimmick_Lens_00_Scale); 2346 uint2 bayer_idx = (glasses_uv_round % 8); 2347 float2 grab_uv = i.grabPos.xy / i.grabPos.w; 2348 float3 grab_color = _Tooner_Grabpass.SampleLevel(linear_clamp_s, grab_uv, 0).rgb; 2349#if defined(_GIMMICK_LENS_00_BAYER) 2350 float mask = BayerM8x8[bayer_idx.y * 8 + bayer_idx.x]; 2351 mask = frac(mask + frame * PHI * _Gimmick_Lens_00_Frame_Counter_Speed); 2352#elif defined(_GIMMICK_LENS_00_INTERLEAVED_GRADIENT_NOISE) 2353 float mask = ign(glasses_uv_round); 2354 mask = frac(mask + frame * PHI * _Gimmick_Lens_00_Frame_Counter_Speed); 2355#elif defined(_GIMMICK_LENS_00_SSFD) 2356 float3 mask = float3( 2357 ssfd(i.uv0, _Gimmick_Lens_00_SSFD_Scale / grab_color.r, _Gimmick_Lens_00_SSFD_Max_Fwidth, 0, _Gimmick_Lens_00_SSFD_Noise), 2358 ssfd(i.uv0, _Gimmick_Lens_00_SSFD_Scale / grab_color.g, _Gimmick_Lens_00_SSFD_Max_Fwidth, 0, _Gimmick_Lens_00_SSFD_Noise), 2359 ssfd(i.uv0, _Gimmick_Lens_00_SSFD_Scale / grab_color.b, _Gimmick_Lens_00_SSFD_Max_Fwidth, 0, _Gimmick_Lens_00_SSFD_Noise) 2360 ); 2361 mask = mask > grab_color * _Gimmick_Lens_00_SSFD_Size_Factor ? 1 : 0; 2362#endif 2363 2364 //grab_uv = floor(grab_uv * _ScreenParams.xy * _Gimmick_Lens_00_Scale) / (_ScreenParams.xy * _Gimmick_Lens_00_Scale); 2365 grab_color = round(grab_color * _Gimmick_Lens_00_Subdivisions) / _Gimmick_Lens_00_Subdivisions; 2366 lit.rgb = (grab_color > mask); 2367 //lit.rgb = mask; 2368 } 2369#endif 2370 2371#if defined(_GIMMICK_FLAT_COLOR) 2372 if (round(_Gimmick_Flat_Color_Enable_Dynamic)) { 2373#if defined(_RENDERING_CUTOUT) 2374#if defined(_RENDERING_CUTOUT_STOCHASTIC) 2375 float ar = rand2(i.uv0); 2376 clip(albedo.a - ar); 2377#else 2378 clip(albedo.a - _Alpha_Cutoff); 2379#endif 2380 albedo.a = 1; 2381#endif 2382 return float4(lit.rgb + 2383 _Gimmick_Flat_Color_Emission * _Global_Emission_Factor, 2384 albedo.a); 2385 } 2386#endif 2387 2388 float4 result = lit; 2389#if defined(_MATCAP0) || defined(_MATCAP1) || defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1) 2390 result.rgb += matcap_emission * _Global_Emission_Factor; 2391#endif 2392#if defined(_DECAL0) || defined(_DECAL1) || defined(_DECAL2) || defined(_DECAL3) || defined(_DECAL4) || defined(_DECAL5) || defined(_DECAL6) || defined(_DECAL7) || defined(_DECAL8) || defined(_DECAL9) 2393 result.rgb += decal_emission * _Global_Emission_Factor; 2394#endif 2395#if defined(_GLITTER) 2396 result.rgb += glitter_color_unlit * _Glitter_Brightness; 2397#endif 2398#if defined(_GIMMICK_DS2) 2399 result = ds2.fog + result * (1 - ds2.fog.a); 2400 result.rgb += ds2.emission * _Gimmick_DS2_Emission_Factor * ds2_mask; 2401#endif 2402 2403#if defined(_GIMMICK_FOG_01) 2404 [branch] 2405 if (_Gimmick_Fog_01_Overlay_Mode) { 2406 float4 fog_color = apply_fog( 2407 length(i.worldPos.xyz - getCenterCamPos()), 2408 _Gimmick_Fog_01_Density, 2409 normalize(i.worldPos.xyz - getCenterCamPos()), 2410 _Gimmick_Fog_01_Sun_Direction, 2411 _Gimmick_Fog_01_Sun_Color, 2412 _Gimmick_Fog_01_Sun_Exponent, 2413 _Gimmick_Fog_01_Sun_Color_2_Enable, 2414 _Gimmick_Fog_01_Sun_Color_2, 2415 _Gimmick_Fog_01_Sun_Exponent_2, 2416 _Gimmick_Fog_01_Color 2417 ); 2418 result.xyz = fog_color * fog_color.a + result * (1 - fog_color.a); 2419 } 2420#endif 2421 2422#if defined(_ACES_FILMIC) 2423 result.rgb = aces_filmic(max(result.rgb, 0)); 2424#endif 2425 2426 // This version exists for compatibility with the Bakery lightmapper. We 2427 // specifically need to expose _EmissionMap and _EmissionColor. 2428#if defined(_EMISSION) 2429 { 2430 float3 emission = _EmissionMap.SampleBias(linear_repeat_s, i.uv0, _Global_Sample_Bias); 2431 result.rgb += emission * _EmissionColor * _Global_Emission_Factor; 2432 } 2433#endif 2434#if defined(_EMISSION0) 2435 { 2436 float3 emission = _Emission0Tex.SampleBias(linear_repeat_s, get_uv_by_channel(i, round(_Emission0_UV_Select)), _Global_Sample_Bias); 2437 result.rgb += emission * _Emission0Color * 2438 _Global_Emission_Factor * _Emission0Multiplier; 2439 } 2440#endif 2441#if defined(_EMISSION1) 2442 { 2443 float3 emission = _Emission1Tex.SampleBias(linear_repeat_s, get_uv_by_channel(i, round(_Emission1_UV_Select)), _Global_Sample_Bias); 2444 result.rgb += emission * _Emission1Color * 2445 _Global_Emission_Factor * _Emission1Multiplier; 2446 } 2447#endif 2448#if defined(_RORSCHACH) 2449 result.rgb += rorschach_albedo.rgb * _Rorschach_Emission_Strength; 2450#endif 2451#if defined(_GIMMICK_LETTER_GRID) 2452 result.rgb += gimmick_letter_grid_emission; 2453#endif 2454#if defined(_GIMMICK_LETTER_GRID_2) 2455 result.rgb += gimmick_letter_grid_2_emission; 2456#endif 2457 2458#if defined(_EXPLODE) && defined(_AUDIOLINK) 2459 if (AudioLinkIsAvailable() && _Explode_Phase > 1E-6) { 2460 float4 al_color = 2461 AudioLinkData( 2462 ALPASS_CCLIGHTS + 2463 uint2(uint(i.uv0.x * 8) + uint(i.uv0.y * 16) * 8, 0 )).rgba; 2464 result = lerp(result, al_color, _Explode_Phase * _Explode_Phase); 2465 } 2466#endif 2467#if defined(_RENDERING_TRANSPARENT) || defined(_RENDERING_TRANSCLIPPING) 2468 result.rgb *= result.a; 2469#endif 2470 result.rgb += getOverlayEmission(ov, i) * _Global_Emission_Factor; 2471 result.rgb += _Global_Emission_Additive_Factor * albedo.rgb; 2472 2473#if defined(_SURFACE_STABLE_FRACTAL_DITHERING) 2474 [branch] 2475 if (_Surface_Stable_Fractal_Dithering_Enable_Dynamic) { 2476 float3 c = result.rgb * _Surface_Stable_Fractal_Dithering_Brightness_Factor; 2477 // Let's draw dots at the vertices of an equilateral triangle. 2478 // The internal angle is 60 degrees. 2479 // sin(60d) = sqrt(3) / 2 2480 // cos(60d) = 1 / 2 2481#if 1 2482 float3 mask = float3( 2483 ssfd(i.uv0, _Surface_Stable_Fractal_Dithering_Scale / c.r, 2484 _Surface_Stable_Fractal_Dithering_Max_Fwidth, 2485 _Surface_Stable_Fractal_Dithering_UV_Offset_R, 2486 _Surface_Stable_Fractal_Dithering_Noise), 2487 ssfd(i.uv0, _Surface_Stable_Fractal_Dithering_Scale / c.g, 2488 _Surface_Stable_Fractal_Dithering_Max_Fwidth, 2489 _Surface_Stable_Fractal_Dithering_UV_Offset_G, 2490 _Surface_Stable_Fractal_Dithering_Noise), 2491 ssfd(i.uv0, _Surface_Stable_Fractal_Dithering_Scale / c.b, 2492 _Surface_Stable_Fractal_Dithering_Max_Fwidth, 2493 _Surface_Stable_Fractal_Dithering_UV_Offset_B, 2494 _Surface_Stable_Fractal_Dithering_Noise) 2495 ); 2496 float3 thresholded = lerp(0, 1, mask > 1 - c * _Surface_Stable_Fractal_Dithering_Size_Factor); 2497#else 2498 float cc = length(c) / sqrt(3); 2499 float mask = ssfd(i.uv0, _Surface_Stable_Fractal_Dithering_Scale / cc, 2500 _Surface_Stable_Fractal_Dithering_Max_Fwidth, 2501 0.8, 2502 _Surface_Stable_Fractal_Dithering_Noise); 2503 float3 thresholded = lerp(0, 1, mask > 1 - cc * _Surface_Stable_Fractal_Dithering_Size_Factor); 2504#endif 2505 2506 result.rgb = thresholded; 2507 } 2508#endif 2509 2510 2511 return result; 2512} 2513 2514fixed4 frag_debug(v2f i) 2515{ 2516 float3 view_dir = normalize(_WorldSpaceCameraPos - i.worldPos); 2517 float3 indirect_specular = getIndirectSpecular(i, view_dir, i.normal, 2518 /*smoothness=*/1, /*metallic=*/0, i.worldPos); 2519 const float3 l = reflect(-view_dir, i.normal); 2520 const float3 h = normalize(l + view_dir); 2521 const float NoH = dot(i.normal, h); 2522 return float4(saturate(NoH) * indirect_specular, 1); 2523} 2524 2525fixed4 frag(v2f i 2526#if defined(EXPERIMENT__CUSTOM_DEPTH) 2527, out float depth: SV_DepthGreaterEqual 2528#endif 2529 ) : SV_Target 2530{ 2531#if !defined(EXPERIMENT__CUSTOM_DEPTH) 2532 float depth; 2533#endif 2534 UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy); 2535 UNITY_SETUP_INSTANCE_ID(i); 2536 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); 2537 2538/* 2539#if defined(_TROCHOID) 2540 float3x3 vector_mover = cyl2_to_troch_jacobian(i.objPos_pre_trochoid); 2541 float det = determinant(vector_mover); 2542 det = saturate(abs(det)); 2543 return float4(det, det, det, 1); 2544#endif 2545*/ 2546 2547 return FILTER_COLOR(effect(i, depth)); 2548} 2549 2550#endif // TOONER_LIGHTING 2551