593 lines
20 KiB
HLSL
593 lines
20 KiB
HLSL
//Unity Toon Shader/HDRP
|
|
//nobuyuki@unity3d.com
|
|
//toshiyuki@unity3d.com (Universal RP/HDRP)
|
|
|
|
#ifndef UCTS_HDRP_INCLUDED
|
|
#define UCTS_HDRP_INCLUDED
|
|
|
|
#include "Packages/com.misaki.hdrp-toon/Runtime/Shaders/Includes/Common/UtsCommon.hlsl"
|
|
|
|
#define UTS_LAYER_VISIBILITY
|
|
|
|
#ifndef DIRECTIONAL
|
|
# define DIRECTIONAL
|
|
#endif
|
|
|
|
#define FP_BUFFER 1
|
|
|
|
|
|
#if defined(UNITY_PASS_PREPASSBASE) || defined(UNITY_PASS_DEFERRED) || defined(UNITY_PASS_SHADOWCASTER)
|
|
#undef FOG_LINEAR
|
|
#undef FOG_EXP
|
|
#undef FOG_EXP2
|
|
#endif
|
|
|
|
#define Uts_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04)
|
|
|
|
#if 1
|
|
|
|
struct UTSData
|
|
{
|
|
};
|
|
|
|
struct UTSSurfaceData
|
|
{
|
|
uint materialFeatures;
|
|
|
|
real3 baseColor;
|
|
real3 firstShadingColor;
|
|
real3 secondShadingColor;
|
|
real alpha;
|
|
|
|
float3 normalWS;
|
|
real perceptualSmoothness;
|
|
real metallic;
|
|
real specularOcclusion;
|
|
real ambientOcclusion;
|
|
real3 specularColor;
|
|
|
|
float3 geomNormalWS;
|
|
float3 tangentWS;
|
|
|
|
real4 subsurfaceColor;
|
|
|
|
real anisotropy;
|
|
};
|
|
|
|
struct UtsBSDFData
|
|
{
|
|
uint materialFeatures;
|
|
|
|
real3 diffuseColor;
|
|
real3 firstShadingDiffuseColor;
|
|
real3 secondShadingDiffuseColor;
|
|
|
|
real3 fresnel0;
|
|
real fresnel90;
|
|
real reflectivity;
|
|
|
|
real ambientOcclusion;
|
|
real specularOcclusion;
|
|
real perceptualRoughness;
|
|
|
|
real3 subsurfaceColor;
|
|
|
|
float3 geomNormalWS;
|
|
float3 normalWS;
|
|
float3 tangentWS;
|
|
float3 bitangentWS;
|
|
|
|
real anisotropy;
|
|
real roughnessT;
|
|
real roughnessB;
|
|
};
|
|
|
|
UTSSurfaceData ConvertSurfaceDataToUTSSurfaceData(SurfaceData surfaceData)
|
|
{
|
|
UTSSurfaceData output;
|
|
ZERO_INITIALIZE(UTSSurfaceData, output);
|
|
|
|
output.materialFeatures = surfaceData.materialFeatures;
|
|
output.baseColor = surfaceData.baseColor;
|
|
output.alpha = 1.0;
|
|
output.normalWS = surfaceData.normalWS;
|
|
output.perceptualSmoothness = surfaceData.perceptualSmoothness;
|
|
output.metallic = surfaceData.metallic;
|
|
output.specularOcclusion = surfaceData.specularOcclusion;
|
|
output.ambientOcclusion = surfaceData.ambientOcclusion;
|
|
output.specularColor = surfaceData.specularColor;
|
|
output.geomNormalWS = surfaceData.geomNormalWS;
|
|
output.tangentWS = surfaceData.tangentWS;
|
|
output.subsurfaceColor.rgb = surfaceData.transmittanceColor;
|
|
output.subsurfaceColor.a = surfaceData.subsurfaceMask;
|
|
output.anisotropy = surfaceData.anisotropy;
|
|
|
|
return output;
|
|
}
|
|
|
|
UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
|
|
{
|
|
UTSSurfaceData output;
|
|
//ZERO_INITIALIZE(UTSSurfaceData, output);
|
|
|
|
output.materialFeatures = 0;
|
|
|
|
float4 mainTexture = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
|
|
output.baseColor = mainTexture.rgb * _BaseColor.rgb;
|
|
output.alpha = mainTexture.a;
|
|
|
|
float4 firstShadingTexture = SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
|
|
float4 secondShadingTexture = SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
|
|
output.firstShadingColor = lerp(firstShadingTexture.rgb, mainTexture.rgb, _Use_BaseAs1st) * _1st_ShadeColor.rgb;
|
|
output.secondShadingColor = lerp(secondShadingTexture.rgb, output.firstShadingColor, _Use_1stAs2nd) * _2nd_ShadeColor.rgb;
|
|
|
|
float4 normalLocal = float4(0, 0, 1.0, 1.0);
|
|
#if _NORMAL_MAP
|
|
if (_Use_SSSLut)
|
|
{
|
|
normalLocal = SAMPLE_TEXTURE2D_LOD(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap), _SSSIntensity);
|
|
}
|
|
else
|
|
{
|
|
normalLocal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
|
|
normalLocal.rgb = UnpackNormalScale(normalLocal, _NormalScale);
|
|
}
|
|
#endif
|
|
float3 normalWS = normalize(mul(normalLocal.rgb, input.tangentToWorld));
|
|
#if _PBR_MODE_OFF
|
|
float smoothness = 0.0;
|
|
float metallic = 0.0;
|
|
#else
|
|
float smoothness = _Smoothness;
|
|
float metallic = _Metallic;
|
|
#endif
|
|
float ao = 1.0;
|
|
float3 specularColor = 1;
|
|
float anisotropy = 0;
|
|
|
|
#ifdef _MASK_MAP
|
|
float4 _MaskMap_var = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
|
|
metallic = _MaskMap_var.x;
|
|
metallic = lerp(_MetallicRemapMin, _MetallicRemapMax, metallic);
|
|
ao = _MaskMap_var.y;
|
|
ao = lerp(_AORemapMin, _AORemapMax, ao);
|
|
smoothness = _MaskMap_var.w;
|
|
smoothness = lerp(_SmoothnessRemapMin, _SmoothnessRemapMax, smoothness);
|
|
#endif
|
|
|
|
#ifdef _ANISOTROPY_MAP
|
|
anisotropy = SAMPLE_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, TRANSFORM_TEX(input.texCoord0, _AnisotropyMap)).r;
|
|
#if _PBR_Mode_KK
|
|
anisotropy += _Anisotropy - 0.5;
|
|
#else
|
|
anisotropy *= _Anisotropy;
|
|
#endif
|
|
#else
|
|
anisotropy = 1.0;
|
|
anisotropy *= _Anisotropy;
|
|
#endif
|
|
|
|
#ifdef _PBR_Mode_KK
|
|
metallic = 0.0;
|
|
smoothness *=_BSDFContribution;
|
|
#endif
|
|
|
|
#ifdef _PBR_Mode_TOON
|
|
#ifdef _SPECULAR_COLOR_MAP
|
|
specularColor = SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)).rgb * _SpecularColor;
|
|
#endif
|
|
specularColor = GetSpecularColor(_MainTex_var.rgb * _BaseColor.rgb, metallic);
|
|
#endif
|
|
|
|
output.metallic = metallic;
|
|
output.ambientOcclusion = ao;
|
|
output.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(dot(normalWS, V), ao, PerceptualRoughnessToRoughness(1 - smoothness));
|
|
output.perceptualSmoothness = smoothness;
|
|
output.normalWS = normalWS;
|
|
output.specularColor = specularColor;
|
|
|
|
output.geomNormalWS = input.tangentToWorld[2];
|
|
output.tangentWS = Orthonormalize(input.tangentToWorld[0].rgb, normalWS);
|
|
|
|
output.subsurfaceColor = SAMPLE_TEXTURE2D(_SSSLutMap, sampler_MainTex, TRANSFORM_TEX(input.texCoord0, _BaseColorMap)) * _SSSIntensity;
|
|
|
|
output.anisotropy = anisotropy;
|
|
|
|
return output;
|
|
}
|
|
|
|
UtsBSDFData ConvertUTSSurfaceDataToUTSBSDFData(UTSSurfaceData surfaceData)
|
|
{
|
|
UtsBSDFData output;
|
|
|
|
output.materialFeatures = surfaceData.materialFeatures;
|
|
|
|
output.diffuseColor = UtsComputeDiffuseColor(surfaceData.baseColor, surfaceData.metallic, 0.05);
|
|
output.firstShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.firstShadingColor, surfaceData.metallic, 0.05);
|
|
output.secondShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.secondShadingColor, surfaceData.metallic, 0.05);
|
|
|
|
#if _PBR_MODE_OFF
|
|
output.fresnel0 = surfaceData.baseColor;
|
|
#else
|
|
output.fresnel0 = ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, 0.22);
|
|
#endif
|
|
output.fresnel90 = ComputeF90(output.fresnel0);
|
|
output.reflectivity = (1.0 - 0.22) * (1 - surfaceData.metallic);
|
|
|
|
output.ambientOcclusion = surfaceData.ambientOcclusion;
|
|
output.specularOcclusion = surfaceData.specularOcclusion;
|
|
output.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness);\
|
|
|
|
output.subsurfaceColor = surfaceData.subsurfaceColor.rgb * surfaceData.subsurfaceColor.a;
|
|
|
|
output.normalWS = surfaceData.normalWS;
|
|
output.geomNormalWS = surfaceData.geomNormalWS;
|
|
output.tangentWS = surfaceData.tangentWS;
|
|
output.bitangentWS = normalize(cross(surfaceData.normalWS, surfaceData.tangentWS));
|
|
|
|
output.anisotropy = surfaceData.anisotropy;
|
|
ConvertAnisotropyToRoughness(output.perceptualRoughness, surfaceData.anisotropy, output.roughnessT, output.roughnessB);
|
|
|
|
return output;
|
|
}
|
|
|
|
PreLightData GetPreLightData_UTS(float3 V, PositionInputs posInput, inout UtsBSDFData bsdfData)
|
|
{
|
|
PreLightData preLightData;
|
|
ZERO_INITIALIZE(PreLightData, preLightData);
|
|
|
|
float3 N = bsdfData.normalWS;
|
|
preLightData.NdotV = dot(N, V);
|
|
preLightData.iblPerceptualRoughness = bsdfData.perceptualRoughness;
|
|
|
|
float clampedNdotV = ClampNdotV(preLightData.NdotV);
|
|
|
|
// Handle IBL + area light + multiscattering.
|
|
// Note: use the not modified by anisotropy iblPerceptualRoughness here.
|
|
float specularReflectivity = 1.0;
|
|
#if _PBR_MODE_OFF
|
|
preLightData.diffuseFGD = 1.0;
|
|
preLightData.specularFGD = 1.0;
|
|
#else
|
|
GetPreIntegratedFGDGGXAndDisneyDiffuse(clampedNdotV, preLightData.iblPerceptualRoughness, bsdfData.fresnel0, bsdfData.fresnel90, preLightData.specularFGD, preLightData.diffuseFGD, specularReflectivity);
|
|
#endif
|
|
|
|
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
|
|
// Ref: Practical multiple scattering compensation for microfacet models.
|
|
// We only apply the formulation for metals.
|
|
// For dielectrics, the change of reflectance is negligible.
|
|
// We deem the intensity difference of a couple of percent for high values of roughness
|
|
// to not be worth the cost of another precomputed table.
|
|
// Note: this formulation bakes the BSDF non-symmetric!
|
|
preLightData.energyCompensation = 1.0 / specularReflectivity - 1.0;
|
|
#else
|
|
preLightData.energyCompensation = 0.0;
|
|
#endif // LIT_USE_GGX_ENERGY_COMPENSATION
|
|
|
|
float3 iblN;
|
|
|
|
#if _PBR_MODE_ANISOTROPY
|
|
float TdotV = dot(bsdfData.tangentWS, V);
|
|
float BdotV = dot(bsdfData.bitangentWS, V);
|
|
|
|
preLightData.partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, clampedNdotV, bsdfData.roughnessT, bsdfData.roughnessB);
|
|
|
|
// perceptualRoughness is use as input and output here
|
|
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS, N, V, bsdfData.anisotropy, preLightData.iblPerceptualRoughness, iblN, preLightData.iblPerceptualRoughness);
|
|
#else
|
|
preLightData.partLambdaV = GetSmithJointGGXPartLambdaV(clampedNdotV, bsdfData.roughnessT);
|
|
iblN = N;
|
|
#endif
|
|
|
|
preLightData.iblR = reflect(-V, iblN);
|
|
|
|
// Area light
|
|
#ifdef USE_DIFFUSE_LAMBERT_BRDF
|
|
preLightData.ltcTransformDiffuse = k_identity3x3;
|
|
|
|
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_SSS_DIFFUSE_POWER))
|
|
ModifyLambertLTCTransformForDiffusePower(preLightData.ltcTransformDiffuse, GetDiffusePower(bsdfData.diffusionProfileIndex));
|
|
#else
|
|
preLightData.ltcTransformDiffuse = SampleLtcMatrix(bsdfData.perceptualRoughness, clampedNdotV, LTCLIGHTINGMODEL_DISNEY_DIFFUSE);
|
|
#endif
|
|
|
|
float perceptualRoughnessA = bsdfData.perceptualRoughness;
|
|
|
|
preLightData.ltcTransformSpecular[0] = SampleLtcMatrix(perceptualRoughnessA, clampedNdotV, LTCLIGHTINGMODEL_GGX);
|
|
|
|
// Construct a right-handed view-dependent orthogonal basis around the normal
|
|
preLightData.orthoBasisViewNormal = GetOrthoBasisViewNormal(V, N, preLightData.NdotV);
|
|
|
|
preLightData.ltcTransformCoat = 0.0;
|
|
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
|
|
{
|
|
preLightData.ltcTransformCoat = SampleLtcMatrix(CLEAR_COAT_PERCEPTUAL_ROUGHNESS, clampedNdotV, LTCLIGHTINGMODEL_GGX);
|
|
}
|
|
|
|
return preLightData;
|
|
}
|
|
|
|
void UtsClampRoughness(inout PreLightData preLightData, inout UtsBSDFData bsdfData, float minRoughness)
|
|
{
|
|
bsdfData.roughnessT = max(minRoughness, bsdfData.roughnessT);
|
|
bsdfData.roughnessB = max(minRoughness, bsdfData.roughnessB);
|
|
}
|
|
|
|
// Legacy for compatibility with existing shaders
|
|
inline bool IsGammaSpace()
|
|
{
|
|
#ifdef UNITY_COLORSPACE_GAMMA
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
|
|
// normal should be normalized, w=1.0
|
|
half3 SHEvalLinearL0L1(half4 normal)
|
|
{
|
|
half3 x;
|
|
|
|
// Linear (L1) + constant (L0) polynomial terms
|
|
x.r = dot(unity_SHAr, normal);
|
|
x.g = dot(unity_SHAg, normal);
|
|
x.b = dot(unity_SHAb, normal);
|
|
|
|
return x;
|
|
}
|
|
|
|
// normal should be normalized, w=1.0
|
|
half3 SHEvalLinearL2(half4 normal)
|
|
{
|
|
half3 x1, x2;
|
|
// 4 of the quadratic (L2) polynomials
|
|
half4 vB = normal.xyzz * normal.yzzx;
|
|
x1.r = dot(unity_SHBr, vB);
|
|
x1.g = dot(unity_SHBg, vB);
|
|
x1.b = dot(unity_SHBb, vB);
|
|
|
|
// Final (5th) quadratic (L2) polynomial
|
|
half vC = normal.x * normal.x - normal.y * normal.y;
|
|
x2 = unity_SHC.rgb * vC;
|
|
|
|
return x1 + x2;
|
|
}
|
|
|
|
// normal should be normalized, w=1.0
|
|
// output in active color space
|
|
half3 ShadeSH9(half4 normal)
|
|
{
|
|
// Linear + constant polynomial terms
|
|
half3 res = SHEvalLinearL0L1(normal);
|
|
|
|
// Quadratic polynomials
|
|
res += SHEvalLinearL2(normal);
|
|
|
|
# ifdef UNITY_COLORSPACE_GAMMA
|
|
res = LinearToGammaSpace(res);
|
|
# endif
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 DecodeLightProbe(float3 N) {
|
|
return ShadeSH9(float4(N, 1));
|
|
}
|
|
|
|
|
|
inline float GammaToLinearSpaceExact(float value)
|
|
{
|
|
if (value <= 0.04045F)
|
|
return value / 12.92F;
|
|
else if (value < 1.0F)
|
|
return pow((value + 0.055F) / 1.055F, 2.4F);
|
|
else
|
|
return pow(value, 2.2F);
|
|
}
|
|
|
|
inline float3 GammaToLinearSpace(float3 sRGB)
|
|
{
|
|
// Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
|
|
return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);
|
|
|
|
// Precise version, useful for debugging.
|
|
//return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
|
|
}
|
|
|
|
inline float LinearToGammaSpaceExact(float value)
|
|
{
|
|
if (value <= 0.0F)
|
|
return 0.0F;
|
|
else if (value <= 0.0031308F)
|
|
return 12.92F * value;
|
|
else if (value < 1.0F)
|
|
return 1.055F * pow(value, 0.4166667F) - 0.055F;
|
|
else
|
|
return pow(value, 0.45454545F);
|
|
}
|
|
|
|
inline float3 LinearToGammaSpace(float3 linRGB)
|
|
{
|
|
linRGB = max(linRGB, float3(0.h, 0.h, 0.h));
|
|
// An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
|
|
return max(1.055h * pow(linRGB, 0.416666667h) - 0.055h, 0.h);
|
|
|
|
// Exact version, useful for debugging.
|
|
//return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b));
|
|
}
|
|
|
|
|
|
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
|
|
#define UNITY_FOG_COORDS(idx) UNITY_FOG_COORDS_PACKED(idx, float1)
|
|
|
|
#if (SHADER_TARGET < 30) || defined(SHADER_API_MOBILE)
|
|
// mobile or SM2.0: calculate fog factor per-vertex
|
|
#define UNITY_TRANSFER_FOG(o,outpos) UNITY_CALC_FOG_FACTOR((outpos).z); o.fogCoord.x = unityFogFactor
|
|
#else
|
|
// SM3.0 and PC/console: calculate fog distance per-vertex, and fog factor per-pixel
|
|
#define UNITY_TRANSFER_FOG(o,outpos) o.fogCoord.x = (outpos).z
|
|
#endif
|
|
#else
|
|
#define UNITY_FOG_COORDS(idx)
|
|
#define UNITY_TRANSFER_FOG(o,outpos)
|
|
#endif
|
|
|
|
#define UNITY_FOG_LERP_COLOR(col,fogCol,fogFac) col.rgb = lerp((fogCol).rgb, (col).rgb, saturate(fogFac))
|
|
|
|
|
|
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
|
|
#if (SHADER_TARGET < 30) || defined(SHADER_API_MOBILE)
|
|
// mobile or SM2.0: fog factor was already calculated per-vertex, so just lerp the color
|
|
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_FOG_LERP_COLOR(col,fogCol,(coord).x)
|
|
#else
|
|
// SM3.0 and PC/console: calculate fog factor and lerp fog color
|
|
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_CALC_FOG_FACTOR((coord).x); UNITY_FOG_LERP_COLOR(col,fogCol,unityFogFactor)
|
|
#endif
|
|
#else
|
|
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol)
|
|
#endif
|
|
|
|
#ifdef UNITY_PASS_FORWARDADD
|
|
#define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,fixed4(0,0,0,0))
|
|
#else
|
|
#define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,unity_FogColor)
|
|
#endif
|
|
|
|
#endif //#if false
|
|
|
|
#ifdef DIRECTIONAL
|
|
#define LIGHTING_COORDS(idx1,idx2) SHADOW_COORDS(idx1)
|
|
#define TRANSFER_VERTEX_TO_FRAGMENT(a) TRANSFER_SHADOW(a)
|
|
#define LIGHT_ATTENUATION(a) SHADOW_ATTENUATION(a)
|
|
#endif
|
|
|
|
// Transforms 2D UV by scale/bias property
|
|
//#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
|
|
#define UCTS_TEXTURE2D(tex,name) SAMPLE_TEXTURE2D(tex,sampler##tex,TRANSFORM_TEX(name, tex));
|
|
|
|
|
|
inline float4 UnityObjectToClipPosInstanced(in float3 pos)
|
|
{
|
|
// return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorldArray[unity_InstanceID], float4(pos, 1.0)));
|
|
// todo. right?
|
|
return mul(UNITY_MATRIX_VP, mul(UNITY_MATRIX_M, float4(pos, 1.0)));
|
|
}
|
|
inline float4 UnityObjectToClipPosInstanced(float4 pos)
|
|
{
|
|
return UnityObjectToClipPosInstanced(pos.xyz);
|
|
}
|
|
#define UnityObjectToClipPos UnityObjectToClipPosInstanced
|
|
|
|
inline float3 UnityObjectToWorldNormal( in float3 norm )
|
|
{
|
|
#ifdef UNITY_ASSUME_UNIFORM_SCALING
|
|
return UnityObjectToWorldDir(norm);
|
|
#else
|
|
// mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
|
|
return normalize(mul(norm, (float3x3)UNITY_MATRIX_M));
|
|
#endif
|
|
}
|
|
// normal should be normalized, w=1.0
|
|
float3 SHEvalLinearL0L1 (float4 normal)
|
|
{
|
|
float3 x;
|
|
|
|
// Linear (L1) + constant (L0) polynomial terms
|
|
x.r = dot(unity_SHAr,normal);
|
|
x.g = dot(unity_SHAg,normal);
|
|
x.b = dot(unity_SHAb,normal);
|
|
|
|
return x;
|
|
}
|
|
|
|
// normal should be normalized, w=1.0
|
|
float3 SHEvalLinearL2 (float4 normal)
|
|
{
|
|
float3 x1, x2;
|
|
// 4 of the quadratic (L2) polynomials
|
|
float4 vB = normal.xyzz * normal.yzzx;
|
|
x1.r = dot(unity_SHBr,vB);
|
|
x1.g = dot(unity_SHBg,vB);
|
|
x1.b = dot(unity_SHBb,vB);
|
|
|
|
// Final (5th) quadratic (L2) polynomial
|
|
half vC = normal.x*normal.x - normal.y*normal.y;
|
|
x2 = unity_SHC.rgb * vC;
|
|
|
|
return x1 + x2;
|
|
}
|
|
|
|
// normal should be normalized, w=1.0
|
|
// output in active color space
|
|
float3 ShadeSH9 (float4 normal)
|
|
{
|
|
// Linear + constant polynomial terms
|
|
float3 res = SHEvalLinearL0L1 (normal);
|
|
|
|
// Quadratic polynomials
|
|
res += SHEvalLinearL2 (normal);
|
|
|
|
# ifdef UNITY_COLORSPACE_GAMMA
|
|
res = LinearToGammaSpace (res);
|
|
# endif
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 SampleBakedGI_UTS(float3 positionRWS, float3 normalWS, float2 uvStaticLightmap, float2 uvDynamicLightmap, bool needToIncludeAPV = false)
|
|
{
|
|
float3 bakeDiffuseLighting = float3(0, 0, 0);
|
|
float3 backBakeDiffuseLighting = float3(0, 0, 0);
|
|
float3 backNormalWS = float3(0, 0, 0);
|
|
|
|
#if !defined(_SURFACE_TYPE_TRANSPARENT) && (SHADERPASS != SHADERPASS_RAYTRACING_INDIRECT) && (SHADERPASS != SHADERPASS_RAYTRACING_GBUFFER)
|
|
if (_IndirectDiffuseMode != INDIRECTDIFFUSEMODE_OFF
|
|
#if (SHADERPASS == SHADERPASS_GBUFER)
|
|
&& _IndirectDiffuseMode != INDIRECTDIFFUSEMODE_MIXED && _ReflectionsMode != REFLECTIONSMODE_MIXED
|
|
#endif
|
|
)
|
|
return bakeDiffuseLighting;
|
|
#endif
|
|
|
|
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
|
|
EvaluateLightmap(positionRWS, normalWS, backNormalWS, uvStaticLightmap, uvDynamicLightmap, bakeDiffuseLighting, backBakeDiffuseLighting);
|
|
#elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
|
|
if (needToIncludeAPV)
|
|
{
|
|
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(positionRWS), normalWS, backNormalWS, GetWorldSpaceNormalizeViewDir(positionRWS), 0.0, bakeDiffuseLighting, backBakeDiffuseLighting);
|
|
}
|
|
#else
|
|
EvaluateLightProbeBuiltin(positionRWS, normalWS, backNormalWS, bakeDiffuseLighting, backBakeDiffuseLighting);
|
|
#if defined(SHADER_STAGE_RAY_TRACING)
|
|
bakeDiffuseLighting *= _RayTracingAmbientProbeDimmer;
|
|
backBakeDiffuseLighting *= _RayTracingAmbientProbeDimmer;
|
|
#endif
|
|
#endif
|
|
|
|
return bakeDiffuseLighting;
|
|
}
|
|
|
|
float3 SampleBakedGI_UTS_OutLine(float3 positionRWS, float3 normalWS, float2 uvStaticLightmap, float2 uvDynamicLightmap)
|
|
{
|
|
float3 bakeDiffuseLighting = float3(0, 0, 0);
|
|
float3 backBakeDiffuseLighting = float3(0, 0, 0);
|
|
float3 backNormalWS = float3(0, 0, 0);
|
|
|
|
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
|
|
EvaluateLightmap(positionRWS, normalWS, backNormalWS, uvStaticLightmap, uvDynamicLightmap, bakeDiffuseLighting, backBakeDiffuseLighting);
|
|
#elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
|
|
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(positionRWS), normalWS, backNormalWS, GetWorldSpaceNormalizeViewDir(positionRWS), 0.0, bakeDiffuseLighting, backBakeDiffuseLighting);
|
|
#else
|
|
EvaluateLightProbeBuiltin(positionRWS, normalWS, backNormalWS, bakeDiffuseLighting, backBakeDiffuseLighting);
|
|
#if defined(SHADER_STAGE_RAY_TRACING)
|
|
bakeDiffuseLighting *= _RayTracingAmbientProbeDimmer;
|
|
backBakeDiffuseLighting *= _RayTracingAmbientProbeDimmer;
|
|
#endif
|
|
#endif
|
|
|
|
return bakeDiffuseLighting;
|
|
}
|
|
|
|
|
|
#endif //#ifndef UCTS_HDRP_INCLUDED |