Files
kronic e362aaeb43 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>
2026-06-02 22:50:43 -07:00

567 lines
22 KiB
HLSL
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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