vault backup: 2025-02-12 15:27:18
This commit is contained in:
parent
da264458f6
commit
76de98e336
@ -305,7 +305,6 @@ FDeferredLightData InitDeferredLightFromUniforms(uint InLightType)
|
|||||||
```
|
```
|
||||||
|
|
||||||
### DeferredLightPixelMain
|
### DeferredLightPixelMain
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
void DeferredLightPixelMain(
|
void DeferredLightPixelMain(
|
||||||
#if LIGHT_SOURCE_SHAPE > 0
|
#if LIGHT_SOURCE_SHAPE > 0
|
||||||
@ -435,7 +434,7 @@ void DeferredLightPixelMain(
|
|||||||
|
|
||||||
float SurfaceShadow = 1.0f;
|
float SurfaceShadow = 1.0f;
|
||||||
|
|
||||||
float4 LightAttenuation = GetLightAttenuationFromShadow(InputParams, SceneDepth);
|
float4 LightAttenuation = GetLightAttenuationFromShadow(InputParams, SceneDepth);//根绝是否开启VSM 分别从VirtualShadowMap 或者 LightAttenuationTexture(上一阶段渲染的ShadowProjction) 获取灯光衰减值。
|
||||||
float4 Radiance = GetDynamicLighting(DerivedParams.TranslatedWorldPosition, DerivedParams.CameraVector, ScreenSpaceData.GBuffer, ScreenSpaceData.AmbientOcclusion, ScreenSpaceData.GBuffer.ShadingModelID, LightData, LightAttenuation, Dither, uint2(InputParams.PixelPos), SurfaceShadow);
|
float4 Radiance = GetDynamicLighting(DerivedParams.TranslatedWorldPosition, DerivedParams.CameraVector, ScreenSpaceData.GBuffer, ScreenSpaceData.AmbientOcclusion, ScreenSpaceData.GBuffer.ShadingModelID, LightData, LightAttenuation, Dither, uint2(InputParams.PixelPos), SurfaceShadow);
|
||||||
|
|
||||||
OutColor += Radiance;
|
OutColor += Radiance;
|
||||||
@ -454,4 +453,194 @@ void DeferredLightPixelMain(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
### GetDynamicLighting() => GetDynamicLightingSplit()
|
||||||
|
```c++
|
||||||
|
FDeferredLightingSplit GetDynamicLightingSplit(
|
||||||
|
float3 TranslatedWorldPosition, float3 CameraVector, FGBufferData GBuffer, float AmbientOcclusion, uint ShadingModelID,
|
||||||
|
FDeferredLightData LightData, float4 LightAttenuation, float Dither, uint2 SVPos,
|
||||||
|
inout float SurfaceShadow)
|
||||||
|
{
|
||||||
|
FLightAccumulator LightAccumulator = AccumulateDynamicLighting(TranslatedWorldPosition, CameraVector, GBuffer, AmbientOcclusion, ShadingModelID, LightData, LightAttenuation, Dither, SVPos, SurfaceShadow);
|
||||||
|
return LightAccumulator_GetResultSplit(LightAccumulator);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
LightAccumulator_GetResultSplit():针对Subsurface,`RetDiffuse.a = In.ScatterableLightLuma;` 或者 `RetDiffuse.a = Luminance(In.ScatterableLight);`
|
||||||
|
```c++
|
||||||
|
FDeferredLightingSplit LightAccumulator_GetResultSplit(FLightAccumulator In)
|
||||||
|
{
|
||||||
|
float4 RetDiffuse;
|
||||||
|
float4 RetSpecular;
|
||||||
|
|
||||||
|
if (VISUALIZE_LIGHT_CULLING == 1)
|
||||||
|
{
|
||||||
|
// a soft gradient from dark red to bright white, can be changed to be different
|
||||||
|
RetDiffuse = 0.1f * float4(1.0f, 0.25f, 0.075f, 0) * In.EstimatedCost;
|
||||||
|
RetSpecular = 0.1f * float4(1.0f, 0.25f, 0.075f, 0) * In.EstimatedCost;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RetDiffuse = float4(In.TotalLightDiffuse, 0);
|
||||||
|
RetSpecular = float4(In.TotalLightSpecular, 0);
|
||||||
|
|
||||||
|
//针对Subsurface会额外对RetDiffuse的Alpha设置数值 ScatterableLight的亮度数值
|
||||||
|
if (SUBSURFACE_CHANNEL_MODE == 1 )
|
||||||
|
{
|
||||||
|
if (View.bCheckerboardSubsurfaceProfileRendering == 0)
|
||||||
|
{
|
||||||
|
// RGB accumulated RGB HDR color, A: specular luminance for screenspace subsurface scattering
|
||||||
|
RetDiffuse.a = In.ScatterableLightLuma;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (SUBSURFACE_CHANNEL_MODE == 2)
|
||||||
|
{
|
||||||
|
// RGB accumulated RGB HDR color, A: view independent (diffuse) luminance for screenspace subsurface scattering
|
||||||
|
// 3 add, 1 mul, 2 mad, can be optimized to use 2 less temporary during accumulation and remove the 3 add
|
||||||
|
RetDiffuse.a = Luminance(In.ScatterableLight);
|
||||||
|
// todo, need second MRT for SUBSURFACE_CHANNEL_MODE==2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FDeferredLightingSplit Ret;
|
||||||
|
Ret.DiffuseLighting = RetDiffuse;
|
||||||
|
Ret.SpecularLighting = RetSpecular;
|
||||||
|
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#### AccumulateDynamicLighting
|
||||||
|
```c++
|
||||||
|
FLightAccumulator AccumulateDynamicLighting(
|
||||||
|
float3 TranslatedWorldPosition, half3 CameraVector, FGBufferData GBuffer, half AmbientOcclusion, uint ShadingModelID,
|
||||||
|
FDeferredLightData LightData, half4 LightAttenuation, float Dither, uint2 SVPos,
|
||||||
|
inout float SurfaceShadow)
|
||||||
|
{
|
||||||
|
FLightAccumulator LightAccumulator = (FLightAccumulator)0;
|
||||||
|
|
||||||
|
half3 V = -CameraVector;
|
||||||
|
half3 N = GBuffer.WorldNormal;
|
||||||
|
//针对开启CLEAR_COAT_BOTTOM_NORMAL的清漆ShadingModel进行Normal处理
|
||||||
|
BRANCH if( GBuffer.ShadingModelID == SHADINGMODELID_CLEAR_COAT && CLEAR_COAT_BOTTOM_NORMAL)
|
||||||
|
{
|
||||||
|
const float2 oct1 = ((float2(GBuffer.CustomData.a, GBuffer.CustomData.z) * 4) - (512.0/255.0)) + UnitVectorToOctahedron(GBuffer.WorldNormal);
|
||||||
|
N = OctahedronToUnitVector(oct1);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 L = LightData.Direction; // Already normalized
|
||||||
|
float3 ToLight = L;
|
||||||
|
float3 MaskedLightColor = LightData.Color;//灯光颜色
|
||||||
|
float LightMask = 1;
|
||||||
|
// 获取辐射光源的衰减值,衰减方法根据LightData.bInverseSquared,会分别使用新版衰减方法InverseSquared 或者 旧方法。如果是SpotLight与RectLight就乘以SpotLight、RectLight对应的形状衰减数值。
|
||||||
|
if (LightData.bRadialLight)
|
||||||
|
{
|
||||||
|
LightMask = GetLocalLightAttenuation( TranslatedWorldPosition, LightData, ToLight, L );
|
||||||
|
MaskedLightColor *= LightMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
LightAccumulator.EstimatedCost += 0.3f; // running the PixelShader at all has a cost
|
||||||
|
|
||||||
|
BRANCH
|
||||||
|
if( LightMask > 0 )//如果不是完全死黑就计算阴影部分逻辑
|
||||||
|
{
|
||||||
|
FShadowTerms Shadow;
|
||||||
|
Shadow.SurfaceShadow = AmbientOcclusion;//GBuffer中的AO
|
||||||
|
Shadow.TransmissionShadow = 1;
|
||||||
|
Shadow.TransmissionThickness = 1;
|
||||||
|
Shadow.HairTransmittance.OpaqueVisibility = 1;
|
||||||
|
const float ContactShadowOpacity = GBuffer.CustomData.a;//TODO:修正ToonStandard对应的逻辑
|
||||||
|
//
|
||||||
|
GetShadowTerms(GBuffer.Depth, GBuffer.PrecomputedShadowFactors, GBuffer.ShadingModelID, ContactShadowOpacity,
|
||||||
|
LightData, TranslatedWorldPosition, L, LightAttenuation, Dither, Shadow);
|
||||||
|
SurfaceShadow = Shadow.SurfaceShadow;
|
||||||
|
|
||||||
|
LightAccumulator.EstimatedCost += 0.3f; // add the cost of getting the shadow terms
|
||||||
|
|
||||||
|
#if SHADING_PATH_MOBILE
|
||||||
|
const bool bNeedsSeparateSubsurfaceLightAccumulation = UseSubsurfaceProfile(GBuffer.ShadingModelID);
|
||||||
|
|
||||||
|
FDirectLighting Lighting = (FDirectLighting)0;
|
||||||
|
|
||||||
|
half NoL = max(0, dot(GBuffer.WorldNormal, L));
|
||||||
|
#if TRANSLUCENCY_NON_DIRECTIONAL
|
||||||
|
NoL = 1.0f;
|
||||||
|
#endif
|
||||||
|
Lighting = EvaluateBxDF(GBuffer, N, V, L, NoL, Shadow);
|
||||||
|
|
||||||
|
Lighting.Specular *= LightData.SpecularScale;
|
||||||
|
|
||||||
|
LightAccumulator_AddSplit( LightAccumulator, Lighting.Diffuse, Lighting.Specular, Lighting.Diffuse, MaskedLightColor * Shadow.SurfaceShadow, bNeedsSeparateSubsurfaceLightAccumulation );
|
||||||
|
LightAccumulator_AddSplit( LightAccumulator, Lighting.Transmission, 0.0f, Lighting.Transmission, MaskedLightColor * Shadow.TransmissionShadow, bNeedsSeparateSubsurfaceLightAccumulation );
|
||||||
|
#else // SHADING_PATH_MOBILE
|
||||||
|
BRANCH
|
||||||
|
if( Shadow.SurfaceShadow + Shadow.TransmissionShadow > 0 )
|
||||||
|
{
|
||||||
|
const bool bNeedsSeparateSubsurfaceLightAccumulation = UseSubsurfaceProfile(GBuffer.ShadingModelID);
|
||||||
|
|
||||||
|
#if NON_DIRECTIONAL_DIRECT_LIGHTING
|
||||||
|
float Lighting;
|
||||||
|
|
||||||
|
if( LightData.bRectLight )
|
||||||
|
{
|
||||||
|
FRect Rect = GetRect( ToLight, LightData );
|
||||||
|
|
||||||
|
Lighting = IntegrateLight( Rect );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FCapsuleLight Capsule = GetCapsule( ToLight, LightData );
|
||||||
|
|
||||||
|
Lighting = IntegrateLight( Capsule, LightData.bInverseSquared );
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 LightingDiffuse = Diffuse_Lambert( GBuffer.DiffuseColor ) * Lighting;
|
||||||
|
LightAccumulator_AddSplit(LightAccumulator, LightingDiffuse, 0.0f, 0, MaskedLightColor * Shadow.SurfaceShadow, bNeedsSeparateSubsurfaceLightAccumulation);
|
||||||
|
#else
|
||||||
|
FDirectLighting Lighting;
|
||||||
|
|
||||||
|
if (LightData.bRectLight)
|
||||||
|
{
|
||||||
|
FRect Rect = GetRect( ToLight, LightData );
|
||||||
|
const FRectTexture SourceTexture = ConvertToRectTexture(LightData);
|
||||||
|
|
||||||
|
#if REFERENCE_QUALITY
|
||||||
|
Lighting = IntegrateBxDF( GBuffer, N, V, Rect, Shadow, SourceTexture, SVPos );
|
||||||
|
#else
|
||||||
|
Lighting = IntegrateBxDF( GBuffer, N, V, Rect, Shadow, SourceTexture);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FCapsuleLight Capsule = GetCapsule( ToLight, LightData );
|
||||||
|
|
||||||
|
#if REFERENCE_QUALITY
|
||||||
|
Lighting = IntegrateBxDF( GBuffer, N, V, Capsule, Shadow, SVPos );
|
||||||
|
#else
|
||||||
|
Lighting = IntegrateBxDF( GBuffer, N, V, Capsule, Shadow, LightData.bInverseSquared );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Lighting.Specular *= LightData.SpecularScale;
|
||||||
|
|
||||||
|
LightAccumulator_AddSplit( LightAccumulator, Lighting.Diffuse, Lighting.Specular, Lighting.Diffuse, MaskedLightColor * Shadow.SurfaceShadow, bNeedsSeparateSubsurfaceLightAccumulation );
|
||||||
|
LightAccumulator_AddSplit( LightAccumulator, Lighting.Transmission, 0.0f, Lighting.Transmission, MaskedLightColor * Shadow.TransmissionShadow, bNeedsSeparateSubsurfaceLightAccumulation );
|
||||||
|
|
||||||
|
LightAccumulator.EstimatedCost += 0.4f; // add the cost of the lighting computations (should sum up to 1 form one light)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // SHADING_PATH_MOBILE
|
||||||
|
}
|
||||||
|
return LightAccumulator;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
光源新衰减公式,相关计算位于`GetLocalLightAttenuation()`:
|
||||||
|
$$Falloff = \frac{saturate(1-(distance/lightRadius)^4)^2}{distance^2 + 1}$$
|
||||||
|
|
||||||
|
光源旧衰减公式,相关函数位于DynamicLightingCommon.ush中的`RadialAttenuation()`
|
||||||
|
$$Falloff = (1 - saturate(length(WorldLightVector)))^ {FalloffExponent}$$
|
||||||
|
##### GetShadowTerms()
|
||||||
|
```c++
|
||||||
|
|
||||||
```
|
```
|
Loading…
x
Reference in New Issue
Block a user