vault backup: 2024-01-25 20:10:54

This commit is contained in:
BlueRose 2024-01-25 20:10:54 +08:00
parent a3e718a76a
commit 598d61b281

View File

@ -275,7 +275,7 @@ FMooaToonData DecodeMooaToonDataFromBuffer(uint4 ToonBufferA, float4 CustomData)
- MooaToonDataC(**GBufferD CustomData**) = MainLightShadowColor(8 8 8) + MainLightShadowValueOffset(8)
# LightModel
# ShaderMoodel
```c++
/* ================================== Mooa Toon Deferred Lighting Model ======================================================================================================
* IndirectColor                (DiffuseIndirectComposite.usf)    = IndirectDiffuse + IndirectSpecular
@ -309,3 +309,113 @@ else
OutAddColor = LightAccumulator_GetResult(LightAccumulator);
}
```
```c++
FDirectLighting ToonBxDF(FGBufferData GBuffer, half3 N, half3 V, half3 L, float Falloff, float NoL, FAreaLight AreaLight, FShadowTerms Shadow)
{
FMooaToonContext Context = GBuffer.MooaToonContext;
FMooaToonData MooaToonData = GBuffer.MooaToonContext.MooaToonData;
FDirectLighting Lighting = (FDirectLighting)0;
Context.LightColor *= PI_INV; // default(EV100=0) light intensity == PI
float3 LightColorAndAttenuation = AreaLight.FalloffColor * Context.LightColor * Falloff;
/* Tips:
* SvPosition == PixelPos (0 ~ View.BufferSizeAndInvSize.xy) * SceneTextureUV == BufferUV == ScreenUV (0 ~ 1), used to GetScreenSpaceData() / GetGBufferData() * * ScreenPosition = ClipPosition.xy / ClipPosition.w
* ViewportUV = ScreenPosition * float2(0.5, -0.5) + 0.5 * ViewportUV is the visible part of Buffer's UV (0 ~ 1) */ const float SpecularIntensity = Pow2(GBuffer.Specular * 2);
const float3 H = normalize(V + L);
const float NoH = saturate(dot(N, H));
const float halfNoL = dot(N, L) * 0.5f + 0.5f;
const float2 BufferUV = SvPositionToBufferUV(float4(Context.PixelPos, 0, 0));
const float3 L_ClipSpace = mul(L, (float3x3)View.TranslatedWorldToClip).xyz;
const float2 L_ViewportSpace = normalize(L_ClipSpace.xy * float2(0.5, -0.5));
const float3 N_ClipSpace = mul(N, (float3x3)View.TranslatedWorldToClip).xyz;
const float2 N_ViewportSpace = normalize(N_ClipSpace.xy * float2(0.5, -0.5));
const float WorldUnitLengthInBufferSizePixels = ComputeWorldUnitLengthInBufferSizePixels(GBuffer.Depth);
// Diffuse
BRANCH if (Context.IsMainLight)
{ // Screen Space Depth Test Hair Shadow
float HairShadowValueOffset = 0;
BRANCH if(MooaToonData.RayTracingShadowFlag == MOOA_RAY_TRACING_SHADOW_FLAG_FACE_SCREEN_SPACE_HAIR_SHADOW &&
MooaToonData.HairShadowWidth > 0 && MooaToonData.HairShadowIntensity > 0)
{ float2 UVOffset = L_ViewportSpace * WorldUnitLengthInBufferSizePixels * Pow2(MooaToonData.HairShadowWidth) * View.MooaHairShadowMaxScreenSpaceDistance;
FGBufferData HairGbuffer = GetGBufferData(BufferUV + UVOffset);
float DepthFade = 1 - saturate(max(0, HairGbuffer.Depth - GBuffer.Depth - View.MooaHairShadowDepthTestThreshold) / max(1e-5, View.MooaHairShadowDepthFadeDistance));
if (HairGbuffer.ShadingModelID == SHADINGMODELID_TOON &&
HairGbuffer.MooaToonContext.MooaToonData.RayTracingShadowFlag == MOOA_RAY_TRACING_SHADOW_FLAG_HAIR)
{ HairShadowValueOffset = -1 * MooaToonData.HairShadowIntensity * DepthFade;
} }
Shadow.SurfaceShadow = saturate(Shadow.SurfaceShadow + HairShadowValueOffset + MooaToonData.MainLightShadowValueOffset * 2.0f - 1.0f);
LightColorAndAttenuation *= Shadow.SurfaceShadow;
Lighting.Diffuse = lerp(MooaToonData.MainLightShadowColor * lerp(1, Context.LightColor, MooaToonData.MainLightShadowApplyLightColor) * View.MooaIsGlobalIlluminationEnabled,
GBuffer.DiffuseColor * Context.LightColor, Shadow.SurfaceShadow);
} else
{
float OtherLightShadowValue = ToonStep(halfNoL, MooaToonData.OtherLightDiffuseFeather, MooaToonData.OtherLightDiffuseThreshold);
// Non-Directional light's SurfaceShadow contains distance attenuation, not just shadowmap
Shadow.SurfaceShadow *= OtherLightShadowValue;
LightColorAndAttenuation *= Shadow.SurfaceShadow;
Lighting.Diffuse = GBuffer.DiffuseColor * LightColorAndAttenuation;
}
// Anisotropy Context
#if SUPPORTS_ANISOTROPIC_MATERIALS
bool bHasAnisotropy = HasAnisotropy(GBuffer.SelectiveOutputMask);
#else
bool bHasAnisotropy = false;
#endif
BxDFContext AnisotropyContext = (BxDFContext)0;
{ half3 X = GBuffer.WorldTangent;
half3 Y = normalize(cross(N, X));
Init(AnisotropyContext, N, X, Y, V, L);
AnisotropyContext.NoV = saturate(abs( AnisotropyContext.NoV ) + 1e-5);
if (!bHasAnisotropy) GBuffer.Anisotropy = 0;
}
// Specular
BRANCH if (MooaToonData.IsPBRSpecular)
{ Lighting.Specular = LightColorAndAttenuation * NoL *
max(0, SpecularGGX(GBuffer.Roughness, GBuffer.Anisotropy, GBuffer.SpecularColor, AnisotropyContext, NoL, AreaLight));
} else
{
// Anisotropy
float2 XY = normalize(float2(1.0f + GBuffer.Anisotropy, 1.0f - GBuffer.Anisotropy));
float AnisotropyGradient = length(float2(XY.y * AnisotropyContext.XoH, XY.x * AnisotropyContext.YoH));
// Toon Specular: https://www.desmos.com/calculator/qecziyizl1
float SpecularGradient = 1.0f - AnisotropyGradient;
float SpecularThreshold = 1.0f - Pow2(MooaToonData.SpecularThreshold);
float SpecularFeather = Pow2(MooaToonData.SpecularFeather) * SpecularThreshold * 0.5f;
Lighting.Specular = saturate(ToonStep(SpecularGradient, SpecularFeather, SpecularThreshold + SpecularFeather, 1.0f, false, false))
* MooaToonData.SpecularColor * SpecularIntensity * LightColorAndAttenuation;
}
// Screen Space Depth Test Rim Light
// Recompute Normals to override DCC Normals on Face/Hair const float3 WorldNormalFromDepth = normalize(ReconstructNormalFromDepthBuffer_Copy(Context.PixelPos));
const float3 DepthToN_ClipSpace = mul(WorldNormalFromDepth, (float3x3)View.TranslatedWorldToClip).xyz;
const float2 DepthToN_ViewportSpace = DepthToN_ClipSpace.xy * float2(0.5, -0.5);
BRANCH if (MooaToonData.RimLightIntensity > 0 && MooaToonData.RimLightWidth > 0)
{ float NoL_ClipSpaceAngle01 = (dot(normalize(DepthToN_ClipSpace.xy), normalize(L_ClipSpace.xy)) * 0.5 + 0.5);
float WidthScaleByAngle = saturate(lerp(NoL_ClipSpaceAngle01, 1, MooaToonData.RimLightAngle));
const float MaxRimLightWidth = 0.0003 * View.MooaRimLightMaxWidth;
const float MaxDepthTestDistance = 100 * View.MooaRimLightMaxDepthTestDistance;
const float MaxDepthFadeDistance = 100 * View.MooaRimLightMaxDepthFadeDistance;
// TODO: AA
float SubPixelFade = 1;
float2 UVOffset = L_ViewportSpace * WorldUnitLengthInBufferSizePixels * MaxRimLightWidth * WidthScaleByAngle * Pow2(MooaToonData.RimLightWidth);
float2 TargetBufferUV = BufferUV + UVOffset;
#if MATERIALBLENDING_TRANSLUCENT || MATERIALBLENDING_ADDITIVE || MATERIALBLENDING_MODULATE
// TranslucentBasePass.SceneDepth include Translucent First Layer Depth
// see UseFrontLayerReflection() float SingleLayerDeviceZ = Texture2DSampleLevel( TranslucentBasePass.SceneDepth, GlobalPointClampedSampler, TargetBufferUV, 0).r;
float NewDepth = ConvertFromDeviceZ(SingleLayerDeviceZ);
#else
float NewDepth = GetGBufferData(TargetBufferUV).Depth;
#endif
float DepthFade = saturate(max(0, NewDepth - GBuffer.Depth - MaxDepthTestDistance * Pow2(MooaToonData.RimLightDepthThreshold))
/ max(1e-5, MaxDepthFadeDistance * Pow2(MooaToonData.RimLightDepthThreshold)));
Lighting.Specular = max(Lighting.Specular, DepthFade * MooaToonData.RimLightIntensity * LightColorAndAttenuation);
}
return Lighting;
}
```