yum-archive/2ner
A toon shader for Unity's BIRP.
git clone https://git.yummers.dev/yum-archive/2ner
0a8d744
master
1#ifndef __FILAMENTED_INC 2#define __FILAMENTED_INC 3 4#include "SharedSamplingLib.hlsl" 5#include "SharedFilteringLib.hlsl" 6 7#include "UnityImageBasedLighting.cginc" 8#include "UnityStandardUtils.cginc" 9 10#include "data.cginc" 11#include "math.cginc" 12 13// I made changes to this code. 14 15/* 16 Apache License 17 Version 2.0, January 2004 18 http://www.apache.org/licenses/ 19 20 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 21 22 1. Definitions. 23 24 "License" shall mean the terms and conditions for use, reproduction, 25 and distribution as defined by Sections 1 through 9 of this document. 26 27 "Licensor" shall mean the copyright owner or entity authorized by 28 the copyright owner that is granting the License. 29 30 "Legal Entity" shall mean the union of the acting entity and all 31 other entities that control, are controlled by, or are under common 32 control with that entity. For the purposes of this definition, 33 "control" means (i) the power, direct or indirect, to cause the 34 direction or management of such entity, whether by contract or 35 otherwise, or (ii) ownership of fifty percent (50%) or more of the 36 outstanding shares, or (iii) beneficial ownership of such entity. 37 38 "You" (or "Your") shall mean an individual or Legal Entity 39 exercising permissions granted by this License. 40 41 "Source" form shall mean the preferred form for making modifications, 42 including but not limited to software source code, documentation 43 source, and configuration files. 44 45 "Object" form shall mean any form resulting from mechanical 46 transformation or translation of a Source form, including but 47 not limited to compiled object code, generated documentation, 48 and conversions to other media types. 49 50 "Work" shall mean the work of authorship, whether in Source or 51 Object form, made available under the License, as indicated by a 52 copyright notice that is included in or attached to the work 53 (an example is provided in the Appendix below). 54 55 "Derivative Works" shall mean any work, whether in Source or Object 56 form, that is based on (or derived from) the Work and for which the 57 editorial revisions, annotations, elaborations, or other modifications 58 represent, as a whole, an original work of authorship. For the purposes 59 of this License, Derivative Works shall not include works that remain 60 separable from, or merely link (or bind by name) to the interfaces of, 61 the Work and Derivative Works thereof. 62 63 "Contribution" shall mean any work of authorship, including 64 the original version of the Work and any modifications or additions 65 to that Work or Derivative Works thereof, that is intentionally 66 submitted to Licensor for inclusion in the Work by the copyright owner 67 or by an individual or Legal Entity authorized to submit on behalf of 68 the copyright owner. For the purposes of this definition, "submitted" 69 means any form of electronic, verbal, or written communication sent 70 to the Licensor or its representatives, including but not limited to 71 communication on electronic mailing lists, source code control systems, 72 and issue tracking systems that are managed by, or on behalf of, the 73 Licensor for the purpose of discussing and improving the Work, but 74 excluding communication that is conspicuously marked or otherwise 75 designated in writing by the copyright owner as "Not a Contribution." 76 77 "Contributor" shall mean Licensor and any individual or Legal Entity 78 on behalf of whom a Contribution has been received by Licensor and 79 subsequently incorporated within the Work. 80 81 2. Grant of Copyright License. Subject to the terms and conditions of 82 this License, each Contributor hereby grants to You a perpetual, 83 worldwide, non-exclusive, no-charge, royalty-free, irrevocable 84 copyright license to reproduce, prepare Derivative Works of, 85 publicly display, publicly perform, sublicense, and distribute the 86 Work and such Derivative Works in Source or Object form. 87 88 3. Grant of Patent License. Subject to the terms and conditions of 89 this License, each Contributor hereby grants to You a perpetual, 90 worldwide, non-exclusive, no-charge, royalty-free, irrevocable 91 (except as stated in this section) patent license to make, have made, 92 use, offer to sell, sell, import, and otherwise transfer the Work, 93 where such license applies only to those patent claims licensable 94 by such Contributor that are necessarily infringed by their 95 Contribution(s) alone or by combination of their Contribution(s) 96 with the Work to which such Contribution(s) was submitted. If You 97 institute patent litigation against any entity (including a 98 cross-claim or counterclaim in a lawsuit) alleging that the Work 99 or a Contribution incorporated within the Work constitutes direct 100 or contributory patent infringement, then any patent licenses 101 granted to You under this License for that Work shall terminate 102 as of the date such litigation is filed. 103 104 4. Redistribution. You may reproduce and distribute copies of the 105 Work or Derivative Works thereof in any medium, with or without 106 modifications, and in Source or Object form, provided that You 107 meet the following conditions: 108 109 (a) You must give any other recipients of the Work or 110 Derivative Works a copy of this License; and 111 112 (b) You must cause any modified files to carry prominent notices 113 stating that You changed the files; and 114 115 (c) You must retain, in the Source form of any Derivative Works 116 that You distribute, all copyright, patent, trademark, and 117 attribution notices from the Source form of the Work, 118 excluding those notices that do not pertain to any part of 119 the Derivative Works; and 120 121 (d) If the Work includes a "NOTICE" text file as part of its 122 distribution, then any Derivative Works that You distribute must 123 include a readable copy of the attribution notices contained 124 within such NOTICE file, excluding those notices that do not 125 pertain to any part of the Derivative Works, in at least one 126 of the following places: within a NOTICE text file distributed 127 as part of the Derivative Works; within the Source form or 128 documentation, if provided along with the Derivative Works; or, 129 within a display generated by the Derivative Works, if and 130 wherever such third-party notices normally appear. The contents 131 of the NOTICE file are for informational purposes only and 132 do not modify the License. You may add Your own attribution 133 notices within Derivative Works that You distribute, alongside 134 or as an addendum to the NOTICE text from the Work, provided 135 that such additional attribution notices cannot be construed 136 as modifying the License. 137 138 You may add Your own copyright statement to Your modifications and 139 may provide additional or different license terms and conditions 140 for use, reproduction, or distribution of Your modifications, or 141 for any such Derivative Works as a whole, provided Your use, 142 reproduction, and distribution of the Work otherwise complies with 143 the conditions stated in this License. 144 145 5. Submission of Contributions. Unless You explicitly state otherwise, 146 any Contribution intentionally submitted for inclusion in the Work 147 by You to the Licensor shall be under the terms and conditions of 148 this License, without any additional terms or conditions. 149 Notwithstanding the above, nothing herein shall supersede or modify 150 the terms of any separate license agreement you may have executed 151 with Licensor regarding such Contributions. 152 153 6. Trademarks. This License does not grant permission to use the trade 154 names, trademarks, service marks, or product names of the Licensor, 155 except as required for reasonable and customary use in describing the 156 origin of the Work and reproducing the content of the NOTICE file. 157 158 7. Disclaimer of Warranty. Unless required by applicable law or 159 agreed to in writing, Licensor provides the Work (and each 160 Contributor provides its Contributions) on an "AS IS" BASIS, 161 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 162 implied, including, without limitation, any warranties or conditions 163 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 164 PARTICULAR PURPOSE. You are solely responsible for determining the 165 appropriateness of using or redistributing the Work and assume any 166 risks associated with Your exercise of permissions under this License. 167 168 8. Limitation of Liability. In no event and under no legal theory, 169 whether in tort (including negligence), contract, or otherwise, 170 unless required by applicable law (such as deliberate and grossly 171 negligent acts) or agreed to in writing, shall any Contributor be 172 liable to You for damages, including any direct, indirect, special, 173 incidental, or consequential damages of any character arising as a 174 result of this License or out of the use or inability to use the 175 Work (including but not limited to damages for loss of goodwill, 176 work stoppage, computer failure or malfunction, or any and all 177 other commercial damages or losses), even if such Contributor 178 has been advised of the possibility of such damages. 179 180 9. Accepting Warranty or Additional Liability. While redistributing 181 the Work or Derivative Works thereof, You may choose to offer, 182 and charge a fee for, acceptance of support, warranty, indemnity, 183 or other liability obligations and/or rights consistent with this 184 License. However, in accepting such obligations, You may act only 185 on Your own behalf and on Your sole responsibility, not on behalf 186 of any other Contributor, and only if You agree to indemnify, 187 defend, and hold each Contributor harmless for any liability 188 incurred by, or claims asserted against, such Contributor by reason 189 of your accepting any such warranty or additional liability. 190 191 END OF TERMS AND CONDITIONS 192 193 APPENDIX: How to apply the Apache License to your work. 194 195 To apply the Apache License to your work, attach the following 196 boilerplate notice, with the fields enclosed by brackets "[]" 197 replaced with your own identifying information. (Don't include 198 the brackets!) The text should be enclosed in the appropriate 199 comment syntax for the file format. We also recommend that a 200 file or class name and description of purpose be included on the 201 same "printed page" as the copyright notice for easier 202 identification within third-party archives. 203 204 Copyright [yyyy] [name of copyright owner] 205 206 Licensed under the Apache License, Version 2.0 (the "License"); 207 you may not use this file except in compliance with the License. 208 You may obtain a copy of the License at 209 210 http://www.apache.org/licenses/LICENSE-2.0 211 212 Unless required by applicable law or agreed to in writing, software 213 distributed under the License is distributed on an "AS IS" BASIS, 214 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 215 See the License for the specific language governing permissions and 216 limitations under the License. 217 218Unity Built-in Shaders 219 220Copyright (c) 2016 Unity Technologies 221 222Permission is hereby granted, free of charge, to any person obtaining a copy of 223this software and associated documentation files (the "Software"), to deal in 224the Software without restriction, including without limitation the rights to 225use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 226of the Software, and to permit persons to whom the Software is furnished to do 227so, subject to the following conditions: 228 229The above copyright notice and this permission notice shall be included in all 230copies or substantial portions of the Software. 231 232THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 233IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 234FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 235COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 236IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 237CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 238*/ 239 240// Check if Bakery is available 241#if defined(_BAKERY_RNM) || defined(_BAKERY_SH) || defined(_BAKERY_MONOSH) 242 #define USING_BAKERY 1 243#endif 244 245// Bakery textures (Unity auto-binds these) 246#if defined(_BAKERY_RNM) || defined(_BAKERY_SH) || defined(_BAKERY_MONOSH) 247TEXTURE2D(_RNM0); 248TEXTURE2D(_RNM1); 249TEXTURE2D(_RNM2); 250SAMPLER(sampler_RNM0); 251#endif 252 253 254 255#define MIN_PERCEPTUAL_ROUGHNESS 0.045 256 257// Filamented defines for spherical harmonics 258#define SPHERICAL_HARMONICS_DEFAULT 0 259#define SPHERICAL_HARMONICS_GEOMETRICS 1 260#define SPHERICAL_HARMONICS_ZH3 2 261#define SPHERICAL_HARMONICS SPHERICAL_HARMONICS_ZH3 262#define SPHERICAL_HARMONICS_USE_L2 0 263 264// Light struct from filamented 265struct Light { 266 float4 colorIntensity; 267 float3 l; 268 float attenuation; 269 float NoL; 270 float3 worldPosition; 271}; 272 273// Helper functions 274half getExposureOcclusionBias() 275{ 276 return 1.0/(_ExposureOcclusion); 277} 278 279bool getIsBakeryVertexMode() 280{ 281#if defined(USING_BAKERY_VERTEXLM) 282 #define BAKERYMODE_DEFAULT 0 283 #define BAKERYMODE_VERTEXLM 1.0f 284 #define BAKERYMODE_RNM 2.0f 285 #define BAKERYMODE_SH 3.0f 286 return (bakeryLightmapMode == BAKERYMODE_VERTEXLM); 287#endif 288 return false; 289} 290 291half getLightVolumeSurfaceBias() 292{ 293 #if defined(_VRCLV) 294 return _VRCLVSurfaceBias; 295 #else 296 return 0; 297 #endif 298} 299 300// Geomerics spherical harmonics evaluation 301float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n) 302{ 303 float R0 = max(L0, 0); 304 float3 R1 = 0.5f * L1; 305 float lenR1 = length(R1); 306 float q = dot(normalize(R1), n) * 0.5 + 0.5; 307 q = saturate(q); 308 float p = 1.0f + 2.0f * lenR1 / R0; 309 float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0); 310 return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p)); 311} 312 313// ZH3 constants and functions 314const static float L0IrradianceToRadiance = 2 * sqrt(UNITY_PI); 315const static float L1IrradianceToRadiance = sqrt(3 * UNITY_PI); 316const static float4 L0L1IrradianceToRadiance = float4(L0IrradianceToRadiance, L1IrradianceToRadiance, L1IrradianceToRadiance, L1IrradianceToRadiance); 317 318float SHEvalLinearL0L1_ZH3Hallucinate(float4 sh, float3 normal) 319{ 320 float4 radiance = sh * L0L1IrradianceToRadiance; 321 float3 zonalAxis = float3(radiance.w, radiance.y, radiance.z); 322 float l1Length = length(zonalAxis); 323 zonalAxis /= l1Length; 324 float ratio = l1Length / radiance.x; 325 float zonalL2Coeff = radiance.x * ratio * (0.08 + 0.6 * ratio); 326 float fZ = dot(zonalAxis, normal); 327 float zhNormal = sqrt(5.0f / (16.0f * UNITY_PI)) * (3.0f * fZ * fZ - 1.0f); 328 float result = dot(sh, float4(1, float3(normal.y, normal.z, normal.x))); 329 result += 0.25f * zhNormal * zonalL2Coeff; 330 return result; 331} 332 333float3 SHEvalLinearL0L1_ZH3Hallucinate(float3 normal) 334{ 335 float3 shL0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + 336 float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0; 337 float3 shL1_1 = float3(unity_SHAr.y, unity_SHAg.y, unity_SHAb.y); 338 float3 shL1_2 = float3(unity_SHAr.z, unity_SHAg.z, unity_SHAb.z); 339 float3 shL1_3 = float3(unity_SHAr.x, unity_SHAg.x, unity_SHAb.x); 340 341 float3 result = 0.0; 342 float4 a = float4(shL0.r, shL1_1.r, shL1_2.r, shL1_3.r); 343 float4 b = float4(shL0.g, shL1_1.g, shL1_2.g, shL1_3.g); 344 float4 c = float4(shL0.b, shL1_1.b, shL1_2.b, shL1_3.b); 345 result.r = SHEvalLinearL0L1_ZH3Hallucinate(a, normal); 346 result.g = SHEvalLinearL0L1_ZH3Hallucinate(b, normal); 347 result.b = SHEvalLinearL0L1_ZH3Hallucinate(c, normal); 348 return result; 349} 350 351float3 Irradiance_SphericalHarmonics(const float3 n, const bool useL2) { 352 float3 finalSH = float3(0,0,0); 353 354 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_DEFAULT) 355 finalSH = SHEvalLinearL0L1(half4(n, 1.0)); 356 #endif 357 358 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_GEOMETRICS) 359 float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); 360 float3 L0L2 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0; 361 L0 = (useL2) ? L0+L0L2 : L0-L0L2; 362 finalSH.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, n); 363 finalSH.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, n); 364 finalSH.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, n); 365 #endif 366 367 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_ZH3) 368 finalSH = SHEvalLinearL0L1_ZH3Hallucinate(half4(n, 1.0)); 369 #endif 370 371 #if (SPHERICAL_HARMONICS_USE_L2 == 1) 372 if (useL2) finalSH += SHEvalLinearL2(half4(n, 1.0)); 373 #endif 374 375 return finalSH; 376} 377 378float3 Irradiance_SphericalHarmonics(const float3 n) { 379 return Irradiance_SphericalHarmonics(n, true); 380} 381 382#if UNITY_LIGHT_PROBE_PROXY_VOLUME 383half3 Irradiance_SampleProbeVolume (half4 normal, float3 worldPos) 384{ 385 const float transformToLocal = unity_ProbeVolumeParams.y; 386 const float texelSizeX = unity_ProbeVolumeParams.z; 387 388 float3 position = (transformToLocal == 1.0f) ? mul(unity_ProbeVolumeWorldToObject, float4(worldPos, 1.0)).xyz : worldPos; 389 float3 texCoord = (position - unity_ProbeVolumeMin.xyz) * unity_ProbeVolumeSizeInv.xyz; 390 texCoord.x = texCoord.x * 0.25f; 391 392 float texCoordX = clamp(texCoord.x, 0.5f * texelSizeX, 0.25f - 0.5f * texelSizeX); 393 394 texCoord.x = texCoordX; 395 half4 SHAr = UNITY_SAMPLE_TEX3D_SAMPLER(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord); 396 397 texCoord.x = texCoordX + 0.25f; 398 half4 SHAg = UNITY_SAMPLE_TEX3D_SAMPLER(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord); 399 400 texCoord.x = texCoordX + 0.5f; 401 half4 SHAb = UNITY_SAMPLE_TEX3D_SAMPLER(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord); 402 403 half3 x1; 404 405 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_DEFAULT) 406 x1.r = dot(SHAr, normal); 407 x1.g = dot(SHAg, normal); 408 x1.b = dot(SHAb, normal); 409 #endif 410 411 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_GEOMETRICS) 412 x1.r = shEvaluateDiffuseL1Geomerics_local(SHAr.w, SHAr.rgb, normal); 413 x1.g = shEvaluateDiffuseL1Geomerics_local(SHAg.w, SHAg.rgb, normal); 414 x1.b = shEvaluateDiffuseL1Geomerics_local(SHAb.w, SHAb.rgb, normal); 415 #endif 416 417 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_ZH3) 418 x1.r = SHEvalLinearL0L1_ZH3Hallucinate(float4(SHAr.w, SHAr.rgb), normal); 419 x1.g = SHEvalLinearL0L1_ZH3Hallucinate(float4(SHAg.w, SHAg.rgb), normal); 420 x1.b = SHEvalLinearL0L1_ZH3Hallucinate(float4(SHAb.w, SHAb.rgb), normal); 421 #endif 422 423 return x1; 424} 425#endif 426 427#if defined(_VRCLV) 428half3 Irradiance_SampleVRCLightVolume(half3 normal, float3 worldPos, out Light derivedLight) 429{ 430 derivedLight = (Light)0; 431 float3 samplePos = worldPos + normal * getLightVolumeSurfaceBias(); 432 433 float3 L0, L1r, L1g, L1b; 434 LightVolumeSH(samplePos, L0, L1r, L1g, L1b); 435 436 half3 irradiance = 0.0; 437 438 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_DEFAULT) 439 irradiance.r = dot(L1r, normal.xyz) + L0.r; 440 irradiance.g = dot(L1g, normal.xyz) + L0.g; 441 irradiance.b = dot(L1b, normal.xyz) + L0.b; 442 #endif 443 444 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_GEOMETRICS) 445 irradiance.r = shEvaluateDiffuseL1Geomerics_local(L0.r, L1r, normal.xyz); 446 irradiance.g = shEvaluateDiffuseL1Geomerics_local(L0.g, L1g, normal.xyz); 447 irradiance.b = shEvaluateDiffuseL1Geomerics_local(L0.b, L1b, normal.xyz); 448 #endif 449 450 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_ZH3) 451 irradiance.r = shEvaluateDiffuseL1Geomerics_local(L0.r, L1r, normal.xyz); 452 irradiance.g = shEvaluateDiffuseL1Geomerics_local(L0.g, L1g, normal.xyz); 453 irradiance.b = shEvaluateDiffuseL1Geomerics_local(L0.b, L1b, normal.xyz); 454 #endif 455 456 #if defined(LIGHTMAP_SPECULAR) 457 float3 nL1x = float3(L1r[0], L1g[0], L1b[0]); 458 float3 nL1y = float3(L1r[1], L1g[1], L1b[1]); 459 float3 nL1z = float3(L1r[2], L1g[2], L1b[2]); 460 float3 dominantDir = float3(luminance(nL1x), luminance(nL1y), luminance(nL1z)); 461 462 derivedLight.l = dominantDir; 463 half directionality = max(FLT_EPS, length(derivedLight.l)); 464 derivedLight.l /= directionality; 465 466 derivedLight.colorIntensity = float4(irradiance * directionality, 1.0); 467 derivedLight.attenuation = directionality; 468 derivedLight.NoL = saturate(dot(normal, derivedLight.l)); 469 #endif 470 471 return irradiance; 472} 473 474half3 Irradiance_SampleVRCLightVolumeAdditive(half3 normal, float3 worldPos, out Light derivedLight) 475{ 476 derivedLight = (Light)0; 477 478 if (!_UdonLightVolumeEnabled || _UdonLightVolumeAdditiveCount == 0) return 0; 479 480 float3 L0, L1r, L1g, L1b; 481 LightVolumeAdditiveSH(worldPos, L0, L1r, L1g, L1b); 482 483 half3 irradiance = 0.0; 484 irradiance.r = dot(L1r, normal.xyz) + L0.r; 485 irradiance.g = dot(L1g, normal.xyz) + L0.g; 486 irradiance.b = dot(L1b, normal.xyz) + L0.b; 487 488 #if defined(LIGHTMAP_SPECULAR) 489 float3 nL1x = float3(L1r[0], L1g[0], L1b[0]); 490 float3 nL1y = float3(L1r[1], L1g[1], L1b[1]); 491 float3 nL1z = float3(L1r[2], L1g[2], L1b[2]); 492 float3 dominantDir = float3(luminance(nL1x), luminance(nL1y), luminance(nL1z)); 493 494 derivedLight.l = dominantDir; 495 half directionality = max(FLT_EPS, length(derivedLight.l)); 496 derivedLight.l /= directionality; 497 498 derivedLight.colorIntensity = float4(irradiance * directionality, 1.0); 499 derivedLight.attenuation = directionality; 500 derivedLight.NoL = saturate(dot(normal, derivedLight.l)); 501 #endif 502 503 return irradiance; 504} 505#endif 506 507half3 Irradiance_SphericalHarmonicsUnity (half3 normal, half3 ambient, float3 worldPos, out Light derivedLight) 508{ 509 half3 ambient_contrib = 0.0; 510 derivedLight = (Light)0; 511 512#if defined(_VRCLV) 513 #if UNITY_LIGHT_PROBE_PROXY_VOLUME 514 if (unity_ProbeVolumeParams.x == 1.0) 515 ambient_contrib = Irradiance_SampleProbeVolume(half4(normal, 1.0), worldPos); 516 else 517 ambient_contrib = Irradiance_SampleVRCLightVolume(normal, worldPos, derivedLight); 518 #else 519 ambient_contrib = Irradiance_SampleVRCLightVolume(normal, worldPos, derivedLight); 520 #endif 521 522 ambient += max(half3(0, 0, 0), ambient_contrib); 523 524 #ifdef UNITY_COLORSPACE_GAMMA 525 ambient = LinearToGammaSpace (ambient); 526 #endif 527 528 return ambient; 529#else 530 531 #if UNITY_SAMPLE_FULL_SH_PER_PIXEL 532 #if UNITY_LIGHT_PROBE_PROXY_VOLUME 533 if (unity_ProbeVolumeParams.x == 1.0) 534 ambient_contrib = Irradiance_SampleProbeVolume(half4(normal, 1.0), worldPos); 535 else 536 ambient_contrib = Irradiance_SphericalHarmonics(normal, true); 537 #else 538 ambient_contrib = Irradiance_SphericalHarmonics(normal, true); 539 #endif 540 541 ambient += max(half3(0, 0, 0), ambient_contrib); 542 543 #ifdef UNITY_COLORSPACE_GAMMA 544 ambient = LinearToGammaSpace(ambient); 545 #endif 546 #elif (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE 547 // Completely per-vertex 548 #else 549 #if UNITY_LIGHT_PROBE_PROXY_VOLUME 550 if (unity_ProbeVolumeParams.x == 1.0) 551 ambient_contrib = Irradiance_SampleProbeVolume (half4(normal, 1.0), worldPos); 552 else 553 ambient_contrib = Irradiance_SphericalHarmonics(normal, false); 554 #else 555 ambient_contrib = Irradiance_SphericalHarmonics(normal, false); 556 #endif 557 558 ambient = max(half3(0, 0, 0), ambient+ambient_contrib); 559 #ifdef UNITY_COLORSPACE_GAMMA 560 ambient = LinearToGammaSpace (ambient); 561 #endif 562 #endif 563 564 return ambient; 565#endif 566} 567 568float4 SampleLightmapBicubic(float2 uv) 569{ 570 #if defined(SHADER_API_D3D11) 571 float width, height; 572 unity_Lightmap.GetDimensions(width, height); 573 float4 unity_Lightmap_TexelSize = float4(width, height, 1.0/width, 1.0/height); 574 return SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(unity_Lightmap, samplerunity_Lightmap), 575 uv, unity_Lightmap_TexelSize); 576 #else 577 return SAMPLE_TEXTURE2D(unity_Lightmap, samplerunity_Lightmap, uv); 578 #endif 579} 580 581float4 SampleLightmapDirBicubic(float2 uv) 582{ 583 #if defined(SHADER_API_D3D11) && false 584 float width, height; 585 unity_LightmapInd.GetDimensions(width, height); 586 float4 unity_LightmapInd_TexelSize = float4(width, height, 1.0/width, 1.0/height); 587 return SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(unity_LightmapInd, samplerunity_Lightmap), 588 uv, unity_LightmapInd_TexelSize); 589 #else 590 return SAMPLE_TEXTURE2D(unity_LightmapInd, samplerunity_Lightmap, uv); 591 #endif 592} 593 594float4 SampleDynamicLightmapBicubic(float2 uv) 595{ 596 #if defined(SHADER_API_D3D11) 597 float width, height; 598 unity_DynamicLightmap.GetDimensions(width, height); 599 float4 unity_DynamicLightmap_TexelSize = float4(width, height, 1.0/width, 1.0/height); 600 return SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(unity_DynamicLightmap, samplerunity_DynamicLightmap), 601 uv, unity_DynamicLightmap_TexelSize); 602 #else 603 return SAMPLE_TEXTURE2D(unity_DynamicLightmap, samplerunity_DynamicLightmap, uv); 604 #endif 605} 606 607float4 SampleDynamicLightmapDirBicubic(float2 uv) 608{ 609 #if defined(SHADER_API_D3D11) && false 610 float width, height; 611 unity_DynamicDirectionality.GetDimensions(width, height); 612 float4 unity_DynamicDirectionality_TexelSize = float4(width, height, 1.0/width, 1.0/height); 613 return SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(unity_DynamicDirectionality, samplerunity_DynamicLightmap), 614 uv, unity_DynamicDirectionality_TexelSize); 615 #else 616 return SAMPLE_TEXTURE2D(unity_DynamicDirectionality, samplerunity_DynamicLightmap, uv); 617 #endif 618} 619 620inline float3 DecodeDirectionalLightmapSpecular(half3 color, half4 dirTex, half3 normalWorld, 621 const bool isRealtimeLightmap, fixed4 realtimeNormalTex, out Light o_light) 622{ 623 o_light = (Light)0; 624 o_light.colorIntensity = float4(color, 1.0); 625 o_light.l = dirTex.xyz * 2 - 1; 626 627 half directionality = max(0.001, length(o_light.l)); 628 o_light.l /= directionality; 629 630 #ifdef DYNAMICLIGHTMAP_ON 631 if (isRealtimeLightmap) 632 { 633 half3 realtimeNormal = realtimeNormalTex.xyz * 2 - 1; 634 o_light.colorIntensity /= max(0.125, dot(realtimeNormal, o_light.l)); 635 } 636 #endif 637 638 half3 ambient = o_light.colorIntensity * (1 - directionality); 639 o_light.colorIntensity = o_light.colorIntensity * directionality; 640 o_light.attenuation = directionality; 641 o_light.NoL = saturate(dot(normalWorld, o_light.l)); 642 643 return color; 644} 645 646#if defined(USING_BAKERY) && defined(LIGHTMAP_ON) 647float3 DecodeRNMLightmap(half3 color, half2 lightmapUV, half3 normalTangent, float3x3 tangentToWorld, out Light o_light) 648{ 649 const float rnmBasis0 = float3(0.816496580927726f, 0, 0.5773502691896258f); 650 const float rnmBasis1 = float3(-0.4082482904638631f, 0.7071067811865475f, 0.5773502691896258f); 651 const float rnmBasis2 = float3(-0.4082482904638631f, -0.7071067811865475f, 0.5773502691896258f); 652 653 float3 irradiance; 654 o_light = (Light)0; 655 656 #if defined(SHADER_API_D3D11) 657 float width, height; 658 _RNM0.GetDimensions(width, height); 659 float4 rnm_TexelSize = float4(width, height, 1.0/width, 1.0/height); 660 661 float3 rnm0 = DecodeLightmap(SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(_RNM0, sampler_RNM0), lightmapUV, rnm_TexelSize)); 662 float3 rnm1 = DecodeLightmap(SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(_RNM1, sampler_RNM0), lightmapUV, rnm_TexelSize)); 663 float3 rnm2 = DecodeLightmap(SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(_RNM2, sampler_RNM0), lightmapUV, rnm_TexelSize)); 664 #else 665 float3 rnm0 = DecodeLightmap(SAMPLE_TEXTURE2D(_RNM0, sampler_RNM0, lightmapUV)); 666 float3 rnm1 = DecodeLightmap(SAMPLE_TEXTURE2D(_RNM1, sampler_RNM0, lightmapUV)); 667 float3 rnm2 = DecodeLightmap(SAMPLE_TEXTURE2D(_RNM2, sampler_RNM0, lightmapUV)); 668 #endif 669 670 normalTangent.g *= -1; 671 672 irradiance = saturate(dot(rnmBasis0, normalTangent)) * rnm0 673 + saturate(dot(rnmBasis1, normalTangent)) * rnm1 674 + saturate(dot(rnmBasis2, normalTangent)) * rnm2; 675 676 #if defined(LIGHTMAP_SPECULAR) 677 float3 dominantDirT = rnmBasis0 * luminance(rnm0) + 678 rnmBasis1 * luminance(rnm1) + 679 rnmBasis2 * luminance(rnm2); 680 681 float3 dominantDirTN = normalize(dominantDirT); 682 float3 specColor = saturate(dot(rnmBasis0, dominantDirTN)) * rnm0 + 683 saturate(dot(rnmBasis1, dominantDirTN)) * rnm1 + 684 saturate(dot(rnmBasis2, dominantDirTN)) * rnm2; 685 686 o_light.l = normalize(mul(tangentToWorld, dominantDirT)); 687 half directionality = max(0.001, length(o_light.l)); 688 o_light.l /= directionality; 689 690 o_light.colorIntensity = float4(specColor * directionality, 1.0); 691 o_light.attenuation = directionality; 692 o_light.NoL = saturate(dot(normalTangent, dominantDirTN)); 693 #endif 694 695 return irradiance; 696} 697 698float3 DecodeSHLightmap(half3 L0, half2 lightmapUV, half3 normalWorld, out Light o_light) 699{ 700 float3 irradiance; 701 o_light = (Light)0; 702 703 #if defined(SHADER_API_D3D11) 704 float width, height; 705 _RNM0.GetDimensions(width, height); 706 float4 rnm_TexelSize = float4(width, height, 1.0/width, 1.0/height); 707 708 float3 nL1x = SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(_RNM0, sampler_RNM0), lightmapUV, rnm_TexelSize); 709 float3 nL1y = SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(_RNM1, sampler_RNM0), lightmapUV, rnm_TexelSize); 710 float3 nL1z = SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(_RNM2, sampler_RNM0), lightmapUV, rnm_TexelSize); 711 #else 712 float3 nL1x = SAMPLE_TEXTURE2D(_RNM0, sampler_RNM0, lightmapUV); 713 float3 nL1y = SAMPLE_TEXTURE2D(_RNM1, sampler_RNM0, lightmapUV); 714 float3 nL1z = SAMPLE_TEXTURE2D(_RNM2, sampler_RNM0, lightmapUV); 715 #endif 716 717 nL1x = nL1x * 2 - 1; 718 nL1y = nL1y * 2 - 1; 719 nL1z = nL1z * 2 - 1; 720 float3 L1x = nL1x * L0 * 2; 721 float3 L1y = nL1y * L0 * 2; 722 float3 L1z = nL1z * L0 * 2; 723 724 #ifdef BAKERY_SHNONLINEAR 725 float lumaL0 = dot(L0, float(1)); 726 float lumaL1x = dot(L1x, float(1)); 727 float lumaL1y = dot(L1y, float(1)); 728 float lumaL1z = dot(L1z, float(1)); 729 730 float lumaSH = shEvaluateDiffuseL1Geomerics_local(lumaL0, float3(lumaL1x, lumaL1y, lumaL1z), normalWorld); 731 732 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_ZH3) 733 lumaSH = SHEvalLinearL0L1_ZH3Hallucinate(float4(lumaL0, lumaL1y, lumaL1z, lumaL1x), normalWorld); 734 #endif 735 736 irradiance = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; 737 float regularLumaSH = dot(irradiance, 1); 738 irradiance *= lerp(1, lumaSH / regularLumaSH, saturate(regularLumaSH*16)); 739 #else 740 irradiance = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; 741 #endif 742 743 #if defined(LIGHTMAP_SPECULAR) 744 float3 dominantDir = float3(luminance(nL1x), luminance(nL1y), luminance(nL1z)); 745 746 o_light.l = dominantDir; 747 half directionality = max(0.001, length(o_light.l)); 748 o_light.l /= directionality; 749 750 o_light.colorIntensity = float4(irradiance * directionality, 1.0); 751 o_light.attenuation = directionality; 752 o_light.NoL = saturate(dot(normalWorld, o_light.l)); 753 #endif 754 755 return irradiance; 756} 757 758float3 DecodeSHLightmapVertex(half3 L0, half3 ambientSH[3], half3 normalWorld, out Light o_light) 759{ 760 float3 irradiance; 761 o_light = (Light)0; 762 763 float3 nL1x = ambientSH[0]; 764 float3 nL1y = ambientSH[1]; 765 float3 nL1z = ambientSH[2]; 766 767 nL1x = nL1x * 2 - 1; 768 nL1y = nL1y * 2 - 1; 769 nL1z = nL1z * 2 - 1; 770 float3 L1x = nL1x * L0 * 2; 771 float3 L1y = nL1y * L0 * 2; 772 float3 L1z = nL1z * L0 * 2; 773 774 #ifdef BAKERY_SHNONLINEAR 775 float lumaL0 = dot(L0, float(1)); 776 float lumaL1x = dot(L1x, float(1)); 777 float lumaL1y = dot(L1y, float(1)); 778 float lumaL1z = dot(L1z, float(1)); 779 float lumaSH = shEvaluateDiffuseL1Geomerics_local(lumaL0, float3(lumaL1x, lumaL1y, lumaL1z), normalWorld); 780 781 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_ZH3) 782 lumaSH = SHEvalLinearL0L1_ZH3Hallucinate(float4(lumaL0, lumaL1y, lumaL1z, lumaL1x), normalWorld); 783 #endif 784 785 irradiance = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; 786 float regularLumaSH = dot(irradiance, 1); 787 irradiance *= lerp(1, lumaSH / regularLumaSH, saturate(regularLumaSH*16)); 788 #else 789 irradiance = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; 790 #endif 791 792 #if defined(LIGHTMAP_SPECULAR) 793 float3 dominantDir = float3(luminance(nL1x), luminance(nL1y), luminance(nL1z)); 794 795 o_light.l = dominantDir; 796 half directionality = max(0.001, length(o_light.l)); 797 o_light.l /= directionality; 798 799 o_light.colorIntensity = float4(irradiance * directionality, 1.0); 800 o_light.attenuation = directionality; 801 o_light.NoL = saturate(dot(normalWorld, o_light.l)); 802 #endif 803 804 return irradiance; 805} 806#endif 807 808#if defined(_BAKERY_MONOSH) 809float3 DecodeMonoSHLightmap(half3 L0, half3 dominantDir, half3 normalWorld, out Light o_light, const bool remapDir = true) 810{ 811 o_light = (Light)0; 812 813 float3 nL1 = remapDir? dominantDir * 2 - 1 : dominantDir; 814 float3 L1x = nL1.x * L0 * 2; 815 float3 L1y = nL1.y * L0 * 2; 816 float3 L1z = nL1.z * L0 * 2; 817 818 float3 sh; 819 820 #if BAKERY_SHNONLINEAR 821 float lumaL0 = dot(L0, 1); 822 float lumaL1x = dot(L1x, 1); 823 float lumaL1y = dot(L1y, 1); 824 float lumaL1z = dot(L1z, 1); 825 float lumaSH = shEvaluateDiffuseL1Geomerics_local(lumaL0, float3(lumaL1x, lumaL1y, lumaL1z), normalWorld); 826 827 #if (SPHERICAL_HARMONICS == SPHERICAL_HARMONICS_ZH3) 828 lumaSH = SHEvalLinearL0L1_ZH3Hallucinate(float4(lumaL0, lumaL1y, lumaL1z, lumaL1x), normalWorld); 829 #endif 830 831 sh = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; 832 float regularLumaSH = dot(sh, 1); 833 834 sh *= lerp(1, lumaSH / regularLumaSH, saturate(regularLumaSH*16)); 835 #else 836 sh = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; 837 #endif 838 839 #if defined(LIGHTMAP_SPECULAR) 840 dominantDir = nL1; 841 842 o_light.l = dominantDir; 843 half directionality = max(0.001, length(o_light.l)); 844 o_light.l /= directionality; 845 846 o_light.colorIntensity = float4(L0 * directionality, 1.0); 847 o_light.attenuation = directionality; 848 o_light.NoL = saturate(dot(normalWorld, o_light.l)); 849 #endif 850 851 return sh; 852} 853#endif 854 855float IrradianceToExposureOcclusion(float3 irradiance) 856{ 857 return saturate(length(irradiance + FLT_EPS) * getExposureOcclusionBias()); 858} 859 860float3 specularDFG(const float3 dfg, const float3 f0) { 861 return lerp(dfg.xxx, dfg.yyy, f0); 862} 863 864float D_GGX(float roughness, float NoH, const float3 h) { 865 // Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces" 866 867 // In mediump, there are two problems computing 1.0 - NoH^2 868 // 1) 1.0 - NoH^2 suffers floating point cancellation when NoH^2 is close to 1 (highlights) 869 // 2) NoH doesn't have enough precision around 1.0 870 // Both problem can be fixed by computing 1-NoH^2 in highp and providing NoH in highp as well 871 872 // However, we can do better using Lagrange's identity: 873 // ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2 874 // since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2 875 // This computes 1.0 - NoH^2 directly (which is close to zero in the highlights and has 876 // enough precision). 877 // Overall this yields better performance, keeping all computations in mediump 878 // Not available without reworking to pass NxH to the function 879 float oneMinusNoHSquared = 1.0 - NoH * NoH; 880 float a = NoH * roughness; 881 float k = roughness / (oneMinusNoHSquared + a * a); 882 float d = k * k * (1.0 / PI); 883 return d; 884} 885 886// t = tangent vector, b = bitangent vector 887float D_GGX_Anisotropic(float at, float ab, float NoH, 888 const float3 h, 889 const float3 t, const float3 b) { 890 float ToH = dot(t, h); 891 float BoH = dot(b, h); 892 float a2 = at * ab; 893 float3 v = float3(ab * ToH, at * BoH, a2 * NoH); 894 float v2 = dot(v, v); 895 float w2 = a2 / v2; 896 return a2 * w2 * w2 * (1.0 / PI); 897} 898 899float F_Schlick(float f0, float VoH) { 900 return f0 + (1.0 - f0) * pow5(1.0 - VoH); 901} 902 903float F_Schlick(float f0, float f90, float VoH) { 904 // Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering" 905 return f0 + (f90 - f0) * pow5(1.0 - VoH); 906} 907 908float3 F_Schlick(const float3 f0, float VoH) { 909 float f = pow5(1.0 - VoH); 910 return f + f0 * (1.0 - f); 911} 912 913float3 F_Schlick(const float3 f0, float f90, float VoH) { 914 // Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering" 915 return f0 + (f90 - f0) * pow5(1.0 - VoH); 916} 917 918float Fd_Lambert() { 919 return 1.0 / PI; 920} 921 922float Fd_Burley(float roughness, float NoV, float NoL, float LoH) { 923 // Burley 2012, "Physically-Based Shading at Disney" 924 float f90 = 0.5 + 2.0 * roughness * LoH * LoH; 925 float lightScatter = F_Schlick(1.0, f90, NoL); 926 float viewScatter = F_Schlick(1.0, f90, NoV); 927 return lightScatter * viewScatter * (1.0 / PI); 928} 929 930float V_SmithGGXCorrelated(float roughness, float NoV, float NoL) { 931 // Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs" 932 float a2 = roughness * roughness; 933 float lambdaV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2); 934 float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2); 935 float v = 0.5 / (lambdaV + lambdaL); 936 return v; 937} 938 939float V_SmithGGXCorrelated_Fast(float roughness, float NoV, float NoL) { 940 // Hammon 2017, "PBR Diffuse Lighting for GGX+Smith Microsurfaces" 941 float v = 0.5 / lerp(2.0 * NoL * NoV, NoL + NoV, roughness); 942 return v; 943} 944 945float V_SmithGGXCorrelated_Anisotropic(float at, float ab, float ToV, float BoV, 946 float ToL, float BoL, float NoV, float NoL) { 947 float lambdaV = NoL * length(float3(at * ToV, ab * BoV, NoV)); 948 float lambdaL = NoV * length(float3(at * ToL, ab * BoL, NoL)); 949 float v = 0.5 / (lambdaV + lambdaL); 950 return saturate(v); 951} 952 953float perceptualRoughnessToRoughness(float perceptualRoughness) { 954 return perceptualRoughness * perceptualRoughness; 955} 956 957float roughnessToPerceptualRoughness(float roughness) { 958 return sqrt(roughness); 959} 960 961float normalFiltering(float perceptualRoughness, const float3 worldNormal) { 962 // Kaplanyan 2016, "Stable specular highlights" 963 // Tokuyoshi 2017, "Error Reduction and Simplification for Shading Anti-Aliasing" 964 // Tokuyoshi and Kaplanyan 2019, "Improved Geometric Specular Antialiasing" 965 966 // This implementation is meant for deferred rendering in the original paper but 967 // we use it in forward rendering as well (as discussed in Tokuyoshi and Kaplanyan 968 // 2019). The main reason is that the forward version requires an expensive transform 969 // of the half vector by the tangent frame for every light. This is therefore an 970 // approximation but it works well enough for our needs and provides an improvement 971 // over our original implementation based on Vlachos 2015, "Advanced VR Rendering". 972 973 float3 du = ddx(worldNormal); 974 float3 dv = ddy(worldNormal); 975 976 float variance = _specularAntiAliasingVariance * (dot(du, du) + dot(dv, dv)); 977 978 float roughness = perceptualRoughnessToRoughness(perceptualRoughness); 979 float kernelRoughness = min(2.0 * variance, _specularAntiAliasingThreshold); 980 float squareRoughness = saturate(roughness * roughness + kernelRoughness); 981 982 return roughnessToPerceptualRoughness(sqrt(squareRoughness)); 983} 984 985float3 energyCompensation(float3 dfg, float3 f0) 986{ 987 // Energy compensation for multiple scattering in a microfacet model 988 // See "Multiple-Scattering Microfacet BSDFs with the Smith Model" 989 return 1.0 + f0 * (1.0 / dfg.yyy - 1.0); 990} 991 992half3 Unity_GlossyEnvironment_local (UNITY_ARGS_TEXCUBE(tex), half4 hdr, Unity_GlossyEnvironmentData glossIn) 993{ 994 half perceptualRoughness = glossIn.roughness /* perceptualRoughness */ ; 995 996 // Workaround for issue where objects are blurrier than they should be 997 // due to specular AA. 998 float roughnessAdjustment = 1-perceptualRoughness; 999 roughnessAdjustment = MIN_PERCEPTUAL_ROUGHNESS * roughnessAdjustment * roughnessAdjustment; 1000 perceptualRoughness = perceptualRoughness - roughnessAdjustment; 1001 1002 // Unity derivation 1003 perceptualRoughness = perceptualRoughness*(1.7 - 0.7 * perceptualRoughness); 1004 // Filament derivation 1005 // perceptualRoughness = perceptualRoughness * (2.0 - perceptualRoughness); 1006 half mip = perceptualRoughnessToMipmapLevel(perceptualRoughness); 1007 half3 R = glossIn.reflUVW; 1008 half4 rgbm = UNITY_SAMPLE_TEXCUBE_LOD(tex, R, mip); 1009 1010 return DecodeHDR(rgbm, hdr); 1011} 1012 1013inline half3 UnityGI_prefilteredRadiance(const UnityGIInput data, 1014 const float perceptualRoughness, const float3 r) { 1015 half3 specular; 1016 1017 Unity_GlossyEnvironmentData glossIn = (Unity_GlossyEnvironmentData)0; 1018 glossIn.roughness = perceptualRoughness; 1019 glossIn.reflUVW = r; 1020 1021#ifdef UNITY_SPECCUBE_BOX_PROJECTION 1022 // we will tweak reflUVW in glossIn directly (as we pass it to Unity_GlossyEnvironment twice for probe0 and pr obe1), so keep original to pass into BoxProjectedCubemapDirection 1023 half3 originalReflUVW = glossIn.reflUVW; 1024 glossIn.reflUVW = BoxProjectedCubemapDirection(originalReflUVW, 1025 data.worldPos, data.probePosition[0], data.boxMin[0], data.boxMax[0]); 1026#endif 1027 1028#ifdef _GLOSSYREFLECTIONS_OFF 1029 specular = unity_IndirectSpecColor.rgb; 1030#else 1031 half3 env0 = Unity_GlossyEnvironment_local (UNITY_PASS_TEXCUBE(unity_SpecCube0), data.probeHDR[0], glossIn); 1032#ifdef UNITY_SPECCUBE_BLENDING 1033 const float kBlendFactor = 0.99999; 1034 float blendLerp = data.boxMin[0].w; 1035 UNITY_BRANCH 1036 if (blendLerp < kBlendFactor) 1037 { 1038#ifdef UNITY_SPECCUBE_BOX_PROJECTION 1039 glossIn.reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition [1], data.boxMin[1], data.boxMax[1]); 1040#endif // UNITY_SPECCUBE_BOX_PROJECTION 1041 1042 half3 env1 = Unity_GlossyEnvironment_local (UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1,unity_SpecCube0 ), data.probeHDR[1], glossIn); 1043 specular = lerp(env1, env0, blendLerp); } 1044 else 1045 { 1046 specular = env0; 1047 } 1048#else 1049 specular = env0; 1050#endif // UNITY_SPECCUBE_BLENDING 1051#endif // _GLOSSYREFLECTIONS_OFF 1052 1053 return specular; 1054} 1055 1056// R dither mask 1057float noiseR2(float2 pixel) { 1058 const float a1 = 0.75487766624669276; 1059 const float a2 = 0.569840290998; 1060 return frac(a1 * float(pixel.x) + a2 * float(pixel.y)); 1061} 1062 1063// Return light probes or lightmap. 1064// Port of UnityGI_Irradiance without ShadingParams 1065float3 UnityGI_Irradiance( 1066 float3 worldNormal, 1067 float3 worldPos, 1068 float4 lightmapUV, 1069 float3 ambient, 1070 float attenuation, 1071 float3 tangentNormal, 1072 float3x3 tangentToWorld, 1073 #if defined(USING_BAKERY_VERTEXLMSH) 1074 float3 ambientSH[3], 1075 #elif defined(USING_BAKERY_VERTEXLMDIR) 1076 float3 ambientDir, 1077 #endif 1078 out float occlusion, 1079 out Light derivedLight) 1080{ 1081 float3 irradiance = ambient; 1082 float3 irradianceForAO; 1083 occlusion = 1.0; 1084 derivedLight = (Light)0; 1085 1086 #if UNITY_SHOULD_SAMPLE_SH 1087 irradiance += Irradiance_SphericalHarmonicsUnity(worldNormal, ambient, worldPos, derivedLight); 1088 #endif 1089 1090 irradianceForAO = irradiance; 1091 1092 // Should be stripped out at compile time if vertex LM mode is disabled. 1093 if (getIsBakeryVertexMode() == false) 1094 { 1095 #if defined(LIGHTMAP_ON) 1096 // Baked lightmaps 1097 half4 bakedColorTex = SampleLightmapBicubic(lightmapUV.xy); 1098 half3 bakedColor = DecodeLightmap(bakedColorTex); 1099 1100 #ifdef DIRLIGHTMAP_COMBINED 1101 fixed4 bakedDirTex = SampleLightmapDirBicubic(lightmapUV.xy); 1102 1103 // Bakery's MonoSH mode replaces the regular directional lightmap 1104 #if defined(_BAKERY_MONOSH) 1105 irradiance = DecodeMonoSHLightmap(bakedColor, bakedDirTex, worldNormal, derivedLight); 1106 1107 irradianceForAO = irradiance; 1108 1109 #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) 1110 irradiance = SubtractMainLightWithRealtimeAttenuationFromLightmap(irradiance, attenuation, bakedColorTex, worldNormal); 1111 #endif 1112 #else 1113 irradiance = DecodeDirectionalLightmap(bakedColor, bakedDirTex, worldNormal); 1114 1115 irradianceForAO = irradiance; 1116 1117 #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) 1118 irradiance = SubtractMainLightWithRealtimeAttenuationFromLightmap(irradiance, attenuation, bakedColorTex, worldNormal); 1119 #endif 1120 1121 #if defined(LIGHTMAP_SPECULAR) 1122 irradiance = DecodeDirectionalLightmapSpecular(bakedColor, bakedDirTex, worldNormal, false, 0, derivedLight); 1123 #endif 1124 #endif 1125 1126 #else // not directional lightmap 1127 1128 #if defined(USING_BAKERY) 1129 #if defined(_BAKERY_RNM) 1130 // bakery rnm mode 1131 irradiance = DecodeRNMLightmap(0, lightmapUV.xy, tangentNormal, tangentToWorld, derivedLight); 1132 #endif 1133 1134 #if defined(_BAKERY_SH) 1135 // bakery sh mode 1136 irradiance = DecodeSHLightmap(bakedColor, lightmapUV.xy, worldNormal, derivedLight); 1137 #endif 1138 1139 irradianceForAO = irradiance; 1140 1141 #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) 1142 irradiance = SubtractMainLightWithRealtimeAttenuationFromLightmap(irradiance, attenuation, bakedColorTex, worldNormal); 1143 #endif 1144 1145 #else 1146 1147 irradiance += bakedColor; 1148 1149 irradianceForAO = irradiance; 1150 1151 #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) 1152 irradiance = SubtractMainLightWithRealtimeAttenuationFromLightmap(irradiance, attenuation, bakedColorTex, worldNormal); 1153 #endif 1154 #endif 1155 1156 #endif 1157 #endif 1158 } 1159 1160 #if defined(USING_BAKERY_VERTEXLM) 1161 if (getIsBakeryVertexMode() == true) 1162 { 1163 // Lightmap colour is already stored in ambient. 1164 // If directionality is on, then ambientDir contains directionality. 1165 // If SH is on, then ambientSH[3] contains the SH data. 1166 half4 bakedColorTex = float4(ambient, 1.0); 1167 1168 #if defined(USING_BAKERY_VERTEXLMSH) 1169 irradiance = DecodeSHLightmapVertex(ambient, ambientSH, worldNormal, derivedLight); 1170 irradianceForAO = irradiance; 1171 #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) 1172 irradiance = SubtractMainLightWithRealtimeAttenuationFromLightmap(irradiance, attenuation, bakedColorTex, worldNormal); 1173 #endif 1174 #else 1175 #if defined(USING_BAKERY_VERTEXLMDIR) 1176 #if defined(_BAKERY_MONOSH) 1177 irradiance = DecodeMonoSHLightmap(ambient, ambientDir, worldNormal, derivedLight, false); 1178 irradianceForAO = irradiance; 1179 #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) 1180 irradiance = SubtractMainLightWithRealtimeAttenuationFromLightmap(irradiance, attenuation, bakedColorTex, worldNormal); 1181 #endif 1182 #else 1183 irradiance = DecodeDirectionalLightmap(ambient, ambientDir, worldNormal); 1184 irradianceForAO = irradiance; 1185 #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) 1186 irradiance = SubtractMainLightWithRealtimeAttenuationFromLightmap(irradiance, attenuation, bakedColorTex, worldNormal); 1187 #endif 1188 #if defined(LIGHTMAP_SPECULAR) 1189 irradiance = DecodeDirectionalLightmapSpecular(ambient, ambientDir, worldNormal, false, 0, derivedLight); 1190 #endif 1191 #endif 1192 #else 1193 // No directionality, just light colour. 1194 // Irradiance and IrradianceForAO already contain the irradiance, so just handle subtractive lighting. 1195 #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) 1196 irradiance = SubtractMainLightWithRealtimeAttenuationFromLightmap(irradiance, attenuation, bakedColorTex, worldNormal); 1197 #endif 1198 #endif 1199 #endif 1200 } 1201 #endif 1202 1203 #if defined(DYNAMICLIGHTMAP_ON) 1204 // Dynamic lightmaps 1205 fixed4 realtimeColorTex = SampleDynamicLightmapBicubic(lightmapUV.zw); 1206 half3 realtimeColor = DecodeRealtimeLightmap(realtimeColorTex); 1207 1208 irradianceForAO += realtimeColor; 1209 1210 #ifdef DIRLIGHTMAP_COMBINED 1211 half4 realtimeDirTex = SampleDynamicLightmapDirBicubic(lightmapUV.zw); 1212 irradiance += DecodeDirectionalLightmap(realtimeColor, realtimeDirTex, worldNormal); 1213 #else 1214 irradiance += realtimeColor; 1215 #endif 1216 #endif 1217 1218 // VRC Light Volumes also have an additive component which can be added over lightmapping. 1219 #if defined(_VRCLV) && !UNITY_SHOULD_SAMPLE_SH 1220 Light volumeLight = (Light)0; 1221 irradiance += Irradiance_SampleVRCLightVolumeAdditive(worldNormal, worldPos, volumeLight); 1222 1223 // Merge lights, weighing each light's contribution by their intensity 1224 float derivedLum = luminance(derivedLight.colorIntensity.rgb); 1225 float volumeLum = luminance(volumeLight.colorIntensity.rgb); 1226 float totalIntensity = derivedLum + volumeLum + FLT_EPS; 1227 float derivedWeight = derivedLum / totalIntensity; 1228 float volumeWeight = volumeLum / totalIntensity; 1229 1230 derivedLight.l = normalize(derivedLight.l * derivedWeight + volumeLight.l * volumeWeight); 1231 derivedLight.colorIntensity = derivedLight.colorIntensity * derivedWeight + volumeLight.colorIntensity * volumeWeight; 1232 derivedLight.attenuation = derivedLight.attenuation * derivedWeight + volumeLight.attenuation * volumeWeight; 1233 derivedLight.NoL = derivedLight.NoL * derivedWeight + volumeLight.NoL * volumeWeight; 1234 #endif 1235 1236 occlusion = IrradianceToExposureOcclusion(irradianceForAO); 1237 1238 return irradiance; 1239} 1240 1241// Simplified integration function using existing Unity/Bakery functions 1242float3 BakeryGI_Irradiance( 1243 float3 worldNormal, 1244 float3 worldPos, 1245 float4 lightmapUV, // xy = uv0, zw = uv1 1246 float3 ambient, 1247 float attenuation, 1248 float3 tangentNormal, 1249 float3x3 tangentToWorld, 1250 out float occlusion, 1251 out Light derivedLight) 1252{ 1253 // The existing UnityGI_Irradiance function already handles all Bakery modes correctly, 1254 // including MonoSH via the DecodeMonoSHLightmap function that's already defined above 1255 float3 ambientSH[3] = {float3(0,0,0), float3(0,0,0), float3(0,0,0)}; 1256 float3 ambientDir = float3(0,0,0); 1257 1258 return UnityGI_Irradiance( 1259 worldNormal, 1260 worldPos, 1261 lightmapUV, 1262 ambient, 1263 attenuation, 1264 tangentNormal, 1265 tangentToWorld, 1266 #if defined(USING_BAKERY_VERTEXLMSH) 1267 ambientSH, 1268 #elif defined(USING_BAKERY_VERTEXLMDIR) 1269 ambientDir, 1270 #endif 1271 occlusion, 1272 derivedLight 1273 ); 1274} 1275 1276 1277#endif // __FILAMENTED_INC