Added GT Toon map;

Changed shadow bias from fixed to slope based;
This commit is contained in:
2025-08-25 10:47:26 +09:00
parent 973f617590
commit e35650f052
8 changed files with 65 additions and 20 deletions

View File

@@ -74,12 +74,14 @@ struct UtsBSDFData
real roughnessB;
};
bool IsNonZeroBSDF(float3 L, float3 normalWS)
bool IsNonZeroBSDF(float3 L, float3 N)
{
// Should we sample shadow in zero bsdf area when using ramp map?
#if _MATERIAL_TYPE_FACE || _USE_SHADING_RAMP_MAP_ON
return true;
//#elif _USE_SHADING_RAMP_MAP_ON
#else
float NdotL = dot(normalWS, L);
float NdotL = dot(N, L);
return NdotL > 0.0;
#endif

View File

@@ -58,7 +58,7 @@ DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData
return lighting;
}
DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 normalWS, float3 V)
DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 N, float3 V)
{
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
@@ -74,15 +74,16 @@ DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 normalWS,
float3 cameraRoll = acos(clamp(cameraRollCos, -1.0, 1.0));
float cameraDir = cameraRight.y < 0 ? -1.0 : 1.0;
float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(normalWS, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy;
float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(N, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy;
arOffsetU = arOffsetU * 0.5 + 0.5;
float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll).x, 0.5, 1.0);
float2 arOffsetUV = float2(arvnRotate.x, lerp(input.texCoord0.y, arvnRotate.y, _AngelRingOffsetV));
float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity;
float weight = saturate(dot(normalize(V), normalWS));
float weight = saturate(dot(V, N));
lighting.specular = angelRingColor.r * angelRingColor.a * weight;
lighting.specular = angelRingColor * angelRingColor.a * weight;
return lighting;
}

View File

@@ -56,10 +56,10 @@ DirectLighting UtsEvaluateBSDF_Directional(LightLoopContext lightLoopContext, Po
if (lightData.lightDimmer > 0.0)
{
// TODO: Colored shadow will overwrite the first and second shading diffuse color
//float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
// TODO: Support ray traced transparent colored shadow
float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
float4 lightColor = EvaluateLight_Directional(lightLoopContext, posInput, lightData);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _LightIntensityMultiplier);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _LightIntensityMultiplier) * shadowColor;
UtsClampRoughness(preLightData, bsdfData, lightData.minRoughness);
@@ -85,8 +85,8 @@ DirectLighting UtsEvaluateBSDF_Punctual(LightLoopContext lightLoopContext, Posit
if (lightData.lightDimmer > 0.0)
{
// TODO: Colored shadow will overwrite the first and second shading diffuse color
//float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
// TODO: Support ray traced transparent colored shadow
float3 shadowColor = ComputeShadowColor(shadow, lightData.shadowTint, lightData.penumbraTint);
float4 lightColor = EvaluateLight_Punctual(lightLoopContext, posInput, lightData, L, distances);
lightColor.rgb = GetLimitedLightColor(lightColor.rgb * lightColor.a * _LightIntensityMultiplier);
@@ -246,9 +246,9 @@ IndirectLighting UtsEvaluateBSDF_Env(LightLoopContext lightLoopContext, Position
return lighting;
}
void ApplyAmbientOcclusion(AmbientOcclusionFactor aoFactor, inout BuiltinData builtinData, inout AggregateLighting lighting)
void ApplyAmbientOcclusion(AmbientOcclusionFactor aoFactor, UtsBSDFData bsdfData, inout BuiltinData builtinData, inout AggregateLighting lighting)
{
builtinData.bakeDiffuseLighting = APPLY_WEIGHT(builtinData.bakeDiffuseLighting, aoFactor.indirectAmbientOcclusion, _SSAOWeight);
builtinData.bakeDiffuseLighting = APPLY_WEIGHT(builtinData.bakeDiffuseLighting, lerp(bsdfData.diffuseColor * 0.2, 1.0, aoFactor.indirectAmbientOcclusion), _SSAOWeight);
lighting.indirect.specularReflected = APPLY_WEIGHT(lighting.indirect.specularReflected, aoFactor.indirectSpecularOcclusion, _SSAOWeight);
lighting.direct.diffuse = APPLY_WEIGHT(lighting.direct.diffuse, aoFactor.directAmbientOcclusion, _SSAOWeight);
lighting.direct.specular = APPLY_WEIGHT(lighting.direct.specular, aoFactor.directSpecularOcclusion, _SSAOWeight);
@@ -266,7 +266,7 @@ void UtsPostEvaluateBSDF(PositionInputs posInput, PreLightData preLightData, Uts
#if !defined(_INDIRECT_DIFFUSE_MODE_OFF) || !defined(_INDIRECT_SPECULAR_MODE_OFF)
AmbientOcclusionFactor aoFactor;
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, bsdfData.ambientOcclusion, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
ApplyAmbientOcclusion(aoFactor, builtinData, lighting);
ApplyAmbientOcclusion(aoFactor, bsdfData, builtinData, lighting);
#endif
AdjustIndirectLighting(preLightData, bsdfData, builtinData, lighting);
@@ -275,7 +275,6 @@ void UtsPostEvaluateBSDF(PositionInputs posInput, PreLightData preLightData, Uts
lightLoopOutput.specularLighting = lighting.direct.specular + lighting.indirect.specularReflected;
// Rescale the GGX to account for the multiple scattering.
lightLoopOutput.specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation;
ApplyExposureAdjustment(lightLoopOutput.diffuseLighting);
ApplyExposureAdjustment(lightLoopOutput.specularLighting);
}

View File

@@ -72,7 +72,7 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && IsNonZeroBSDF(L, bsdfData))
{
context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext,
posInput.positionSS, posInput.positionWS + L * _ShadowDistanceBias, UtsGetShadowNormal(bsdfData),
posInput.positionSS, posInput.positionWS + L * UtsGetShadowSlopeBias(bsdfData.normalWS, L), UtsGetShadowNormal(bsdfData),
light.shadowIndex, L);
}
}

View File

@@ -53,6 +53,7 @@ float3 ComputeSpecularTerm(UtsBSDFData bsdfData, PreLightData preLightData, floa
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, clampedNdotV, TdotL, BdotL, abs(NdotL), bsdfData.roughnessT, bsdfData.roughnessB, partLambdaV);
#elif _PBR_MODE_HAIR
// TODO: Double layer anisotropic specular.
float3 t = ShiftTangent(bsdfData.bitangentWS, N, bsdfData.anisotropy);
float specularExponent = RoughnessToBlinnPhongSpecularExponent(PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness));
DV = D_KajiyaKay(t, H, specularExponent);
@@ -117,7 +118,7 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
if (Max3(lightColor.r, lightColor.g, lightColor.b) > 0.0)
{
SHADOW_TYPE sharpShadow = smoothstep(0.3, 0.7, shadow);
SHADOW_TYPE sharpShadow = smoothstep(0.0, 1.0, shadow);
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
sharpShadow *= GetHairShadow(posInput, L, bsdfData.normalWS);
#endif

View File

@@ -10,6 +10,15 @@ float3 UtsGetShadowNormal(UtsBSDFData bsdfData)
#endif
}
float UtsGetShadowSlopeBias(float3 N, float3 L)
{
// The slope bias is used to avoid shadow acne.
// It is calculated based on the angle between the normal and the light direction.
// The more perpendicular the light is to the surface, the more bias we apply.
float NdotL = dot(N, L);
return (1.0 - NdotL) * _ShadowDistanceBias;
}
float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
{
float2 right_uv = float2(1 - uv.x, uv.y);
@@ -81,7 +90,7 @@ SHADOW_TYPE UtsEvaluateShadow_Punctual(LightLoopContext lightLoopContext, Positi
#endif
if ((light.shadowIndex >= 0) && (light.shadowDimmer > 0) && IsNonZeroBSDF(L, N))
{
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, posInput.positionSS, posInput.positionWS + L * _ShadowDistanceBias, N, light.shadowIndex, L, distances.x, light.lightType == GPULIGHTTYPE_POINT, light.lightType != GPULIGHTTYPE_PROJECTOR_BOX);
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, posInput.positionSS, posInput.positionWS + L * UtsGetShadowSlopeBias(N, L), N, light.shadowIndex, L, distances.x, light.lightType == GPULIGHTTYPE_POINT, light.lightType != GPULIGHTTYPE_PROJECTOR_BOX);
#ifdef SHADOWS_SHADOWMASK
// Note: Legacy Unity have two shadow mask mode. ShadowMask (ShadowMask contain static objects shadow and ShadowMap contain only dynamic objects shadow, final result is the minimun of both value)