197 lines
7.9 KiB
HLSL
197 lines
7.9 KiB
HLSL
// SPDX-License-Identifier: (Not available for this version, you are only allowed to use this software if you have express permission from the copyright holder and agreed to the latest NiloToonURP EULA)
|
|
// Copyright (c) 2021 Kuroneko ShaderLab Limited
|
|
|
|
#pragma once
|
|
|
|
#if _GENERIC_REFLECTION
|
|
half3 BlendGenericReflectionColor(half3 dstCol, half3 srcCol, half3 srcA, uint blendMode)
|
|
{
|
|
half3 add = dstCol + srcCol;
|
|
half3 mul = dstCol * srcCol;
|
|
half3 outCol = dstCol;
|
|
|
|
if (blendMode == 0) outCol = srcCol;
|
|
else if (blendMode == 1) outCol = add;
|
|
else if (blendMode == 2) outCol = max(add - mul, dstCol);
|
|
else if (blendMode == 3) outCol = mul;
|
|
|
|
return lerp(dstCol, outCol, srcA);
|
|
}
|
|
|
|
half GenericReflectionTooningScale(half value, half border, half blur)
|
|
{
|
|
half borderMin = saturate(border - blur * 0.5h);
|
|
half borderMax = saturate(border + blur * 0.5h);
|
|
return saturate((value - borderMin) / saturate(borderMax - borderMin + fwidth(value) * _lilAAStrength));
|
|
}
|
|
|
|
void GenericReflectionGSAAForSmoothness(inout half smoothness, half3 normalWS, half strength)
|
|
{
|
|
float3 dx = abs(ddx(normalWS));
|
|
float3 dy = abs(ddy(normalWS));
|
|
float dxy = max(dot(dx, dx), dot(dy, dy));
|
|
float roughnessGSAA = dxy / (dxy * 5.0 + 0.002) * strength;
|
|
smoothness = min(smoothness, saturate(1.0h - roughnessGSAA));
|
|
}
|
|
|
|
half3 GenericReflectionFresnelTerm(half3 f0, half cosA)
|
|
{
|
|
half a = 1.0h - cosA;
|
|
half a5 = a * a * a * a * a;
|
|
return f0 + (1.0h - f0) * a5;
|
|
}
|
|
|
|
half3 GenericReflectionFresnelLerp(half3 f0, half3 f90, half cosA)
|
|
{
|
|
half a = 1.0h - cosA;
|
|
half a5 = a * a * a * a * a;
|
|
return lerp(f0, f90, a5);
|
|
}
|
|
|
|
half3 DecodeGenericReflectionCubemap(half4 data)
|
|
{
|
|
half alpha = _GenericReflectionCubemap_HDR.w * (data.a - 1.0h) + 1.0h;
|
|
|
|
#if defined(UNITY_COLORSPACE_GAMMA)
|
|
return (_GenericReflectionCubemap_HDR.x * alpha) * data.rgb;
|
|
#elif defined(UNITY_USE_NATIVE_HDR)
|
|
return _GenericReflectionCubemap_HDR.x * data.rgb;
|
|
#else
|
|
return (_GenericReflectionCubemap_HDR.x * pow(abs(alpha), _GenericReflectionCubemap_HDR.y)) * data.rgb;
|
|
#endif
|
|
}
|
|
|
|
half3 SampleGenericReflectionCubemap(half3 reflectVector, half perceptualRoughness)
|
|
{
|
|
half mip = perceptualRoughness * (10.2h - 4.2h * perceptualRoughness);
|
|
half4 encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(
|
|
_GenericReflectionCubemap,
|
|
sampler_linear_repeat,
|
|
reflectVector,
|
|
mip));
|
|
|
|
return DecodeGenericReflectionCubemap(encodedIrradiance);
|
|
}
|
|
|
|
half3 SampleGenericReflectionEnvironment(half3 reflectVector, half perceptualRoughness, ToonSurfaceData surfaceData, ToonLightingData lightingData)
|
|
{
|
|
if (_GenericReflectionCubeOverride > 0.5h)
|
|
{
|
|
half3 cubemapColor = SampleGenericReflectionCubemap(reflectVector, perceptualRoughness);
|
|
cubemapColor *= _GenericReflectionCubeColor.rgb;
|
|
cubemapColor *= lerp(1.0h.xxx, saturate(lightingData.mainLight.color), _GenericReflectionCubeEnableLighting);
|
|
return cubemapColor;
|
|
}
|
|
|
|
#if UNITY_VERSION > 202220
|
|
return GlossyEnvironmentReflection(reflectVector, lightingData.positionWS, perceptualRoughness, surfaceData.occlusion, lightingData.normalizedScreenSpaceUV);
|
|
#else
|
|
return GlossyEnvironmentReflection(reflectVector, lightingData.positionWS, perceptualRoughness, surfaceData.occlusion);
|
|
#endif
|
|
}
|
|
|
|
half3 ApplyGenericReflectionSpecular(half3 normalWS, half smoothnessRoughness, half3 specular, ToonLightingData lightingData)
|
|
{
|
|
half3 viewDirWS = normalize(lightingData.viewDirectionWS);
|
|
half3 lightDirWS = normalize(lightingData.mainLight.direction);
|
|
half3 halfDirWS = normalize(viewDirWS + lightDirWS);
|
|
half NdotH = saturate(dot(normalWS, halfDirWS));
|
|
|
|
if (_GenericReflectionSpecularToon > 0.5h)
|
|
{
|
|
half specularArea = pow(NdotH, rcp(max(smoothnessRoughness, 0.002h)));
|
|
return GenericReflectionTooningScale(specularArea, _GenericReflectionSpecularBorder, _GenericReflectionSpecularBlur).xxx;
|
|
}
|
|
|
|
half NdotV = saturate(dot(normalWS, viewDirWS));
|
|
half NdotL = saturate(dot(normalWS, lightDirWS));
|
|
half LdotH = saturate(dot(lightDirWS, halfDirWS));
|
|
half roughness = max(smoothnessRoughness, 0.002h);
|
|
half lambdaV = NdotL * (NdotV * (1.0h - roughness) + roughness);
|
|
half lambdaL = NdotV * (NdotL * (1.0h - roughness) + roughness);
|
|
half roughness2 = roughness * roughness;
|
|
half d = (NdotH * roughness2 - NdotH) * NdotH + 1.0h;
|
|
half ggx = roughness2 / (d * d + 1e-7h);
|
|
|
|
#if defined(SHADER_API_MOBILE) || defined(SHADER_API_SWITCH)
|
|
half smithJointGGX = 0.5h / (lambdaV + lambdaL + 1e-4h);
|
|
#else
|
|
half smithJointGGX = 0.5h / (lambdaV + lambdaL + 1e-5h);
|
|
#endif
|
|
|
|
half specularTerm = smithJointGGX * ggx;
|
|
#if defined(UNITY_COLORSPACE_GAMMA)
|
|
specularTerm = sqrt(max(1e-4h, specularTerm));
|
|
#endif
|
|
|
|
specularTerm *= NdotL;
|
|
return specularTerm * GenericReflectionFresnelTerm(specular, LdotH);
|
|
}
|
|
#endif
|
|
|
|
void ApplyGenericReflection(inout half3 color, ToonSurfaceData surfaceData, Varyings varyings, ToonLightingData lightingData)
|
|
{
|
|
#if _GENERIC_REFLECTION && NiloToonForwardLitPass
|
|
half3 baseNormalWS = normalize(lightingData.normalWS);
|
|
half smoothness = saturate(_GenericReflectionSmoothness * SAMPLE_TEXTURE2D(
|
|
_GenericReflectionSmoothnessMap,
|
|
sampler_linear_repeat,
|
|
CalcUV(GetUV(varyings), _GenericReflectionSmoothnessMap_ST)).r);
|
|
GenericReflectionGSAAForSmoothness(smoothness, baseNormalWS, _GenericReflectionGSAAStrength);
|
|
half perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(smoothness);
|
|
half roughness = perceptualRoughness * perceptualRoughness;
|
|
|
|
half4 colorMask = SAMPLE_TEXTURE2D(
|
|
_GenericReflectionColorMaskMap,
|
|
sampler_linear_repeat,
|
|
CalcUV(GetUV(varyings), _GenericReflectionColorMaskMap_ST));
|
|
half4 reflectionColor = _GenericReflectionColor * colorMask;
|
|
half reflectionAlpha = _GenericReflectionBlend * reflectionColor.a;
|
|
|
|
if (_GenericReflectionApplyTransparency > 0.5h)
|
|
{
|
|
reflectionAlpha *= surfaceData.alpha;
|
|
}
|
|
|
|
half metallicMask = SAMPLE_TEXTURE2D(
|
|
_GenericReflectionMetallicMap,
|
|
sampler_linear_repeat,
|
|
CalcUV(GetUV(varyings), _GenericReflectionMetallicMap_ST)).r;
|
|
half metallic = saturate(_GenericReflectionMetallic * metallicMask);
|
|
|
|
color -= metallic * color;
|
|
half3 specular = lerp(_GenericReflectionReflectance.xxx, surfaceData.albedo, metallic);
|
|
|
|
if (_GenericReflectionApplySpecular > 0.5h)
|
|
{
|
|
half3 specularNormalWS = normalize(lerp(lightingData.normalWS_NoNormalMap, lightingData.normalWS, _GenericReflectionSpecularNormalStrength));
|
|
half3 specularReflection = ApplyGenericReflectionSpecular(specularNormalWS, roughness, specular, lightingData);
|
|
color = BlendGenericReflectionColor(
|
|
color,
|
|
reflectionColor.rgb * saturate(lightingData.mainLight.color),
|
|
specularReflection * reflectionAlpha,
|
|
_GenericReflectionBlendMode);
|
|
}
|
|
|
|
if (_GenericReflectionApplyReflection <= 0.5h)
|
|
{
|
|
return;
|
|
}
|
|
|
|
half3 normalWS = normalize(lerp(lightingData.normalWS_NoNormalMap, lightingData.normalWS, _GenericReflectionNormalStrength));
|
|
half3 reflectionVectorWS = reflect(-lightingData.viewDirectionWS, normalWS);
|
|
half3 envReflectionColor = SampleGenericReflectionEnvironment(reflectionVectorWS, perceptualRoughness, surfaceData, lightingData);
|
|
half oneMinusReflectivity = 0.96h * (1.0h - metallic);
|
|
half grazingTerm = saturate(smoothness + (1.0h - oneMinusReflectivity));
|
|
half surfaceReduction = 1.0h / (roughness * roughness + 1.0h);
|
|
half normalNdotV = saturate(dot(normalWS, lightingData.viewDirectionWS));
|
|
half3 reflectCol = surfaceReduction * envReflectionColor * GenericReflectionFresnelLerp(specular, grazingTerm.xxx, normalNdotV);
|
|
|
|
color = BlendGenericReflectionColor(
|
|
color,
|
|
reflectionColor.rgb,
|
|
reflectCol * reflectionAlpha,
|
|
_GenericReflectionBlendMode);
|
|
#endif
|
|
}
|