Import art/VFX asset packs + game-feel systems; normalize texture extensions to lowercase for LFS

Add BefourStudios SciFi environment packs, Gabriel Aguiar VFX, and the
ShaderCrew Toon Shader embedded packages, plus combat/enemy/wave/death
gameplay systems and supporting vault docs/screenshots.

Rename 11 vendor textures from uppercase .PNG/.HDR to lowercase so the
case-sensitive Git LFS filters (*.png/*.hdr) match on case-sensitive
filesystems (Linux CI, case-sensitive macOS), not just locally where
core.ignorecase=true masks the gap. Each .meta moved with its asset so
GUID references are preserved. All ~1000 binaries tracked via LFS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 22:50:43 -07:00
parent dd0064c377
commit e362aaeb43
4830 changed files with 1293057 additions and 38 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7bee192214168fe40982b0f3e4f4413f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 853a8be8551772f44936e361da6f62b9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: cdb1479f619aff740b0cea7a60a84201
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/BiRP/TheToonShader_BiRP.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 1c6b3902befc80643a83432be8825adc
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/BiRP/TheToonShader_WithOutline_BiRP.shader
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1d99d54531efd254d9abfa680f0a2692
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 6683d29458b1a1e49914c5f7ac9df895
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/2020/TheToonShader_URP2020.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 7e890f551f2172a47bb3620f9e51c9d3
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/2020/TheToonShader_WithOutline_URP2020.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 4f4a37c1f6c86224f8dc01fd3b499e08
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/2021/TheToonShader_URP2021.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 683c8dbf739a63d4e9cb1d0c025799f7
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/2021/TheToonShader_WithOutline_URP2021.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: cdd39c097f8297d4d86e6ae5f13727bf
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/2022/TheToonShader_URP2022.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: bc97b42f0416e4147b3917bc938d658e
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/2022/TheToonShader_WithOutline_URP2022.shader
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 068ce1bc61fd2c74abfa358b6c346de0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: aef19de831fba0648a6eb5c4487ea286
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/Unity6_3/TheToonShader_URPUnity6_3.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: f50e98b37244d14499bf85f7bbf776a4
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/Unity6_3/TheToonShader_WithOutline_URPUnity6_3.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: f5cbdd554c80cf840960f02543c9e6a8
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/Unity6/TheToonShader_URPUnity6.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 5b7d18bf8a091cc48a3a9075eca72ff9
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/Native/URP/Unity6/TheToonShader_WithOutline_URPUnity6.shader
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7a4651796dac6a74a9fdfdf3f2d9ce57
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 7bb17be94ebc0e04aa338bc7c73c9bec
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/BiRP/TheToonShader_WithOutline_WithSTS_BiRP.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 8686aecb49901f34daa797ae4fd4ac89
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/BiRP/TheToonShader_WithSTS_BiRP.shader
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ee7752e319360304db4537b2c5c0a84d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d9fbac72fa4a01f4ea8e7e295b0f428d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 488c8ac92b1e0cd4185509b7aa3575f7
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/2020/TheToonShader_WithOutline_WithSTS_URP2020.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: e885b2982824444479ff0104053bc193
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/2020/TheToonShader_WithSTS_URP2020.shader
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a9dc1a15d94f5554ab101a4fc82f84d8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 47a6cb016cd681c42b43e2e68209b9cc
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/2021/TheToonShader_WithOutline_WithSTS_URP2021.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 234f46bb649c35f47b3f5cb4b1974f23
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/2021/TheToonShader_WithSTS_URP2021.shader
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d62a9947386da1f49ae371237269cba7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 7955c05ce9d5ce84f8ceb945057e0da1
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/2022/TheToonShader_WithOutline_WithSTS_URP2022.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 571ea507db08a8c4d992d7ef2663f471
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/2022/TheToonShader_WithSTS_URP2022.shader
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2f612e50b8070ba4791a543f128e1eca
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: f2d5ddc601574a74ab8a8f3da8b8b5e1
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/Unity6/TheToonShader_WithOutline_WithSTS_URPUnity6.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 9b360270502ddd04d81fdb48cbc34ce2
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/Unity6/TheToonShader_WithSTS_URPUnity6.shader
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cc4eb9f6d579d8e4b8414c42983331c0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 9a5b01a3d086bab4d9ad18fa4f4a7633
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/Unity6_3/TheToonShader_WithOutline_WithSTS_URPUnity6_3.shader
uploadId: 919972
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 71053e6e9f8d52447a21f3dd5f3f8330
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/STS/URP/Unity6_3/TheToonShader_WithSTS_URPUnity6_3.shader
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 50bc4803b2552dd4fb21024561d81c51
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8b4ab8725136d83409ce376f193919e8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0ebdc6009ece3014ca719b3fc97875d3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,205 @@
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
#ifndef UNITY_PBS_LIGHTING_INCLUDED_TOON
#define UNITY_PBS_LIGHTING_INCLUDED_TOON
#include "UnityShaderVariables.cginc"
#include "UnityStandardConfig.cginc"
#include "UnityLightingCommon.cginc"
#include "UnityGBuffer.cginc"
#include "UnityGlobalIllumination.cginc"
#include "UnityStandardBRDF_Toon.cginc"
//-------------------------------------------------------------------------------------
// Default BRDF to use:
#if !defined (UNITY_BRDF_PBS_TOON) // allow to explicitly override BRDF in custom shader
// still add safe net for low shader models, otherwise we might end up with shaders failing to compile
#if SHADER_TARGET < 30 || defined(SHADER_TARGET_SURFACE_ANALYSIS) // only need "something" for surface shader analysis pass; pick the cheap one
#define UNITY_BRDF_PBS_TOON BRDF3_Unity_PBS_Toon
#elif defined(UNITY_PBS_USE_BRDF3)
#define UNITY_BRDF_PBS_TOON BRDF3_Unity_PBS_Toon
#elif defined(UNITY_PBS_USE_BRDF2)
#define UNITY_BRDF_PBS_TOON BRDF2_Unity_PBS_Toon
#elif defined(UNITY_PBS_USE_BRDF1)
#define UNITY_BRDF_PBS_TOON BRDF1_Unity_PBS_Toon
#else
#error something broke in auto-choosing BRDF
#endif
#endif
////-------------------------------------------------------------------------------------
//// little helpers for GI calculation
//// CAUTION: This is deprecated and not use in Untiy shader code, but some asset store plugin still use it, so let here for compatibility
//#if !defined (UNITY_BRDF_GI)
// #define UNITY_BRDF_GI BRDF_Unity_Indirect
//#endif
//inline half3 BRDF_Unity_Indirect (half3 baseColor, half3 specColor, half oneMinusReflectivity, half smoothness, half3 normal, half3 viewDir, half occlusion, UnityGI gi)
//{
// return half3(0,0,0);
//}
//#define UNITY_GLOSSY_ENV_FROM_SURFACE(x, s, data) \
// Unity_GlossyEnvironmentData g; \
// g.roughness /* perceptualRoughness */ = SmoothnessToPerceptualRoughness(s.Smoothness); \
// g.reflUVW = reflect(-data.worldViewDir, s.Normal); \
//#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS
// #define UNITY_GI(x, s, data) x = UnityGlobalIllumination (data, s.Occlusion, s.Normal);
//#else
// #define UNITY_GI(x, s, data) \
// UNITY_GLOSSY_ENV_FROM_SURFACE(g, s, data); \
// x = UnityGlobalIllumination (data, s.Occlusion, s.Normal, g);
//#endif
//// Surface shader output structure to be used with physically
//// based shading model.
////-------------------------------------------------------------------------------------
//// Metallic workflow
//struct SurfaceOutputStandard
//{
// fixed3 Albedo; // base (diffuse or specular) color
// float3 Normal; // tangent space normal, if written
// half3 Emission;
// half Metallic; // 0=non-metal, 1=metal
// // Smoothness is the user facing name, it should be perceptual smoothness but user should not have to deal with it.
// // Everywhere in the code you meet smoothness it is perceptual smoothness
// half Smoothness; // 0=rough, 1=smooth
// half Occlusion; // occlusion (default 1)
// fixed Alpha; // alpha for transparencies
//};
inline half4 LightingStandard_Toon(SurfaceOutputStandard s, float3 viewDir, UnityGI gi, ToonShadingData toonShadingData)
{
s.Normal = normalize(s.Normal);
half oneMinusReflectivity;
half3 specColor;
s.Albedo = DiffuseAndSpecularFromMetallic(s.Albedo, s.Metallic, /*out*/specColor, /*out*/oneMinusReflectivity);
// shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
// this is necessary to handle transparency in physically correct way - only diffuse component gets affected by alpha
half outputAlpha;
s.Albedo = PreMultiplyAlpha(s.Albedo, s.Alpha, oneMinusReflectivity, /*out*/outputAlpha);
half4 c = UNITY_BRDF_PBS_TOON(s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect, toonShadingData);
c.a = outputAlpha;
return c;
}
//inline half4 LightingStandard_Deferred (SurfaceOutputStandard s, float3 viewDir, UnityGI gi, out half4 outGBuffer0, out half4 outGBuffer1, out half4 outGBuffer2)
//{
// half oneMinusReflectivity;
// half3 specColor;
// s.Albedo = DiffuseAndSpecularFromMetallic (s.Albedo, s.Metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
// half4 c = UNITY_BRDF_PBS (s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);
// UnityStandardData data;
// data.diffuseColor = s.Albedo;
// data.occlusion = s.Occlusion;
// data.specularColor = specColor;
// data.smoothness = s.Smoothness;
// data.normalWorld = s.Normal;
// UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2);
// half4 emission = half4(s.Emission + c.rgb, 1);
// return emission;
//}
inline void LightingStandard_GI_Toon(
SurfaceOutputStandard s,
UnityGIInput data,
inout UnityGI gi, ToonShadingData toonShadingData)
{
if (toonShadingData.enableToonShading == 1 && toonShadingData.shadingAffectByNormalMap == 0)
{
s.Normal = toonShadingData.normalWSNoMap;
}
#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS
gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal);
#else
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.Smoothness, data.worldViewDir, s.Normal, lerp(unity_ColorSpaceDielectricSpec.rgb, s.Albedo, s.Metallic));
gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal, g);
#endif
}
////-------------------------------------------------------------------------------------
//// Specular workflow
//struct SurfaceOutputStandardSpecular
//{
// fixed3 Albedo; // diffuse color
// fixed3 Specular; // specular color
// float3 Normal; // tangent space normal, if written
// half3 Emission;
// half Smoothness; // 0=rough, 1=smooth
// half Occlusion; // occlusion (default 1)
// fixed Alpha; // alpha for transparencies
//};
//inline half4 LightingStandardSpecular (SurfaceOutputStandardSpecular s, float3 viewDir, UnityGI gi)
//{
// s.Normal = normalize(s.Normal);
// // energy conservation
// half oneMinusReflectivity;
// s.Albedo = EnergyConservationBetweenDiffuseAndSpecular (s.Albedo, s.Specular, /*out*/ oneMinusReflectivity);
// // shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
// // this is necessary to handle transparency in physically correct way - only diffuse component gets affected by alpha
// half outputAlpha;
// s.Albedo = PreMultiplyAlpha (s.Albedo, s.Alpha, oneMinusReflectivity, /*out*/ outputAlpha);
// half4 c = UNITY_BRDF_PBS (s.Albedo, s.Specular, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);
// c.a = outputAlpha;
// return c;
//}
//inline half4 LightingStandardSpecular_Deferred (SurfaceOutputStandardSpecular s, float3 viewDir, UnityGI gi, out half4 outGBuffer0, out half4 outGBuffer1, out half4 outGBuffer2)
//{
// // energy conservation
// half oneMinusReflectivity;
// s.Albedo = EnergyConservationBetweenDiffuseAndSpecular (s.Albedo, s.Specular, /*out*/ oneMinusReflectivity);
// half4 c = UNITY_BRDF_PBS (s.Albedo, s.Specular, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);
// UnityStandardData data;
// data.diffuseColor = s.Albedo;
// data.occlusion = s.Occlusion;
// data.specularColor = s.Specular;
// data.smoothness = s.Smoothness;
// data.normalWorld = s.Normal;
// UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2);
// half4 emission = half4(s.Emission + c.rgb, 1);
// return emission;
//}
//inline void LightingStandardSpecular_GI (
// SurfaceOutputStandardSpecular s,
// UnityGIInput data,
// inout UnityGI gi)
//{
//#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS
// gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal);
//#else
// Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.Smoothness, data.worldViewDir, s.Normal, s.Specular);
// gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal, g);
//#endif
//}
#endif // UNITY_PBS_LIGHTING_INCLUDED
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: edc9458448145664e976532f43127acd
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/xxSharedTTSDependecies/ModifiedLightingFunctions/BiRP/UnityPBSLighting_Toon.cginc
uploadId: 919972
@@ -0,0 +1,566 @@
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
#ifndef UNITY_STANDARD_BRDF_INCLUDED_TOON
#define UNITY_STANDARD_BRDF_INCLUDED_TOON
#include "UnityCG.cginc"
#include "UnityStandardConfig.cginc"
#include "UnityLightingCommon.cginc"
void ConvertToCellShading(inout half nl, inout half nv, ToonShadingData toonShadingData)
{
if (toonShadingData.enableToonShading == 1)
{
//Cell Shading Calculations:
toonShadingData.cellTransitionSmoothness = (1.0 / toonShadingData.numberOfCells) * toonShadingData.cellTransitionSmoothness; // adjusted for smoothstep
half currentCell = ceil(nl * toonShadingData.numberOfCells) / toonShadingData.numberOfCells;
half previousCell = max(0, ceil(nl * toonShadingData.numberOfCells) - 1) / toonShadingData.numberOfCells;
nl = max(currentCell * smoothstep(previousCell, previousCell + toonShadingData.cellTransitionSmoothness, nl), previousCell);
currentCell = ceil(nv * toonShadingData.numberOfCells) / toonShadingData.numberOfCells;
previousCell = max(0, ceil(nv * toonShadingData.numberOfCells) - 1) / toonShadingData.numberOfCells;
nv = max(currentCell * smoothstep(previousCell, previousCell + toonShadingData.cellTransitionSmoothness, nv), previousCell);
}
}
half3 ConvertToCellShading(half3 value, ToonShadingData toonShadingData)
{
if (toonShadingData.enableToonShading == 1)
{
//Cell Shading Calculations:
toonShadingData.cellTransitionSmoothness = (1.0 / toonShadingData.numberOfCells) * toonShadingData.cellTransitionSmoothness; // adjusted for smoothstep
half3 currentCell = ceil(value * toonShadingData.numberOfCells) / toonShadingData.numberOfCells;
half3 previousCell = max(0, ceil(value * toonShadingData.numberOfCells) - 1) / toonShadingData.numberOfCells;
value = max(currentCell * smoothstep(previousCell, previousCell + toonShadingData.cellTransitionSmoothness, value), previousCell);
return value;
}
return value;
}
////-----------------------------------------------------------------------------
//// Helper to convert smoothness to roughness
////-----------------------------------------------------------------------------
//float PerceptualRoughnessToRoughness(float perceptualRoughness)
//{
// return perceptualRoughness * perceptualRoughness;
//}
//half RoughnessToPerceptualRoughness(half roughness)
//{
// return sqrt(roughness);
//}
//// Smoothness is the user facing name
//// it should be perceptualSmoothness but we don't want the user to have to deal with this name
//half SmoothnessToRoughness(half smoothness)
//{
// return (1 - smoothness) * (1 - smoothness);
//}
//float SmoothnessToPerceptualRoughness(float smoothness)
//{
// return (1 - smoothness);
//}
////-------------------------------------------------------------------------------------
//inline half Pow4 (half x)
//{
// return x*x*x*x;
//}
//inline float2 Pow4 (float2 x)
//{
// return x*x*x*x;
//}
//inline half3 Pow4 (half3 x)
//{
// return x*x*x*x;
//}
//inline half4 Pow4 (half4 x)
//{
// return x*x*x*x;
//}
//// Pow5 uses the same amount of instructions as generic pow(), but has 2 advantages:
//// 1) better instruction pipelining
//// 2) no need to worry about NaNs
//inline half Pow5 (half x)
//{
// return x*x * x*x * x;
//}
//inline half2 Pow5 (half2 x)
//{
// return x*x * x*x * x;
//}
//inline half3 Pow5 (half3 x)
//{
// return x*x * x*x * x;
//}
//inline half4 Pow5 (half4 x)
//{
// return x*x * x*x * x;
//}
//inline half3 FresnelTerm (half3 F0, half cosA)
//{
// half t = Pow5 (1 - cosA); // ala Schlick interpoliation
// return F0 + (1-F0) * t;
//}
//inline half3 FresnelLerp (half3 F0, half3 F90, half cosA)
//{
// half t = Pow5 (1 - cosA); // ala Schlick interpoliation
// return lerp (F0, F90, t);
//}
//// approximage Schlick with ^4 instead of ^5
//inline half3 FresnelLerpFast (half3 F0, half3 F90, half cosA)
//{
// half t = Pow4 (1 - cosA);
// return lerp (F0, F90, t);
//}
//// Note: Disney diffuse must be multiply by diffuseAlbedo / PI. This is done outside of this function.
//half DisneyDiffuse(half NdotV, half NdotL, half LdotH, half perceptualRoughness)
//{
// half fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
// // Two schlick fresnel term
// half lightScatter = (1 + (fd90 - 1) * Pow5(1 - NdotL));
// half viewScatter = (1 + (fd90 - 1) * Pow5(1 - NdotV));
// return lightScatter * viewScatter;
//}
//// NOTE: Visibility term here is the full form from Torrance-Sparrow model, it includes Geometric term: V = G / (N.L * N.V)
//// This way it is easier to swap Geometric terms and more room for optimizations (except maybe in case of CookTorrance geom term)
//// Generic Smith-Schlick visibility term
//inline half SmithVisibilityTerm (half NdotL, half NdotV, half k)
//{
// half gL = NdotL * (1-k) + k;
// half gV = NdotV * (1-k) + k;
// return 1.0 / (gL * gV + 1e-5f); // This function is not intended to be running on Mobile,
// // therefore epsilon is smaller than can be represented by half
//}
//// Smith-Schlick derived for Beckmann
//inline half SmithBeckmannVisibilityTerm (half NdotL, half NdotV, half roughness)
//{
// half c = 0.797884560802865h; // c = sqrt(2 / Pi)
// half k = roughness * c;
// return SmithVisibilityTerm (NdotL, NdotV, k) * 0.25f; // * 0.25 is the 1/4 of the visibility term
//}
//// Ref: http://jcgt.org/published/0003/02/03/paper.pdf
//inline float SmithJointGGXVisibilityTerm (float NdotL, float NdotV, float roughness)
//{
//#if 0
// // Original formulation:
// // lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;
// // lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;
// // G = 1 / (1 + lambda_v + lambda_l);
// // Reorder code to be more optimal
// half a = roughness;
// half a2 = a * a;
// half lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
// half lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
// // Simplify visibility term: (2.0f * NdotL * NdotV) / ((4.0f * NdotL * NdotV) * (lambda_v + lambda_l + 1e-5f));
// return 0.5f / (lambdaV + lambdaL + 1e-5f); // This function is not intended to be running on Mobile,
// // therefore epsilon is smaller than can be represented by half
//#else
// // Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)
// float a = roughness;
// float lambdaV = NdotL * (NdotV * (1 - a) + a);
// float lambdaL = NdotV * (NdotL * (1 - a) + a);
//#if defined(SHADER_API_SWITCH)
// return 0.5f / (lambdaV + lambdaL + UNITY_HALF_MIN);
//#else
// return 0.5f / (lambdaV + lambdaL + 1e-5f);
//#endif
//#endif
//}
//inline float GGXTerm (float NdotH, float roughness)
//{
// float a2 = roughness * roughness;
// float d = (NdotH * a2 - NdotH) * NdotH + 1.0f; // 2 mad
// return UNITY_INV_PI * a2 / (d * d + 1e-7f); // This function is not intended to be running on Mobile,
// // therefore epsilon is smaller than what can be represented by half
//}
//inline half PerceptualRoughnessToSpecPower (half perceptualRoughness)
//{
// half m = PerceptualRoughnessToRoughness(perceptualRoughness); // m is the true academic roughness.
// half sq = max(1e-4f, m*m);
// half n = (2.0 / sq) - 2.0; // https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf
// n = max(n, 1e-4f); // prevent possible cases of pow(0,0), which could happen when roughness is 1.0 and NdotH is zero
// return n;
//}
//// BlinnPhong normalized as normal distribution function (NDF)
//// for use in micro-facet model: spec=D*G*F
//// eq. 19 in https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf
//inline half NDFBlinnPhongNormalizedTerm (half NdotH, half n)
//{
// // norm = (n+2)/(2*pi)
// half normTerm = (n + 2.0) * (0.5/UNITY_PI);
// half specTerm = pow (NdotH, n);
// return specTerm * normTerm;
//}
////-------------------------------------------------------------------------------------
///*
//// https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html
//const float k0 = 0.00098, k1 = 0.9921;
//// pass this as a constant for optimization
//const float fUserMaxSPow = 100000; // sqrt(12M)
//const float g_fMaxT = ( exp2(-10.0/fUserMaxSPow) - k0)/k1;
//float GetSpecPowToMip(float fSpecPow, int nMips)
//{
// // Default curve - Inverse of TB2 curve with adjusted constants
// float fSmulMaxT = ( exp2(-10.0/sqrt( fSpecPow )) - k0)/k1;
// return float(nMips-1)*(1.0 - clamp( fSmulMaxT/g_fMaxT, 0.0, 1.0 ));
//}
// //float specPower = PerceptualRoughnessToSpecPower(perceptualRoughness);
// //float mip = GetSpecPowToMip (specPower, 7);
//*/
//inline float3 Unity_SafeNormalize(float3 inVec)
//{
// float dp3 = max(0.001f, dot(inVec, inVec));
// return inVec * rsqrt(dp3);
//}
////-------------------------------------------------------------------------------------
// Note: BRDF entry points use smoothness and oneMinusReflectivity for optimization
// purposes, mostly for DX9 SM2.0 level. Most of the math is being done on these (1-x) values, and that saves
// a few precious ALU slots.
// Main Physically Based BRDF
// Derived from Disney work and based on Torrance-Sparrow micro-facet model
//
// BRDF = kD / pi + kS * (D * V * F) / 4
// I = BRDF * NdotL
//
// * NDF (depending on UNITY_BRDF_GGX):
// a) Normalized BlinnPhong
// b) GGX
// * Smith for Visiblity term
// * Schlick approximation for Fresnel
half4 BRDF1_Unity_PBS_Toon(half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,
float3 normal, float3 viewDir,
UnityLight light, UnityIndirect gi, ToonShadingData toonShadingData)
{
if (toonShadingData.enableToonShading == 1 && toonShadingData.shadingAffectByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
float perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness);
float3 halfDir = Unity_SafeNormalize(float3(light.dir) + viewDir);
// NdotV should not be negative for visible pixels, but it can happen due to perspective projection and normal mapping
// In this case normal should be modified to become valid (i.e facing camera) and not cause weird artifacts.
// but this operation adds few ALU and users may not want it. Alternative is to simply take the abs of NdotV (less correct but works too).
// Following define allow to control this. Set it to 0 if ALU is critical on your platform.
// This correction is interesting for GGX with SmithJoint visibility function because artifacts are more visible in this case due to highlight edge of rough surface
// Edit: Disable this code by default for now as it is not compatible with two sided lighting used in SpeedTree.
#define UNITY_HANDLE_CORRECTLY_NEGATIVE_NDOTV 0
#if UNITY_HANDLE_CORRECTLY_NEGATIVE_NDOTV
// The amount we shift the normal toward the view vector is defined by the dot product.
half shiftAmount = dot(normal, viewDir);
normal = shiftAmount < 0.0f ? normal + viewDir * (-shiftAmount + 1e-5f) : normal;
// A re-normalization should be applied here but as the shift is small we don't do it to save ALU.
//normal = normalize(normal);
float nv = saturate(dot(normal, viewDir)); // TODO: this saturate should no be necessary here
#else
half nv = abs(dot(normal, viewDir)); // This abs allow to limit artifact
#endif
float nl = saturate(dot(normal, light.dir));
float nh = saturate(dot(normal, halfDir));
half lv = saturate(dot(light.dir, viewDir));
half lh = saturate(dot(light.dir, halfDir));
float nlCopy = float(nl);
float nvCopy = float(nv);
half nlCell = Posterize(nl, toonShadingData);
half nvCell = Posterize(nv, toonShadingData);
// Diffuse term
half diffuseTerm = DisneyDiffuse(nvCell, nlCell, lh, perceptualRoughness) * nlCell;
// Specular term
// HACK: theoretically we should divide diffuseTerm by Pi and not multiply specularTerm!
// BUT 1) that will make shader look significantly darker than Legacy ones
// and 2) on engine side "Non-important" lights have to be divided by Pi too in cases when they are injected into ambient SH
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
#if UNITY_BRDF_GGX
// GGX with roughtness to 0 would mean no specular at all, using max(roughness, 0.002) here to match HDrenderloop roughtness remapping.
roughness = max(roughness, 0.002);
float V = SmithJointGGXVisibilityTerm (nl, nv, roughness);
float D = GGXTerm (nh, roughness);
#else
// Legacy
half V = SmithBeckmannVisibilityTerm(nl, nv, roughness);
half D = NDFBlinnPhongNormalizedTerm(nh, PerceptualRoughnessToSpecPower(perceptualRoughness));
#endif
float specularTerm = V * D * UNITY_PI; // Torrance-Sparrow model, Fresnel is applied later
#ifdef UNITY_COLORSPACE_GAMMA
specularTerm = sqrt(max(1e-4h, specularTerm));
#endif
// specularTerm * nl can be NaN on Metal in some cases, use max() to make sure it's a sane value
specularTerm = max(0, specularTerm * nl);
#if defined(_SPECULARHIGHLIGHTS_OFF)
specularTerm = 0.0;
#endif
// surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(roughness^2+1)
half surfaceReduction;
#ifdef UNITY_COLORSPACE_GAMMA
surfaceReduction = 1.0-0.28*roughness*perceptualRoughness; // 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]
#else
surfaceReduction = 1.0 / (roughness * roughness + 1.0); // fade \in [0.5;1]
#endif
// To provide true Lambert lighting, we need to be able to kill specular completely.
specularTerm *= any(specColor) ? 1.0 : 0.0;
half grazingTerm = saturate(smoothness + (1 - oneMinusReflectivity));
//original
//half3 color = diffColor * (gi.diffuse + light.color * diffuseTerm)
// + specularTerm * light.color * FresnelTerm(specColor, lh)
// + surfaceReduction * gi.specular * FresnelLerp(specColor, grazingTerm, nv);
half3 color = 0;
color = diffColor * (gi.diffuse + light.color * diffuseTerm);
float3 specular = specularTerm * light.color * FresnelTerm(specColor, lh);
color += PosterizeShifted(specular, toonShadingData);
//float3 posterizedGISpecular = PosterizeShifted(gi.specular, toonShadingData);
color += surfaceReduction * gi.specular * FresnelLerp(specColor, grazingTerm, nvCell);
return half4(color, 1);
}
// Based on Minimalist CookTorrance BRDF
// Implementation is slightly different from original derivation: http://www.thetenthplanet.de/archives/255
//
// * NDF (depending on UNITY_BRDF_GGX):
// a) BlinnPhong
// b) [Modified] GGX
// * Modified Kelemen and Szirmay-Kalos for Visibility term
// * Fresnel approximated with 1/LdotH
half4 BRDF2_Unity_PBS_Toon(half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,
float3 normal, float3 viewDir,
UnityLight light, UnityIndirect gi, ToonShadingData toonShadingData)
{
float3 halfDir = Unity_SafeNormalize(float3(light.dir) + viewDir);
half nl = saturate(dot(normal, light.dir));
float nh = saturate(dot(normal, halfDir));
half nv = saturate(dot(normal, viewDir));
float lh = saturate(dot(light.dir, halfDir));
ConvertToCellShading(nl, nv, toonShadingData);
// Specular term
half perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness);
half roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
#if UNITY_BRDF_GGX
// GGX Distribution multiplied by combined approximation of Visibility and Fresnel
// See "Optimizing PBR for Mobile" from Siggraph 2015 moving mobile graphics course
// https://community.arm.com/events/1155
float a = roughness;
float a2 = a*a;
float d = nh * nh * (a2 - 1.f) + 1.00001f;
#ifdef UNITY_COLORSPACE_GAMMA
// Tighter approximation for Gamma only rendering mode!
// DVF = sqrt(DVF);
// DVF = (a * sqrt(.25)) / (max(sqrt(0.1), lh)*sqrt(roughness + .5) * d);
float specularTerm = a / (max(0.32f, lh) * (1.5f + roughness) * d);
#else
float specularTerm = a2 / (max(0.1f, lh*lh) * (roughness + 0.5f) * (d * d) * 4);
#endif
// on mobiles (where half actually means something) denominator have risk of overflow
// clamp below was added specifically to "fix" that, but dx compiler (we convert bytecode to metal/gles)
// sees that specularTerm have only non-negative terms, so it skips max(0,..) in clamp (leaving only min(100,...))
#if defined (SHADER_API_MOBILE)
specularTerm = specularTerm - 1e-4f;
#endif
#else
// Legacy
half specularPower = PerceptualRoughnessToSpecPower(perceptualRoughness);
// Modified with approximate Visibility function that takes roughness into account
// Original ((n+1)*N.H^n) / (8*Pi * L.H^3) didn't take into account roughness
// and produced extremely bright specular at grazing angles
half invV = lh * lh * smoothness + perceptualRoughness * perceptualRoughness; // approx ModifiedKelemenVisibilityTerm(lh, perceptualRoughness);
half invF = lh;
half specularTerm = ((specularPower + 1) * pow(nh, specularPower)) / (8 * invV * invF + 1e-4h);
#ifdef UNITY_COLORSPACE_GAMMA
specularTerm = sqrt(max(1e-4f, specularTerm));
#endif
#endif
#if defined (SHADER_API_MOBILE)
specularTerm = clamp(specularTerm, 0.0, 100.0); // Prevent FP16 overflow on mobiles
#endif
#if defined(_SPECULARHIGHLIGHTS_OFF)
specularTerm = 0.0;
#endif
// surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(realRoughness^2+1)
// 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]
// 1-x^3*(0.6-0.08*x) approximation for 1/(x^4+1)
#ifdef UNITY_COLORSPACE_GAMMA
half surfaceReduction = 0.28;
#else
half surfaceReduction = (0.6 - 0.08 * perceptualRoughness);
#endif
surfaceReduction = 1.0 - roughness * perceptualRoughness * surfaceReduction;
half grazingTerm = saturate(smoothness + (1 - oneMinusReflectivity));
half3 color = (diffColor + specularTerm * specColor) * light.color * nl
+ gi.diffuse * diffColor
+ surfaceReduction * gi.specular * FresnelLerpFast(specColor, grazingTerm, nv);
return half4(color, 1);
}
//sampler2D_float unity_NHxRoughness;
//half3 BRDF3_Direct(half3 diffColor, half3 specColor, half rlPow4, half smoothness)
//{
// half LUT_RANGE = 16.0; // must match range in NHxRoughness() function in GeneratedTextures.cpp
// // Lookup texture to save instructions
// half specular = tex2D(unity_NHxRoughness, half2(rlPow4, SmoothnessToPerceptualRoughness(smoothness))).r * LUT_RANGE;
//#if defined(_SPECULARHIGHLIGHTS_OFF)
// specular = 0.0;
//#endif
// return diffColor + specular * specColor;
//}
//half3 BRDF3_Indirect(half3 diffColor, half3 specColor, UnityIndirect indirect, half grazingTerm, half fresnelTerm)
//{
// half3 c = indirect.diffuse * diffColor;
// c += indirect.specular * lerp (specColor, grazingTerm, fresnelTerm);
// return c;
//}
// Old school, not microfacet based Modified Normalized Blinn-Phong BRDF
// Implementation uses Lookup texture for performance
//
// * Normalized BlinnPhong in RDF form
// * Implicit Visibility term
// * No Fresnel term
//
// TODO: specular is too weak in Linear rendering mode
half4 BRDF3_Unity_PBS_Toon (half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,
float3 normal, float3 viewDir,
UnityLight light, UnityIndirect gi, ToonShadingData toonShadingData)
{
if (toonShadingData.enableToonShading == 1 && toonShadingData.shadingAffectByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
float3 reflDir = reflect(viewDir, normal);
half nl = saturate(dot(normal, light.dir));
half nv = saturate(dot(normal, viewDir));
//if (toonShadingData.enableToonShading == 1)
//{
// //Cell Shading Calculations:
// toonShadingData.cellTransitionSmoothness = (1.0 / toonShadingData.numberOfCells) * toonShadingData.cellTransitionSmoothness; // adjusted for smoothstep
// half currentCell = ceil(nl * toonShadingData.numberOfCells) / toonShadingData.numberOfCells;
// half previousCell = max(0, ceil(nl * toonShadingData.numberOfCells) - 1) / toonShadingData.numberOfCells;
// nl = max(currentCell * smoothstep(previousCell, previousCell + toonShadingData.cellTransitionSmoothness, nl), previousCell);
// currentCell = ceil(nv * toonShadingData.numberOfCells) / toonShadingData.numberOfCells;
// previousCell = max(0, ceil(nv * toonShadingData.numberOfCells) - 1) / toonShadingData.numberOfCells;
// nv = max(currentCell * smoothstep(previousCell, previousCell + toonShadingData.cellTransitionSmoothness, nv), previousCell);
//}
ConvertToCellShading(nl, nv, toonShadingData);
// Vectorize Pow4 to save instructions
half2 rlPow4AndFresnelTerm = Pow4 (float2(dot(reflDir, light.dir), 1-nv)); // use R.L instead of N.H to save couple of instructions
half rlPow4 = rlPow4AndFresnelTerm.x; // power exponent must match kHorizontalWarpExp in NHxRoughness() function in GeneratedTextures.cpp
half fresnelTerm = rlPow4AndFresnelTerm.y;
half grazingTerm = saturate(smoothness + (1-oneMinusReflectivity));
half3 color = BRDF3_Direct(diffColor, specColor, rlPow4, smoothness);
color *= light.color * nl;
color += BRDF3_Indirect(diffColor, specColor, gi, grazingTerm, fresnelTerm);
return half4(color, 1);
}
//// Include deprecated function
//#define INCLUDE_UNITY_STANDARD_BRDF_DEPRECATED
//#include "UnityDeprecated.cginc"
//#undef INCLUDE_UNITY_STANDARD_BRDF_DEPRECATED
#endif // UNITY_STANDARD_BRDF_INCLUDED
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: a2a159e475fdfd8439cbee9800950e4b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/xxSharedTTSDependecies/ModifiedLightingFunctions/BiRP/UnityStandardBRDF_Toon.cginc
uploadId: 919972
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 13f199b5921f43c4d9da2ea4c8f7b363
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: defea43ca66c7c4428650a4569bb5aa5
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/xxSharedTTSDependecies/ModifiedLightingFunctions/URP/LightingModifiedForToon2020.hlsl
uploadId: 919972
@@ -0,0 +1,614 @@
#ifndef UNIVERSAL_LIGHTING_INCLUDED
#define UNIVERSAL_LIGHTING_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
#if defined(LIGHTMAP_ON)
#define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) float2 lmName : TEXCOORD##index
#define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) OUT.xy = lightmapUV.xy * lightmapScaleOffset.xy + lightmapScaleOffset.zw;
#define OUTPUT_SH(normalWS, OUT)
#else
#define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) half3 shName : TEXCOORD##index
#define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT)
#define OUTPUT_SH(normalWS, OUT) OUT.xyz = SampleSHVertex(normalWS)
#endif
//struct ToonShadingData
//{
// half enableToonShading;
// float3 normalWS;
// float3 normalWSNoMap;
// float cellTransitionSmoothness;
// half numberOfCells;
// float specularEdgeSmoothness;
// half shadowsAffectByNormalMap;
// half specularAffectedByNormalMap;
//};
//float CalculateCellShadingLightPartitioning(half3 lightDirection, ToonShadingData toonShadingData)
//{
// if (toonShadingData.enableToonShading == 1)
// {
// //Cell Shading Calculations:
// toonShadingData.cellTransitionSmoothness = (1.0 / toonShadingData.numberOfCells) * toonShadingData.cellTransitionSmoothness; // adjusted for smoothstep
// half3 normal;
// if (toonShadingData.shadowsAffectByNormalMap == 0)
// {
// normal = toonShadingData.normalWSNoMap;
// }
// else
// {
// normal = toonShadingData.normalWS;
// }
// float NdotL = dot(lightDirection, normal);
// half currentCell = ceil(NdotL * toonShadingData.numberOfCells) / toonShadingData.numberOfCells;
// half previousCell = max(0, ceil(NdotL * toonShadingData.numberOfCells) - 1) / toonShadingData.numberOfCells;
// return max(currentCell * smoothstep(previousCell, previousCell + toonShadingData.cellTransitionSmoothness, NdotL), previousCell);
// }
// else
// {
// return saturate(dot(toonShadingData.normalWS, lightDirection));
// }
//}
///////////////////////////////////////////////////////////////////////////////
// Lighting Functions //
///////////////////////////////////////////////////////////////////////////////
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal)
{
half NdotL = saturate(dot(normal, lightDir));
return lightColor * NdotL;
}
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal, half modifiedLightIntensity)
{
return lightColor * modifiedLightIntensity;
}
//half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness)
//{
// float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
// half NdotH = half(saturate(dot(normal, halfVec)));
// half modifier = pow(NdotH, smoothness);
// half3 specularReflection = specular.rgb * modifier;
// return lightColor * specularReflection;
//}
half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness, ToonShadingData toonShadingData)
{
float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
if (toonShadingData.enableToonShading == 1)
{
if (toonShadingData.specularAffectedByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
else
{
normal = toonShadingData.normalWS;
}
}
half NdotH = saturate(dot(normal, halfVec));
half modifier = pow(NdotH, smoothness);
half3 specularReflection;
if (toonShadingData.enableToonShading == 1)
{
//if (toonShadingData.specularEdgeSmoothness < 1)
//{
// specularReflection = specular.rgb * modifier;
// specularReflection = smoothstep(0.01, 0.01 + toonShadingData.specularEdgeSmoothness, specularReflection);
//}
//else
//{
// specularReflection = specular.rgb * modifier;
//}
specularReflection = PosterizeShifted(saturate(specular.rgb) * modifier, toonShadingData);
}
else
{
specularReflection = saturate(specular.rgb) * modifier;
}
return lightColor * specularReflection;
}
half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat,
half3 lightColor, half3 lightDirectionWS, half lightAttenuation,
half3 normalWS, half3 viewDirectionWS,
half clearCoatMask, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
toonShadingData.normalWS = normalWS;
//half NdotL = saturate(dot(normalWS, lightDirectionWS));
half NdotL = CalculateCellShadingPartitioning(lightDirectionWS, toonShadingData);
half3 radiance = lightColor * (lightAttenuation * NdotL);
half3 brdf = brdfData.diffuse;
#ifndef _SPECULARHIGHLIGHTS_OFF
[branch]
if (!specularHighlightsOff)
{
half3 specularNormal;
if (toonShadingData.specularAffectedByNormalMap == 1)
{
specularNormal = normalWS;
}
else
{
specularNormal = toonShadingData.normalWSNoMap;
}
//brdf += brdfData.specular * DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS); //original
half3 specular = brdfData.specular * DirectBRDFSpecular(brdfData, specularNormal, lightDirectionWS, viewDirectionWS);
if (toonShadingData.enableToonShading == 1)
{
//specular = specular / brdfData.normalizationTerm;
specular = PosterizeShifted(specular, toonShadingData);
// specular = specular * brdfData.normalizationTerm;
}
brdf += specular;
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
// Clear coat evaluates the specular a second timw and has some common terms with the base specular.
// We rely on the compiler to merge these and compute them only once.
half brdfCoat = kDielectricSpec.r * DirectBRDFSpecular(brdfDataClearCoat, normalWS, lightDirectionWS, viewDirectionWS);
// Mix clear coat and base layer using khronos glTF recommended formula
// https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md
// Use NoV for direct too instead of LoH as an optimization (NoV is light invariant).
half NoV = saturate(dot(normalWS, viewDirectionWS));
// Use slightly simpler fresnelTerm (Pow4 vs Pow5) as a small optimization.
// It is matching fresnel used in the GI/Env, so should produce a consistent clear coat blend (env vs. direct)
half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * Pow4(1.0 - NoV);
brdf = brdf * (1.0 - clearCoatMask * coatFresnel) + brdfCoat * clearCoatMask;
#endif // _CLEARCOAT
}
#endif // _SPECULARHIGHLIGHTS_OFF
return brdf * radiance;
}
half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, Light light, half3 normalWS, half3 viewDirectionWS, half clearCoatMask, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
return LightingPhysicallyBased(brdfData, brdfDataClearCoat, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, clearCoatMask, specularHighlightsOff, toonShadingData);
}
// Backwards compatibility
half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS,
ToonShadingData toonShadingData)
{
#ifdef _SPECULARHIGHLIGHTS_OFF
bool specularHighlightsOff = true;
#else
bool specularHighlightsOff = false;
#endif
const BRDFData noClearCoat = (BRDFData) 0;
return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS,
ToonShadingData toonShadingData)
{
Light light;
light.color = lightColor;
light.direction = lightDirectionWS;
light.distanceAttenuation = lightAttenuation;
light.shadowAttenuation = 1;
return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
const BRDFData noClearCoat = (BRDFData) 0;
return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
Light light;
light.color = lightColor;
light.direction = lightDirectionWS;
light.distanceAttenuation = lightAttenuation;
light.shadowAttenuation = 1;
return LightingPhysicallyBased(brdfData, light, viewDirectionWS, specularHighlightsOff, specularHighlightsOff, toonShadingData);
}
half3 VertexLighting(float3 positionWS, half3 normalWS)
{
half3 vertexLightColor = half3(0.0, 0.0, 0.0);
#ifdef _ADDITIONAL_LIGHTS_VERTEX
uint lightsCount = GetAdditionalLightsCount();
LIGHT_LOOP_BEGIN(lightsCount)
Light light = GetAdditionalLight(lightIndex, positionWS);
half3 lightColor = light.color * light.distanceAttenuation;
vertexLightColor += LightingLambert(lightColor, light.direction, normalWS);
LIGHT_LOOP_END
#endif
return vertexLightColor;
}
struct LightingData
{
half3 giColor;
half3 mainLightColor;
half3 additionalLightsColor;
half3 vertexLightingColor;
half3 emissionColor;
};
half3 CalculateLightingColor(LightingData lightingData, half3 albedo)
{
half3 lightingColor = 0;
if (IsOnlyAOLightingFeatureEnabled())
{
return lightingData.giColor; // Contains white + AO
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_GLOBAL_ILLUMINATION))
{
lightingColor += lightingData.giColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_MAIN_LIGHT))
{
lightingColor += lightingData.mainLightColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_ADDITIONAL_LIGHTS))
{
lightingColor += lightingData.additionalLightsColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_VERTEX_LIGHTING))
{
lightingColor += lightingData.vertexLightingColor;
}
lightingColor *= albedo;
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_EMISSION))
{
lightingColor += lightingData.emissionColor;
}
return lightingColor;
}
half4 CalculateFinalColor(LightingData lightingData, half alpha)
{
half3 finalColor = CalculateLightingColor(lightingData, 1);
return half4(finalColor, alpha);
}
half4 CalculateFinalColor(LightingData lightingData, half3 albedo, half alpha, float fogCoord)
{
#if defined(_FOG_FRAGMENT)
#if (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))
float viewZ = -fogCoord;
float nearToFarZ = max(viewZ - _ProjectionParams.y, 0);
half fogFactor = ComputeFogFactorZ0ToFar(nearToFarZ);
#else
half fogFactor = 0;
#endif
#else
half fogFactor = fogCoord;
#endif
half3 lightingColor = CalculateLightingColor(lightingData, albedo);
half3 finalColor = MixFog(lightingColor, fogFactor);
return half4(finalColor, alpha);
}
LightingData CreateLightingData(InputData inputData, SurfaceData surfaceData)
{
LightingData lightingData;
lightingData.giColor = inputData.bakedGI;
lightingData.emissionColor = surfaceData.emission;
lightingData.vertexLightingColor = 0;
lightingData.mainLightColor = 0;
lightingData.additionalLightsColor = 0;
return lightingData;
}
half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData, ToonShadingData toonShadingData)
{
half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
float modifiedLightIntensity = CalculateCellShadingPartitioning(light.direction, toonShadingData);
//half3 lightColor = LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS, modifiedLightIntensity);
half3 lightColor = attenuatedLightColor * modifiedLightIntensity;
lightColor *= surfaceData.albedo;
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
half smoothness = exp2(10 * surfaceData.smoothness + 1);
lightColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, 1), smoothness, toonShadingData);
#endif
return lightColor;
}
///////////////////////////////////////////////////////////////////////////////
// Fragment Functions //
// Used by ShaderGraph and others builtin renderers //
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// PBR lighting...
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData, ToonShadingData toonShadingData)
{
#if defined(_SPECULARHIGHLIGHTS_OFF)
bool specularHighlightsOff = true;
#else
bool specularHighlightsOff = false;
#endif
BRDFData brdfData;
// NOTE: can modify "surfaceData"...
InitializeBRDFData(surfaceData, brdfData);
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, brdfData, debugColor))
{
return debugColor;
}
#endif
// Clear-coat calculation...
BRDFData brdfDataClearCoat = CreateClearCoatBRDFData(surfaceData, brdfData);
half4 shadowMask = CalculateShadowMask(inputData);
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
uint meshRenderingLayers = GetMeshRenderingLightLayer();
Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
// NOTE: We don't apply AO to the GI here because it's done in the lighting calculation below...
//MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI);
//LightingData lightingData = CreateLightingData(inputData, surfaceData);
//lightingData.giColor = GlobalIllumination(brdfData, brdfDataClearCoat, surfaceData.clearCoatMask,
// inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
// inputData.normalWS, inputData.viewDirectionWS);
half3 normal = inputData.normalWS;
if (toonShadingData.enableToonShading == 1 && toonShadingData.shadingAffectByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
MixRealtimeAndBakedGI(mainLight, normal, inputData.bakedGI);
LightingData lightingData = CreateLightingData(inputData, surfaceData);
lightingData.giColor = GlobalIllumination(brdfData, brdfDataClearCoat, surfaceData.clearCoatMask,
inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
normal, inputData.viewDirectionWS);
if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
{
lightingData.mainLightColor = LightingPhysicallyBased(brdfData, brdfDataClearCoat,
mainLight,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
#if defined(_ADDITIONAL_LIGHTS)
uint pixelLightCount = GetAdditionalLightsCount();
#if USE_CLUSTERED_LIGHTING
for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
{
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
{
lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff,
toonShadingData);
}
}
#endif
LIGHT_LOOP_BEGIN(pixelLightCount)
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
{
lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff,
toonShadingData);
}
LIGHT_LOOP_END
#endif
#if defined(_ADDITIONAL_LIGHTS_VERTEX)
lightingData.vertexLightingColor += inputData.vertexLighting * brdfData.diffuse;
#endif
return CalculateFinalColor(lightingData, surfaceData.alpha);
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular,
half smoothness, half occlusion, half3 emission, half alpha, ToonShadingData toonShadingData)
{
SurfaceData surfaceData;
surfaceData.albedo = albedo;
surfaceData.specular = specular;
surfaceData.metallic = metallic;
surfaceData.smoothness = smoothness;
surfaceData.normalTS = half3(0, 0, 1);
surfaceData.emission = emission;
surfaceData.occlusion = occlusion;
surfaceData.alpha = alpha;
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
return UniversalFragmentPBR(inputData, surfaceData, toonShadingData);
}
////////////////////////////////////////////////////////////////////////////////
/// Phong lighting...
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData, ToonShadingData toonShadingData)
{
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
{
return debugColor;
}
#endif
uint meshRenderingLayers = GetMeshRenderingLightLayer();
half4 shadowMask = CalculateShadowMask(inputData);
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, aoFactor);
inputData.bakedGI *= surfaceData.albedo;
LightingData lightingData = CreateLightingData(inputData, surfaceData);
if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
{
lightingData.mainLightColor += CalculateBlinnPhong(mainLight, inputData, surfaceData, toonShadingData);
}
#if defined(_ADDITIONAL_LIGHTS)
uint pixelLightCount = GetAdditionalLightsCount();
#if USE_CLUSTERED_LIGHTING
for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
{
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
{
lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, toonShadingData);
}
}
#endif
LIGHT_LOOP_BEGIN(pixelLightCount)
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
{
lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, toonShadingData);
}
LIGHT_LOOP_END
#endif
#if defined(_ADDITIONAL_LIGHTS_VERTEX)
lightingData.vertexLightingColor += inputData.vertexLighting * surfaceData.albedo;
#endif
return CalculateFinalColor(lightingData, surfaceData.alpha);
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half smoothness, half3 emission, half alpha, half3 normalTS, ToonShadingData toonShadingData)
{
SurfaceData surfaceData;
surfaceData.albedo = diffuse;
surfaceData.alpha = alpha;
surfaceData.emission = emission;
surfaceData.metallic = 0;
surfaceData.occlusion = 1;
surfaceData.smoothness = smoothness;
surfaceData.specular = specularGloss.rgb;
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
surfaceData.normalTS = normalTS;
return UniversalFragmentBlinnPhong(inputData, surfaceData, toonShadingData);
}
////////////////////////////////////////////////////////////////////////////////
/// Unlit
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData)
{
#ifdef _ALPHAPREMULTIPLY_ON
surfaceData.albedo *= surfaceData.alpha;
#endif
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
{
return debugColor;
}
#endif
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
LightingData lightingData = CreateLightingData(inputData, surfaceData);
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION))
{
lightingData.giColor *= aoFactor.indirectAmbientOcclusion;
}
return CalculateFinalColor(lightingData, surfaceData.albedo, surfaceData.alpha, inputData.fogCoord);
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentBakedLit(InputData inputData, half3 color, half alpha, half3 normalTS)
{
SurfaceData surfaceData;
surfaceData.albedo = color;
surfaceData.alpha = alpha;
surfaceData.emission = half3(0, 0, 0);
surfaceData.metallic = 0;
surfaceData.occlusion = 1;
surfaceData.smoothness = 1;
surfaceData.specular = half3(0, 0, 0);
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
surfaceData.normalTS = normalTS;
return UniversalFragmentBakedLit(inputData, surfaceData);
}
#endif
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: d4ab68726c9ecff45acddaaf5dee1687
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/xxSharedTTSDependecies/ModifiedLightingFunctions/URP/LightingModifiedForToon2021.hlsl
uploadId: 919972
@@ -0,0 +1,598 @@
#ifndef UNIVERSAL_LIGHTING_TOON_INCLUDED
#define UNIVERSAL_LIGHTING_TOON_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
#if defined(LIGHTMAP_ON)
#define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) float2 lmName : TEXCOORD##index
#define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) OUT.xy = lightmapUV.xy * lightmapScaleOffset.xy + lightmapScaleOffset.zw;
#define OUTPUT_SH(normalWS, OUT)
#else
#define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) half3 shName : TEXCOORD##index
#define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT)
#define OUTPUT_SH(normalWS, OUT) OUT.xyz = SampleSHVertex(normalWS)
#endif
///////////////////////////////////////////////////////////////////////////////
// Lighting Functions //
///////////////////////////////////////////////////////////////////////////////
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal)
{
half NdotL = saturate(dot(normal, lightDir));
return lightColor * NdotL;
}
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal, half modifiedLightIntensity)
{
return lightColor * modifiedLightIntensity;
}
//half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness)
//{
// float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
// half NdotH = half(saturate(dot(normal, halfVec)));
// half modifier = pow(NdotH, smoothness);
// half3 specularReflection = specular.rgb * modifier;
// return lightColor * specularReflection;
//}
half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness, ToonShadingData toonShadingData)
{
float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
if (toonShadingData.enableToonShading == 1)
{
if (toonShadingData.specularAffectedByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
else
{
normal = toonShadingData.normalWS;
}
}
half NdotH = saturate(dot(normal, halfVec));
half modifier = pow(NdotH, smoothness);
half3 specularReflection;
if (toonShadingData.enableToonShading == 1)
{
//if (toonShadingData.specularEdgeSmoothness < 1)
//{
// specularReflection = specular.rgb * modifier;
// specularReflection = smoothstep(0.01, 0.01 + toonShadingData.cellTransitionSmoothness, specularReflection);
//}
//else
//{
// specularReflection = specular.rgb * modifier;
//}
specularReflection = PosterizeShifted(saturate(specular.rgb) * modifier, toonShadingData);
}
else
{
specularReflection = saturate(specular.rgb) * modifier;
}
return lightColor * specularReflection;
}
half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat,
half3 lightColor, half3 lightDirectionWS, half lightAttenuation,
half3 normalWS, half3 viewDirectionWS,
half clearCoatMask, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
toonShadingData.normalWS = normalWS;
//half NdotL = saturate(dot(normalWS, lightDirectionWS));
half NdotL = CalculateCellShadingPartitioning(lightDirectionWS, toonShadingData);
half3 radiance = lightColor * (lightAttenuation * NdotL);
half3 brdf = brdfData.diffuse;
#ifndef _SPECULARHIGHLIGHTS_OFF
[branch]
if (!specularHighlightsOff)
{
half3 specularNormal;
if (toonShadingData.specularAffectedByNormalMap == 1)
{
specularNormal = normalWS;
}
else
{
specularNormal = toonShadingData.normalWSNoMap;
}
//brdf += brdfData.specular * DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS); //original
half3 specular = brdfData.specular * DirectBRDFSpecular(brdfData, specularNormal, lightDirectionWS, viewDirectionWS);
if (toonShadingData.enableToonShading == 1)
{
//specular = specular / brdfData.normalizationTerm;
specular = PosterizeShifted(specular, toonShadingData);
// specular = specular * brdfData.normalizationTerm;
}
brdf += specular;
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
// Clear coat evaluates the specular a second timw and has some common terms with the base specular.
// We rely on the compiler to merge these and compute them only once.
half brdfCoat = kDielectricSpec.r * DirectBRDFSpecular(brdfDataClearCoat, normalWS, lightDirectionWS, viewDirectionWS);
// Mix clear coat and base layer using khronos glTF recommended formula
// https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md
// Use NoV for direct too instead of LoH as an optimization (NoV is light invariant).
half NoV = saturate(dot(normalWS, viewDirectionWS));
// Use slightly simpler fresnelTerm (Pow4 vs Pow5) as a small optimization.
// It is matching fresnel used in the GI/Env, so should produce a consistent clear coat blend (env vs. direct)
half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * Pow4(1.0 - NoV);
brdf = brdf * (1.0 - clearCoatMask * coatFresnel) + brdfCoat * clearCoatMask;
#endif // _CLEARCOAT
}
#endif // _SPECULARHIGHLIGHTS_OFF
return brdf * radiance;
}
half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, Light light, half3 normalWS, half3 viewDirectionWS, half clearCoatMask, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
return LightingPhysicallyBased(brdfData, brdfDataClearCoat, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, clearCoatMask, specularHighlightsOff, toonShadingData);
}
// Backwards compatibility
half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS,
ToonShadingData toonShadingData)
{
#ifdef _SPECULARHIGHLIGHTS_OFF
bool specularHighlightsOff = true;
#else
bool specularHighlightsOff = false;
#endif
const BRDFData noClearCoat = (BRDFData) 0;
return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS,
ToonShadingData toonShadingData)
{
Light light;
light.color = lightColor;
light.direction = lightDirectionWS;
light.distanceAttenuation = lightAttenuation;
light.shadowAttenuation = 1;
return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
const BRDFData noClearCoat = (BRDFData) 0;
return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
Light light;
light.color = lightColor;
light.direction = lightDirectionWS;
light.distanceAttenuation = lightAttenuation;
light.shadowAttenuation = 1;
return LightingPhysicallyBased(brdfData, light, viewDirectionWS, specularHighlightsOff, specularHighlightsOff, toonShadingData);
}
half3 VertexLighting(float3 positionWS, half3 normalWS)
{
half3 vertexLightColor = half3(0.0, 0.0, 0.0);
#ifdef _ADDITIONAL_LIGHTS_VERTEX
uint lightsCount = GetAdditionalLightsCount();
uint meshRenderingLayers = GetMeshRenderingLayer();
LIGHT_LOOP_BEGIN(lightsCount)
Light light = GetAdditionalLight(lightIndex, positionWS);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
half3 lightColor = light.color * light.distanceAttenuation;
vertexLightColor += LightingLambert(lightColor, light.direction, normalWS);
}
LIGHT_LOOP_END
#endif
return vertexLightColor;
}
struct LightingData
{
half3 giColor;
half3 mainLightColor;
half3 additionalLightsColor;
half3 vertexLightingColor;
half3 emissionColor;
};
half3 CalculateLightingColor(LightingData lightingData, half3 albedo)
{
half3 lightingColor = 0;
if (IsOnlyAOLightingFeatureEnabled())
{
return lightingData.giColor; // Contains white + AO
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_GLOBAL_ILLUMINATION))
{
lightingColor += lightingData.giColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_MAIN_LIGHT))
{
lightingColor += lightingData.mainLightColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_ADDITIONAL_LIGHTS))
{
lightingColor += lightingData.additionalLightsColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_VERTEX_LIGHTING))
{
lightingColor += lightingData.vertexLightingColor;
}
lightingColor *= albedo;
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_EMISSION))
{
lightingColor += lightingData.emissionColor;
}
return lightingColor;
}
half4 CalculateFinalColor(LightingData lightingData, half alpha)
{
half3 finalColor = CalculateLightingColor(lightingData, 1);
return half4(finalColor, alpha);
}
half4 CalculateFinalColor(LightingData lightingData, half3 albedo, half alpha, float fogCoord)
{
#if defined(_FOG_FRAGMENT)
#if (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))
float viewZ = -fogCoord;
float nearToFarZ = max(viewZ - _ProjectionParams.y, 0);
half fogFactor = ComputeFogFactorZ0ToFar(nearToFarZ);
#else
half fogFactor = 0;
#endif
#else
half fogFactor = fogCoord;
#endif
half3 lightingColor = CalculateLightingColor(lightingData, albedo);
half3 finalColor = MixFog(lightingColor, fogFactor);
return half4(finalColor, alpha);
}
LightingData CreateLightingData(InputData inputData, SurfaceData surfaceData)
{
LightingData lightingData;
lightingData.giColor = inputData.bakedGI;
lightingData.emissionColor = surfaceData.emission;
lightingData.vertexLightingColor = 0;
lightingData.mainLightColor = 0;
lightingData.additionalLightsColor = 0;
return lightingData;
}
half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData, ToonShadingData toonShadingData)
{
half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
float modifiedLightIntensity = CalculateCellShadingPartitioning(light.direction, toonShadingData);
//half3 lightDiffuseColor = LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS, modifiedLightIntensity);
half3 lightDiffuseColor = attenuatedLightColor * modifiedLightIntensity;
half3 lightSpecularColor = half3(0, 0, 0);
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
half smoothness = exp2(10 * surfaceData.smoothness + 1);
lightSpecularColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, 1), smoothness, toonShadingData);
#endif
#if _ALPHAPREMULTIPLY_ON
return lightDiffuseColor * surfaceData.albedo * surfaceData.alpha + lightSpecularColor;
#else
return lightDiffuseColor * surfaceData.albedo + lightSpecularColor;
#endif
}
///////////////////////////////////////////////////////////////////////////////
// Fragment Functions //
// Used by ShaderGraph and others builtin renderers //
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// PBR lighting...
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData, ToonShadingData toonShadingData)
{
#if defined(_SPECULARHIGHLIGHTS_OFF)
bool specularHighlightsOff = true;
#else
bool specularHighlightsOff = false;
#endif
BRDFData brdfData;
// NOTE: can modify "surfaceData"...
InitializeBRDFData(surfaceData, brdfData);
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, brdfData, debugColor))
{
return debugColor;
}
#endif
// Clear-coat calculation...
BRDFData brdfDataClearCoat = CreateClearCoatBRDFData(surfaceData, brdfData);
half4 shadowMask = CalculateShadowMask(inputData);
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
//if (toonShadingData.shadingAffectByNormalMap == 0)
//{
// aoFactor.indirectAmbientOcclusion = 1;
// aoFactor.directAmbientOcclusion = 1;
//}
uint meshRenderingLayers = GetMeshRenderingLayer();
Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
// NOTE: We don't apply AO to the GI here because it's done in the lighting calculation below...
half3 normal = inputData.normalWS;
if (toonShadingData.enableToonShading == 1 && toonShadingData.shadingAffectByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
MixRealtimeAndBakedGI(mainLight, normal, inputData.bakedGI);
LightingData lightingData = CreateLightingData(inputData, surfaceData);
lightingData.giColor = GlobalIllumination(brdfData, brdfDataClearCoat, surfaceData.clearCoatMask,
inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
normal, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
#endif
{
lightingData.mainLightColor = LightingPhysicallyBased(brdfData, brdfDataClearCoat,
mainLight,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
#if defined(_ADDITIONAL_LIGHTS)
uint pixelLightCount = GetAdditionalLightsCount();
#if USE_FORWARD_PLUS
for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
{
FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
}
#endif
LIGHT_LOOP_BEGIN(pixelLightCount)
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
LIGHT_LOOP_END
#endif
#if defined(_ADDITIONAL_LIGHTS_VERTEX)
lightingData.vertexLightingColor += inputData.vertexLighting * brdfData.diffuse;
#endif
#if REAL_IS_HALF
// Clamp any half.inf+ to HALF_MAX
return min(CalculateFinalColor(lightingData, surfaceData.alpha), HALF_MAX);
#else
return CalculateFinalColor(lightingData, surfaceData.alpha);
#endif
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular,
half smoothness, half occlusion, half3 emission, half alpha, ToonShadingData toonShadingData)
{
SurfaceData surfaceData;
surfaceData.albedo = albedo;
surfaceData.specular = specular;
surfaceData.metallic = metallic;
surfaceData.smoothness = smoothness;
surfaceData.normalTS = half3(0, 0, 1);
surfaceData.emission = emission;
surfaceData.occlusion = occlusion;
surfaceData.alpha = alpha;
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
return UniversalFragmentPBR(inputData, surfaceData, toonShadingData);
}
////////////////////////////////////////////////////////////////////////////////
/// Phong lighting...
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData, ToonShadingData toonShadingData)
{
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
{
return debugColor;
}
#endif
uint meshRenderingLayers = GetMeshRenderingLayer();
half4 shadowMask = CalculateShadowMask(inputData);
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, aoFactor);
inputData.bakedGI *= surfaceData.albedo;
LightingData lightingData = CreateLightingData(inputData, surfaceData);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
#endif
{
lightingData.mainLightColor += CalculateBlinnPhong(mainLight, inputData, surfaceData, toonShadingData);
}
#if defined(_ADDITIONAL_LIGHTS)
uint pixelLightCount = GetAdditionalLightsCount();
#if USE_FORWARD_PLUS
for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
{
FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, toonShadingData);
}
}
#endif
LIGHT_LOOP_BEGIN(pixelLightCount)
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, toonShadingData);
}
LIGHT_LOOP_END
#endif
#if defined(_ADDITIONAL_LIGHTS_VERTEX)
lightingData.vertexLightingColor += inputData.vertexLighting * surfaceData.albedo;
#endif
return CalculateFinalColor(lightingData, surfaceData.alpha);
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half smoothness, half3 emission, half alpha, half3 normalTS, ToonShadingData toonShadingData)
{
SurfaceData surfaceData;
surfaceData.albedo = diffuse;
surfaceData.alpha = alpha;
surfaceData.emission = emission;
surfaceData.metallic = 0;
surfaceData.occlusion = 1;
surfaceData.smoothness = smoothness;
surfaceData.specular = specularGloss.rgb;
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
surfaceData.normalTS = normalTS;
return UniversalFragmentBlinnPhong(inputData, surfaceData, toonShadingData);
}
////////////////////////////////////////////////////////////////////////////////
/// Unlit
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData)
{
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
{
return debugColor;
}
#endif
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
LightingData lightingData = CreateLightingData(inputData, surfaceData);
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION))
{
lightingData.giColor *= aoFactor.indirectAmbientOcclusion;
}
return CalculateFinalColor(lightingData, surfaceData.albedo, surfaceData.alpha, inputData.fogCoord);
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentBakedLit(InputData inputData, half3 color, half alpha, half3 normalTS)
{
SurfaceData surfaceData;
surfaceData.albedo = color;
surfaceData.alpha = alpha;
surfaceData.emission = half3(0, 0, 0);
surfaceData.metallic = 0;
surfaceData.occlusion = 1;
surfaceData.smoothness = 1;
surfaceData.specular = half3(0, 0, 0);
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
surfaceData.normalTS = normalTS;
return UniversalFragmentBakedLit(inputData, surfaceData);
}
#endif
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 300760cbabfe973489f2dd97ef8399ae
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/xxSharedTTSDependecies/ModifiedLightingFunctions/URP/LightingModifiedForToon2022.hlsl
uploadId: 919972
@@ -0,0 +1,610 @@
#ifndef UNIVERSAL_LIGHTING_INCLUDED
#define UNIVERSAL_LIGHTING_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
#if defined(LIGHTMAP_ON)
#define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) float2 lmName : TEXCOORD##index
#define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) OUT.xy = lightmapUV.xy * lightmapScaleOffset.xy + lightmapScaleOffset.zw;
#define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION)
#define OUTPUT_SH(normalWS, OUT)
#else
#define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) half3 shName : TEXCOORD##index
#define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT)
#ifdef USE_APV_PROBE_OCCLUSION
#define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir, OUT_OCCLUSION)
#else
#define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir)
#endif
// Note: This is the legacy function, which does not support APV.
// Kept to avoid breaking shaders still calling it (UUM-37723)
#define OUTPUT_SH(normalWS, OUT) OUT.xyz = SampleSHVertex(normalWS)
#endif
///////////////////////////////////////////////////////////////////////////////
// Lighting Functions //
///////////////////////////////////////////////////////////////////////////////
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal)
{
half NdotL = saturate(dot(normal, lightDir));
return lightColor * NdotL;
}
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal, half modifiedLightIntensity)
{
return lightColor * modifiedLightIntensity;
}
//half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness)
//{
// float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
// half NdotH = half(saturate(dot(normal, halfVec)));
// half modifier = pow(float(NdotH), float(smoothness)); // Half produces banding, need full precision
// // NOTE: In order to fix internal compiler error on mobile platforms, this needs to be float3
// float3 specularReflection = specular.rgb * modifier;
// return lightColor * specularReflection;
//}
half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness, ToonShadingData toonShadingData)
{
float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
if (toonShadingData.enableToonShading == 1)
{
if (toonShadingData.specularAffectedByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
else
{
normal = toonShadingData.normalWS;
}
}
half NdotH = saturate(dot(normal, halfVec));
half modifier = pow(NdotH, smoothness);
half3 specularReflection;
if (toonShadingData.enableToonShading == 1)
{
//if (toonShadingData.specularEdgeSmoothness < 1)
//{
// specularReflection = specular.rgb * modifier;
// specularReflection = smoothstep(0.01, 0.01 + toonShadingData.specularEdgeSmoothness, specularReflection);
//}
//else
//{
// specularReflection = specular.rgb * modifier;
//}
specularReflection = PosterizeShifted(saturate(specular.rgb) * modifier, toonShadingData);
}
else
{
specularReflection = saturate(specular.rgb) * modifier;
}
return lightColor * specularReflection;
}
half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat,
half3 lightColor, half3 lightDirectionWS, float lightAttenuation,
half3 normalWS, half3 viewDirectionWS,
half clearCoatMask, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
toonShadingData.normalWS = normalWS;
//half NdotL = saturate(dot(normalWS, lightDirectionWS));
half NdotL = CalculateCellShadingPartitioning(lightDirectionWS, toonShadingData);
half3 radiance = lightColor * (lightAttenuation * NdotL);
half3 brdf = brdfData.diffuse;
#ifndef _SPECULARHIGHLIGHTS_OFF
[branch]
if (!specularHighlightsOff)
{
//original:
//brdf += brdfData.specular * DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS);
half3 specularNormal;
if (toonShadingData.specularAffectedByNormalMap == 1)
{
specularNormal = normalWS;
}
else
{
specularNormal = toonShadingData.normalWSNoMap;
}
half3 specular = brdfData.specular * DirectBRDFSpecular(brdfData, specularNormal, lightDirectionWS, viewDirectionWS);
if (toonShadingData.enableToonShading == 1)
{
//specular = specular / brdfData.normalizationTerm;
specular = PosterizeShifted(specular, toonShadingData);
// specular = specular * brdfData.normalizationTerm;
}
brdf += specular;
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
// Clear coat evaluates the specular a second timw and has some common terms with the base specular.
// We rely on the compiler to merge these and compute them only once.
half brdfCoat = kDielectricSpec.r * DirectBRDFSpecular(brdfDataClearCoat, normalWS, lightDirectionWS, viewDirectionWS);
// Mix clear coat and base layer using khronos glTF recommended formula
// https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md
// Use NoV for direct too instead of LoH as an optimization (NoV is light invariant).
half NoV = saturate(dot(normalWS, viewDirectionWS));
// Use slightly simpler fresnelTerm (Pow4 vs Pow5) as a small optimization.
// It is matching fresnel used in the GI/Env, so should produce a consistent clear coat blend (env vs. direct)
half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * Pow4(1.0 - NoV);
brdf = brdf * (1.0 - clearCoatMask * coatFresnel) + brdfCoat * clearCoatMask;
#endif // _CLEARCOAT
}
#endif // _SPECULARHIGHLIGHTS_OFF
return brdf * radiance;
}
half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, Light light, half3 normalWS, half3 viewDirectionWS, half clearCoatMask, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
return LightingPhysicallyBased(brdfData, brdfDataClearCoat, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, clearCoatMask, specularHighlightsOff, toonShadingData);
}
// Backwards compatibility
half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS,
ToonShadingData toonShadingData)
{
#ifdef _SPECULARHIGHLIGHTS_OFF
bool specularHighlightsOff = true;
#else
bool specularHighlightsOff = false;
#endif
const BRDFData noClearCoat = (BRDFData) 0;
return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS,
ToonShadingData toonShadingData)
{
Light light;
light.color = lightColor;
light.direction = lightDirectionWS;
light.distanceAttenuation = lightAttenuation;
light.shadowAttenuation = 1;
return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
const BRDFData noClearCoat = (BRDFData) 0;
return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
Light light;
light.color = lightColor;
light.direction = lightDirectionWS;
light.distanceAttenuation = lightAttenuation;
light.shadowAttenuation = 1;
return LightingPhysicallyBased(brdfData, light, viewDirectionWS, specularHighlightsOff, specularHighlightsOff, toonShadingData);
}
half3 VertexLighting(float3 positionWS, half3 normalWS)
{
half3 vertexLightColor = half3(0.0, 0.0, 0.0);
#ifdef _ADDITIONAL_LIGHTS_VERTEX
uint lightsCount = GetAdditionalLightsCount();
uint meshRenderingLayers = GetMeshRenderingLayer();
LIGHT_LOOP_BEGIN(lightsCount)
Light light = GetAdditionalLight(lightIndex, positionWS);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
half3 lightColor = light.color * light.distanceAttenuation;
vertexLightColor += LightingLambert(lightColor, light.direction, normalWS);
}
LIGHT_LOOP_END
#endif
return vertexLightColor;
}
struct LightingData
{
half3 giColor;
half3 mainLightColor;
half3 additionalLightsColor;
half3 vertexLightingColor;
half3 emissionColor;
};
half3 CalculateLightingColor(LightingData lightingData, half3 albedo)
{
half3 lightingColor = 0;
if (IsOnlyAOLightingFeatureEnabled())
{
return lightingData.giColor; // Contains white + AO
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_GLOBAL_ILLUMINATION))
{
lightingColor += lightingData.giColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_MAIN_LIGHT))
{
lightingColor += lightingData.mainLightColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_ADDITIONAL_LIGHTS))
{
lightingColor += lightingData.additionalLightsColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_VERTEX_LIGHTING))
{
lightingColor += lightingData.vertexLightingColor;
}
lightingColor *= albedo;
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_EMISSION))
{
lightingColor += lightingData.emissionColor;
}
return lightingColor;
}
half4 CalculateFinalColor(LightingData lightingData, half alpha)
{
half3 finalColor = CalculateLightingColor(lightingData, 1);
return half4(finalColor, alpha);
}
half4 CalculateFinalColor(LightingData lightingData, half3 albedo, half alpha, float fogCoord)
{
#if defined(_FOG_FRAGMENT)
#if (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))
float viewZ = -fogCoord;
float nearToFarZ = max(viewZ - _ProjectionParams.y, 0);
half fogFactor = ComputeFogFactorZ0ToFar(nearToFarZ);
#else
half fogFactor = 0;
#endif
#else
half fogFactor = fogCoord;
#endif
half3 lightingColor = CalculateLightingColor(lightingData, albedo);
half3 finalColor = MixFog(lightingColor, fogFactor);
return half4(finalColor, alpha);
}
LightingData CreateLightingData(InputData inputData, SurfaceData surfaceData)
{
LightingData lightingData;
lightingData.giColor = inputData.bakedGI;
lightingData.emissionColor = surfaceData.emission;
lightingData.vertexLightingColor = 0;
lightingData.mainLightColor = 0;
lightingData.additionalLightsColor = 0;
return lightingData;
}
half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData,
ToonShadingData toonShadingData)
{
half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
float modifiedLightIntensity = CalculateCellShadingPartitioning(light.direction, toonShadingData);
half3 lightDiffuseColor = LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS, modifiedLightIntensity);
half3 lightSpecularColor = half3(0, 0, 0);
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
half smoothness = exp2(10 * surfaceData.smoothness + 1);
lightSpecularColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, 1), smoothness, toonShadingData);
#endif
#if _ALPHAPREMULTIPLY_ON
return lightDiffuseColor * surfaceData.albedo * surfaceData.alpha + lightSpecularColor;
#else
return lightDiffuseColor * surfaceData.albedo + lightSpecularColor;
#endif
}
///////////////////////////////////////////////////////////////////////////////
// Fragment Functions //
// Used by ShaderGraph and others builtin renderers //
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// PBR lighting...
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData,
ToonShadingData toonShadingData)
{
#if defined(_SPECULARHIGHLIGHTS_OFF)
bool specularHighlightsOff = true;
#else
bool specularHighlightsOff = false;
#endif
BRDFData brdfData;
// NOTE: can modify "surfaceData"...
InitializeBRDFData(surfaceData, brdfData);
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, brdfData, debugColor))
{
return debugColor;
}
#endif
// Clear-coat calculation...
BRDFData brdfDataClearCoat = CreateClearCoatBRDFData(surfaceData, brdfData);
half4 shadowMask = CalculateShadowMask(inputData);
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
uint meshRenderingLayers = GetMeshRenderingLayer();
Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
half3 normal = inputData.normalWS;
if (toonShadingData.shadingAffectByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
// NOTE: We don't apply AO to the GI here because it's done in the lighting calculation below...
MixRealtimeAndBakedGI(mainLight, normal, inputData.bakedGI);
LightingData lightingData = CreateLightingData(inputData, surfaceData);
lightingData.giColor = GlobalIllumination(brdfData, brdfDataClearCoat, surfaceData.clearCoatMask,
inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
normal, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
#endif
{
lightingData.mainLightColor = LightingPhysicallyBased(brdfData, brdfDataClearCoat,
mainLight,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
#if defined(_ADDITIONAL_LIGHTS)
uint pixelLightCount = GetAdditionalLightsCount();
#if USE_FORWARD_PLUS
[loop] for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
{
FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
}
#endif
LIGHT_LOOP_BEGIN(pixelLightCount)
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
LIGHT_LOOP_END
#endif
#if defined(_ADDITIONAL_LIGHTS_VERTEX)
lightingData.vertexLightingColor += inputData.vertexLighting * brdfData.diffuse;
#endif
#if REAL_IS_HALF
// Clamp any half.inf+ to HALF_MAX
return min(CalculateFinalColor(lightingData, surfaceData.alpha), HALF_MAX);
#else
return CalculateFinalColor(lightingData, surfaceData.alpha);
#endif
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular,
half smoothness, half occlusion, half3 emission, half alpha,
ToonShadingData toonShadingData)
{
SurfaceData surfaceData;
surfaceData.albedo = albedo;
surfaceData.specular = specular;
surfaceData.metallic = metallic;
surfaceData.smoothness = smoothness;
surfaceData.normalTS = half3(0, 0, 1);
surfaceData.emission = emission;
surfaceData.occlusion = occlusion;
surfaceData.alpha = alpha;
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
return UniversalFragmentPBR(inputData, surfaceData, toonShadingData);
}
////////////////////////////////////////////////////////////////////////////////
/// Phong lighting...
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData,
ToonShadingData toonShadingData)
{
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
{
return debugColor;
}
#endif
uint meshRenderingLayers = GetMeshRenderingLayer();
half4 shadowMask = CalculateShadowMask(inputData);
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, aoFactor);
inputData.bakedGI *= surfaceData.albedo;
LightingData lightingData = CreateLightingData(inputData, surfaceData);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
#endif
{
lightingData.mainLightColor += CalculateBlinnPhong(mainLight, inputData, surfaceData, toonShadingData);
}
#if defined(_ADDITIONAL_LIGHTS)
uint pixelLightCount = GetAdditionalLightsCount();
#if USE_FORWARD_PLUS
[loop] for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
{
FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, toonShadingData);
}
}
#endif
LIGHT_LOOP_BEGIN(pixelLightCount)
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, toonShadingData);
}
LIGHT_LOOP_END
#endif
#if defined(_ADDITIONAL_LIGHTS_VERTEX)
lightingData.vertexLightingColor += inputData.vertexLighting * surfaceData.albedo;
#endif
return CalculateFinalColor(lightingData, surfaceData.alpha);
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half smoothness, half3 emission, half alpha, half3 normalTS,
ToonShadingData toonShadingData)
{
SurfaceData surfaceData;
surfaceData.albedo = diffuse;
surfaceData.alpha = alpha;
surfaceData.emission = emission;
surfaceData.metallic = 0;
surfaceData.occlusion = 1;
surfaceData.smoothness = smoothness;
surfaceData.specular = specularGloss.rgb;
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
surfaceData.normalTS = normalTS;
return UniversalFragmentBlinnPhong(inputData, surfaceData, toonShadingData);
}
////////////////////////////////////////////////////////////////////////////////
/// Unlit
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData)
{
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
{
return debugColor;
}
#endif
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
LightingData lightingData = CreateLightingData(inputData, surfaceData);
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION))
{
lightingData.giColor *= aoFactor.indirectAmbientOcclusion;
}
return CalculateFinalColor(lightingData, surfaceData.albedo, surfaceData.alpha, inputData.fogCoord);
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentBakedLit(InputData inputData, half3 color, half alpha, half3 normalTS)
{
SurfaceData surfaceData;
surfaceData.albedo = color;
surfaceData.alpha = alpha;
surfaceData.emission = half3(0, 0, 0);
surfaceData.metallic = 0;
surfaceData.occlusion = 1;
surfaceData.smoothness = 1;
surfaceData.specular = half3(0, 0, 0);
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
surfaceData.normalTS = normalTS;
return UniversalFragmentBakedLit(inputData, surfaceData);
}
#endif
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 3aa2dfcb8a639dd4c960529ee4789b91
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/xxSharedTTSDependecies/ModifiedLightingFunctions/URP/LightingModifiedForToon2023.hlsl
uploadId: 919972
@@ -0,0 +1,625 @@
#ifndef UNIVERSAL_LIGHTING_INCLUDED
#define UNIVERSAL_LIGHTING_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
#if defined(LIGHTMAP_ON)
#define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) float2 lmName : TEXCOORD##index
#define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) OUT.xy = lightmapUV.xy * lightmapScaleOffset.xy + lightmapScaleOffset.zw;
#define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION)
#define OUTPUT_SH(normalWS, OUT)
#else
#define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) half3 shName : TEXCOORD##index
#define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT)
#ifdef USE_APV_PROBE_OCCLUSION
#define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir, OUT_OCCLUSION)
#else
#define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir)
#endif
// Note: This is the legacy function, which does not support APV.
// Kept to avoid breaking shaders still calling it (UUM-37723)
#define OUTPUT_SH(normalWS, OUT) OUT.xyz = SampleSHVertex(normalWS)
#endif
///////////////////////////////////////////////////////////////////////////////
// Lighting Functions //
///////////////////////////////////////////////////////////////////////////////
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal)
{
half NdotL = saturate(dot(normal, lightDir));
return lightColor * NdotL;
}
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal, half modifiedLightIntensity)
{
return lightColor * modifiedLightIntensity;
}
//half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness)
//{
// float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
// half NdotH = half(saturate(dot(normal, halfVec)));
// half modifier = pow(float(NdotH), float(smoothness)); // Half produces banding, need full precision
// // NOTE: In order to fix internal compiler error on mobile platforms, this needs to be float3
// float3 specularReflection = specular.rgb * modifier;
// return lightColor * specularReflection;
//}
half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness, ToonShadingData toonShadingData)
{
float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
if (toonShadingData.enableToonShading == 1)
{
if (toonShadingData.specularAffectedByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
else
{
normal = toonShadingData.normalWS;
}
}
half NdotH = saturate(dot(normal, halfVec));
half modifier = pow(NdotH, smoothness);
half3 specularReflection;
if (toonShadingData.enableToonShading == 1)
{
//if (toonShadingData.specularEdgeSmoothness < 1)
//{
// specularReflection = specular.rgb * modifier;
// specularReflection = smoothstep(0.01, 0.01 + toonShadingData.specularEdgeSmoothness, specularReflection);
//}
//else
//{
// specularReflection = specular.rgb * modifier;
//}
specularReflection = PosterizeShifted(saturate(specular.rgb) * modifier, toonShadingData);
}
else
{
specularReflection = saturate(specular.rgb) * modifier;
}
return lightColor * specularReflection;
}
half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat,
half3 lightColor, half3 lightDirectionWS, float lightAttenuation,
half3 normalWS, half3 viewDirectionWS,
half clearCoatMask, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
toonShadingData.normalWS = normalWS;
//half NdotL = saturate(dot(normalWS, lightDirectionWS));
half NdotL = CalculateCellShadingPartitioning(lightDirectionWS, toonShadingData);
half3 radiance = lightColor * (lightAttenuation * NdotL);
half3 brdf = brdfData.diffuse;
#ifndef _SPECULARHIGHLIGHTS_OFF
[branch]
if (!specularHighlightsOff)
{
//original:
//brdf += brdfData.specular * DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS);
half3 specularNormal;
if (toonShadingData.specularAffectedByNormalMap == 1)
{
specularNormal = normalWS;
}
else
{
specularNormal = toonShadingData.normalWSNoMap;
}
half3 specular = brdfData.specular * DirectBRDFSpecular(brdfData, specularNormal, lightDirectionWS, viewDirectionWS);
if (toonShadingData.enableToonShading == 1)
{
//specular = specular / brdfData.normalizationTerm;
specular = PosterizeShifted(specular, toonShadingData);
// specular = specular * brdfData.normalizationTerm;
}
brdf += specular;
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
// Clear coat evaluates the specular a second timw and has some common terms with the base specular.
// We rely on the compiler to merge these and compute them only once.
half brdfCoat = kDielectricSpec.r * DirectBRDFSpecular(brdfDataClearCoat, normalWS, lightDirectionWS, viewDirectionWS);
// Mix clear coat and base layer using khronos glTF recommended formula
// https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md
// Use NoV for direct too instead of LoH as an optimization (NoV is light invariant).
half NoV = saturate(dot(normalWS, viewDirectionWS));
// Use slightly simpler fresnelTerm (Pow4 vs Pow5) as a small optimization.
// It is matching fresnel used in the GI/Env, so should produce a consistent clear coat blend (env vs. direct)
half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * Pow4(1.0 - NoV);
brdf = brdf * (1.0 - clearCoatMask * coatFresnel) + brdfCoat * clearCoatMask;
#endif // _CLEARCOAT
}
#endif // _SPECULARHIGHLIGHTS_OFF
return brdf * radiance;
}
half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, Light light, half3 normalWS, half3 viewDirectionWS, half clearCoatMask, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
return LightingPhysicallyBased(brdfData, brdfDataClearCoat, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, clearCoatMask, specularHighlightsOff, toonShadingData);
}
// Backwards compatibility
half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS,
ToonShadingData toonShadingData)
{
#ifdef _SPECULARHIGHLIGHTS_OFF
bool specularHighlightsOff = true;
#else
bool specularHighlightsOff = false;
#endif
const BRDFData noClearCoat = (BRDFData) 0;
return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS,
ToonShadingData toonShadingData)
{
Light light;
light.color = lightColor;
light.direction = lightDirectionWS;
light.distanceAttenuation = lightAttenuation;
light.shadowAttenuation = 1;
return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
const BRDFData noClearCoat = (BRDFData) 0;
return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff, toonShadingData);
}
half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff,
ToonShadingData toonShadingData)
{
Light light;
light.color = lightColor;
light.direction = lightDirectionWS;
light.distanceAttenuation = lightAttenuation;
light.shadowAttenuation = 1;
return LightingPhysicallyBased(brdfData, light, viewDirectionWS, specularHighlightsOff, specularHighlightsOff, toonShadingData);
}
half3 VertexLighting(float3 positionWS, half3 normalWS)
{
half3 vertexLightColor = half3(0.0, 0.0, 0.0);
#ifdef _ADDITIONAL_LIGHTS_VERTEX
uint lightsCount = GetAdditionalLightsCount();
uint meshRenderingLayers = GetMeshRenderingLayer();
LIGHT_LOOP_BEGIN(lightsCount)
Light light = GetAdditionalLight(lightIndex, positionWS);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
half3 lightColor = light.color * light.distanceAttenuation;
vertexLightColor += LightingLambert(lightColor, light.direction, normalWS);
}
LIGHT_LOOP_END
#endif
return vertexLightColor;
}
struct LightingData
{
half3 giColor;
half3 mainLightColor;
half3 additionalLightsColor;
half3 vertexLightingColor;
half3 emissionColor;
};
half3 CalculateLightingColor(LightingData lightingData, half3 albedo)
{
half3 lightingColor = 0;
if (IsOnlyAOLightingFeatureEnabled())
{
return lightingData.giColor; // Contains white + AO
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_GLOBAL_ILLUMINATION))
{
lightingColor += lightingData.giColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_MAIN_LIGHT))
{
lightingColor += lightingData.mainLightColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_ADDITIONAL_LIGHTS))
{
lightingColor += lightingData.additionalLightsColor;
}
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_VERTEX_LIGHTING))
{
lightingColor += lightingData.vertexLightingColor;
}
lightingColor *= albedo;
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_EMISSION))
{
lightingColor += lightingData.emissionColor;
}
return lightingColor;
}
half4 CalculateFinalColor(LightingData lightingData, half alpha)
{
half3 finalColor = CalculateLightingColor(lightingData, 1);
return half4(finalColor, alpha);
}
half4 CalculateFinalColor(LightingData lightingData, half3 albedo, half alpha, float fogCoord)
{
half fogFactor = 0;
#if defined(_FOG_FRAGMENT)
bool anyFogEnabled = false;
#if defined(FOG_LINEAR_KEYWORD_DECLARED)
if (FOG_LINEAR)
anyFogEnabled = true;
#endif
#if defined(FOG_EXP_KEYWORD_DECLARED)
if (FOG_EXP)
anyFogEnabled = true;
#endif
#if defined(FOG_EXP2_KEYWORD_DECLARED)
if (FOG_EXP2)
anyFogEnabled = true;
#endif
if (anyFogEnabled)
{
float viewZ = -fogCoord;
float nearToFarZ = max(viewZ - _ProjectionParams.y, 0);
fogFactor = ComputeFogFactorZ0ToFar(nearToFarZ);
}
#else // #if defined(_FOG_FRAGMENT)
fogFactor = fogCoord;
#endif // #if defined(_FOG_FRAGMENT)
half3 lightingColor = CalculateLightingColor(lightingData, albedo);
half3 finalColor = MixFog(lightingColor, fogFactor);
return half4(finalColor, alpha);
}
LightingData CreateLightingData(InputData inputData, SurfaceData surfaceData)
{
LightingData lightingData;
lightingData.giColor = inputData.bakedGI;
lightingData.emissionColor = surfaceData.emission;
lightingData.vertexLightingColor = 0;
lightingData.mainLightColor = 0;
lightingData.additionalLightsColor = 0;
return lightingData;
}
half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData,
ToonShadingData toonShadingData)
{
half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
float modifiedLightIntensity = CalculateCellShadingPartitioning(light.direction, toonShadingData);
half3 lightDiffuseColor = LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS, modifiedLightIntensity);
half3 lightSpecularColor = half3(0, 0, 0);
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
half smoothness = exp2(10 * surfaceData.smoothness + 1);
lightSpecularColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, 1), smoothness, toonShadingData);
#endif
#if _ALPHAPREMULTIPLY_ON
return lightDiffuseColor * surfaceData.albedo * surfaceData.alpha + lightSpecularColor;
#else
return lightDiffuseColor * surfaceData.albedo + lightSpecularColor;
#endif
}
///////////////////////////////////////////////////////////////////////////////
// Fragment Functions //
// Used by ShaderGraph and others builtin renderers //
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// PBR lighting...
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData,
ToonShadingData toonShadingData)
{
#if defined(_SPECULARHIGHLIGHTS_OFF)
bool specularHighlightsOff = true;
#else
bool specularHighlightsOff = false;
#endif
BRDFData brdfData;
// NOTE: can modify "surfaceData"...
InitializeBRDFData(surfaceData, brdfData);
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, brdfData, debugColor))
{
return debugColor;
}
#endif
// Clear-coat calculation...
BRDFData brdfDataClearCoat = CreateClearCoatBRDFData(surfaceData, brdfData);
half4 shadowMask = CalculateShadowMask(inputData);
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
uint meshRenderingLayers = GetMeshRenderingLayer();
Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
half3 normal = inputData.normalWS;
if (toonShadingData.shadingAffectByNormalMap == 0)
{
normal = toonShadingData.normalWSNoMap;
}
// NOTE: We don't apply AO to the GI here because it's done in the lighting calculation below...
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI);
LightingData lightingData = CreateLightingData(inputData, surfaceData);
lightingData.giColor = GlobalIllumination(brdfData, brdfDataClearCoat, surfaceData.clearCoatMask,
inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
#endif
{
lightingData.mainLightColor = LightingPhysicallyBased(brdfData, brdfDataClearCoat,
mainLight,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
#if defined(_ADDITIONAL_LIGHTS)
uint pixelLightCount = GetAdditionalLightsCount();
#if USE_CLUSTER_LIGHT_LOOP
[loop] for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
{
CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
}
#endif
LIGHT_LOOP_BEGIN(pixelLightCount)
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
inputData.normalWS, inputData.viewDirectionWS,
surfaceData.clearCoatMask, specularHighlightsOff, toonShadingData);
}
LIGHT_LOOP_END
#endif
#if defined(_ADDITIONAL_LIGHTS_VERTEX)
lightingData.vertexLightingColor += inputData.vertexLighting * brdfData.diffuse;
#endif
#if REAL_IS_HALF
// Clamp any half.inf+ to HALF_MAX
return min(CalculateFinalColor(lightingData, surfaceData.alpha), HALF_MAX);
#else
return CalculateFinalColor(lightingData, surfaceData.alpha);
#endif
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular,
half smoothness, half occlusion, half3 emission, half alpha,
ToonShadingData toonShadingData)
{
SurfaceData surfaceData;
surfaceData.albedo = albedo;
surfaceData.specular = specular;
surfaceData.metallic = metallic;
surfaceData.smoothness = smoothness;
surfaceData.normalTS = half3(0, 0, 1);
surfaceData.emission = emission;
surfaceData.occlusion = occlusion;
surfaceData.alpha = alpha;
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
return UniversalFragmentPBR(inputData, surfaceData, toonShadingData);
}
////////////////////////////////////////////////////////////////////////////////
/// Phong lighting...
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData,
ToonShadingData toonShadingData)
{
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
{
return debugColor;
}
#endif
uint meshRenderingLayers = GetMeshRenderingLayer();
half4 shadowMask = CalculateShadowMask(inputData);
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, aoFactor);
inputData.bakedGI *= surfaceData.albedo;
LightingData lightingData = CreateLightingData(inputData, surfaceData);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
#endif
{
lightingData.mainLightColor += CalculateBlinnPhong(mainLight, inputData, surfaceData, toonShadingData);
}
#if defined(_ADDITIONAL_LIGHTS)
uint pixelLightCount = GetAdditionalLightsCount();
#if USE_CLUSTER_LIGHT_LOOP
[loop] for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
{
CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, toonShadingData);
}
}
#endif
LIGHT_LOOP_BEGIN(pixelLightCount)
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, toonShadingData);
}
LIGHT_LOOP_END
#endif
#if defined(_ADDITIONAL_LIGHTS_VERTEX)
lightingData.vertexLightingColor += inputData.vertexLighting * surfaceData.albedo;
#endif
return CalculateFinalColor(lightingData, surfaceData.alpha);
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half smoothness, half3 emission, half alpha, half3 normalTS,
ToonShadingData toonShadingData)
{
SurfaceData surfaceData;
surfaceData.albedo = diffuse;
surfaceData.alpha = alpha;
surfaceData.emission = emission;
surfaceData.metallic = 0;
surfaceData.occlusion = 1;
surfaceData.smoothness = smoothness;
surfaceData.specular = specularGloss.rgb;
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
surfaceData.normalTS = normalTS;
return UniversalFragmentBlinnPhong(inputData, surfaceData, toonShadingData);
}
////////////////////////////////////////////////////////////////////////////////
/// Unlit
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData)
{
#if defined(DEBUG_DISPLAY)
half4 debugColor;
if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
{
return debugColor;
}
#endif
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
LightingData lightingData = CreateLightingData(inputData, surfaceData);
if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION))
{
lightingData.giColor *= aoFactor.indirectAmbientOcclusion;
}
return CalculateFinalColor(lightingData, surfaceData.albedo, surfaceData.alpha, inputData.fogCoord);
}
// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
half4 UniversalFragmentBakedLit(InputData inputData, half3 color, half alpha, half3 normalTS)
{
SurfaceData surfaceData;
surfaceData.albedo = color;
surfaceData.alpha = alpha;
surfaceData.emission = half3(0, 0, 0);
surfaceData.metallic = 0;
surfaceData.occlusion = 1;
surfaceData.smoothness = 1;
surfaceData.specular = half3(0, 0, 0);
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
surfaceData.normalTS = normalTS;
return UniversalFragmentBakedLit(inputData, surfaceData);
}
#endif
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 7dfc426d10ce4cf4a8f9d13115f10d8f
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/xxSharedTTSDependecies/ModifiedLightingFunctions/URP/LightingModifiedForToon6p3.hlsl
uploadId: 919972
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 5c8e65ebe129b7a42a447a4799e080bf
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.3d/Scripts/Shaders/xxSharedTTSDependecies/TheToonShaderFunctions3D.hlsl
uploadId: 919972