119 lines
6.1 KiB
HLSL
119 lines
6.1 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
|
|
|
|
half3 BlendGenericMatCapColor(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);
|
|
}
|
|
|
|
float3 GetGenericMatCapCameraUpWS()
|
|
{
|
|
return float3(UNITY_MATRIX_I_V[0][1], UNITY_MATRIX_I_V[1][1], UNITY_MATRIX_I_V[2][1]);
|
|
}
|
|
|
|
float3 GetGenericMatCapCameraForwardWS()
|
|
{
|
|
return normalize(-float3(UNITY_MATRIX_I_V[0][2], UNITY_MATRIX_I_V[1][2], UNITY_MATRIX_I_V[2][2]));
|
|
}
|
|
|
|
float2 CalcGenericMatCapUV(float2 uv1, float3 normalWS, ToonLightingData lightingData, float4 mapST, float4 blendUV1, half zRotCancel, half perspective, half vrParallaxStrength)
|
|
{
|
|
// VR stereo fix: head direction = HMD-center based (stable across eyes),
|
|
// viewDirection = per-eye (parallax-correct). The vrParallaxStrength slider
|
|
// lerps between "stable (0)" and "per-eye parallax (1)". Without this fix,
|
|
// both vectors were equal and the slider had no effect.
|
|
float3 headDirectionWS = GetMatCapHeadDirectionWS(lightingData.positionWS, lightingData.viewDirectionWS);
|
|
float3 viewDirectionWS = lightingData.viewDirectionWS;
|
|
float3 normalVD = normalize(lerp(headDirectionWS, viewDirectionWS, vrParallaxStrength));
|
|
|
|
if (unity_OrthoParams.w > 0.5 || perspective < 0.5)
|
|
{
|
|
normalVD = GetGenericMatCapCameraForwardWS();
|
|
}
|
|
|
|
float3 bitangentVD = zRotCancel > 0.5 ? float3(0, 1, 0) : GetGenericMatCapCameraUpWS();
|
|
bitangentVD = normalize(bitangentVD - normalVD * dot(bitangentVD, normalVD));
|
|
float3 tangentVD = cross(normalVD, bitangentVD);
|
|
|
|
float2 uvMat = float2(dot(tangentVD, normalWS), dot(bitangentVD, normalWS));
|
|
uvMat = lerp(uvMat, saturate(uv1) * 2 - 1, blendUV1.xy);
|
|
uvMat = uvMat * mapST.xy + mapST.zw;
|
|
|
|
return uvMat * 0.5 + 0.5;
|
|
}
|
|
|
|
// lilToon-faithful matcap is applied as a post-light decoration on the lit color,
|
|
// not as a pre-light albedo modifier. Inner guard makes the body empty unless the
|
|
// shader keyword is on AND we are in the ForwardLit pass (matcap should not affect
|
|
// outline / shadow / depth / stencil passes).
|
|
void ApplyGenericMatCap1(inout half3 color, ToonSurfaceData surfaceData, Varyings varyings, ToonLightingData lightingData)
|
|
{
|
|
#if _GENERIC_MATCAP1 && NiloToonForwardLitPass && !_NILOTOON_FUR
|
|
half3 normalWS = normalize(lerp(lightingData.normalWS_NoNormalMap, lightingData.normalWS, _GenericMatCap1NormalStrength));
|
|
|
|
#if _GENERIC_MATCAP1_CUSTOM_NORMAL
|
|
float2 bumpUv = CalcUV(GetUV(varyings), _GenericMatCap1BumpMap_ST);
|
|
half3 customNormalTS = UnpackNormalScale(tex2D(_GenericMatCap1BumpMap, bumpUv), _GenericMatCap1BumpScale);
|
|
normalWS = NormalizeNormalPerPixel(TransformTangentToWorld(customNormalTS, lightingData.TBN_WS));
|
|
#endif
|
|
|
|
float2 matCapUv = CalcGenericMatCapUV(GetUV(varyings, 1), normalWS, lightingData, _GenericMatCap1Map_ST, _GenericMatCap1BlendUV1, _GenericMatCap1ZRotCancel, _GenericMatCap1Perspective, _GenericMatCap1VRParallaxStrength);
|
|
half4 matCapColor = _GenericMatCap1Color * tex2Dlod(_GenericMatCap1Map, float4(matCapUv, 0, _GenericMatCap1Lod));
|
|
matCapColor.rgb = lerp(matCapColor.rgb, matCapColor.rgb * saturate(lightingData.mainLight.color), _GenericMatCap1EnableLighting);
|
|
matCapColor.a = lerp(matCapColor.a, matCapColor.a * lightingData.averageShadowAttenuation, _GenericMatCap1ShadowMask);
|
|
|
|
if (_GenericMatCap1ApplyTransparency > 0.5)
|
|
{
|
|
matCapColor.a *= surfaceData.alpha;
|
|
}
|
|
|
|
matCapColor.a = lightingData.facing < (_GenericMatCap1BackfaceMask - 1.0) ? 0.0 : matCapColor.a;
|
|
|
|
float2 maskUv = CalcUV(GetUV(varyings), _GenericMatCap1Mask_ST);
|
|
half3 matCapMask = tex2D(_GenericMatCap1Mask, maskUv).rgb;
|
|
matCapColor.rgb = lerp(matCapColor.rgb, matCapColor.rgb * surfaceData.albedo, _GenericMatCap1MainStrength);
|
|
color = BlendGenericMatCapColor(color, matCapColor.rgb, _GenericMatCap1Blend * matCapColor.a * matCapMask, _GenericMatCap1BlendMode);
|
|
#endif
|
|
}
|
|
|
|
void ApplyGenericMatCap2(inout half3 color, ToonSurfaceData surfaceData, Varyings varyings, ToonLightingData lightingData)
|
|
{
|
|
#if _GENERIC_MATCAP2 && NiloToonForwardLitPass && !_NILOTOON_FUR
|
|
half3 normalWS = normalize(lerp(lightingData.normalWS_NoNormalMap, lightingData.normalWS, _GenericMatCap2NormalStrength));
|
|
|
|
#if _GENERIC_MATCAP2_CUSTOM_NORMAL
|
|
float2 bumpUv = CalcUV(GetUV(varyings), _GenericMatCap2BumpMap_ST);
|
|
half3 customNormalTS = UnpackNormalScale(tex2D(_GenericMatCap2BumpMap, bumpUv), _GenericMatCap2BumpScale);
|
|
normalWS = NormalizeNormalPerPixel(TransformTangentToWorld(customNormalTS, lightingData.TBN_WS));
|
|
#endif
|
|
|
|
float2 matCapUv = CalcGenericMatCapUV(GetUV(varyings, 1), normalWS, lightingData, _GenericMatCap2Map_ST, _GenericMatCap2BlendUV1, _GenericMatCap2ZRotCancel, _GenericMatCap2Perspective, _GenericMatCap2VRParallaxStrength);
|
|
half4 matCapColor = _GenericMatCap2Color * tex2Dlod(_GenericMatCap2Map, float4(matCapUv, 0, _GenericMatCap2Lod));
|
|
matCapColor.rgb = lerp(matCapColor.rgb, matCapColor.rgb * saturate(lightingData.mainLight.color), _GenericMatCap2EnableLighting);
|
|
matCapColor.a = lerp(matCapColor.a, matCapColor.a * lightingData.averageShadowAttenuation, _GenericMatCap2ShadowMask);
|
|
|
|
if (_GenericMatCap2ApplyTransparency > 0.5)
|
|
{
|
|
matCapColor.a *= surfaceData.alpha;
|
|
}
|
|
|
|
matCapColor.a = lightingData.facing < (_GenericMatCap2BackfaceMask - 1.0) ? 0.0 : matCapColor.a;
|
|
|
|
float2 maskUv = CalcUV(GetUV(varyings), _GenericMatCap2Mask_ST);
|
|
half3 matCapMask = tex2D(_GenericMatCap2Mask, maskUv).rgb;
|
|
matCapColor.rgb = lerp(matCapColor.rgb, matCapColor.rgb * surfaceData.albedo, _GenericMatCap2MainStrength);
|
|
color = BlendGenericMatCapColor(color, matCapColor.rgb, _GenericMatCap2Blend * matCapColor.a * matCapMask, _GenericMatCap2BlendMode);
|
|
#endif
|
|
}
|