vault backup: 2024-01-25 20:10:54
This commit is contained in:
parent
a3e718a76a
commit
598d61b281
@ -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;
|
||||
}
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user