From bb9633fecd6ddc9f2361020bf9f639c510ab13fd Mon Sep 17 00:00:00 2001 From: BlueRose <378100977@qq.com> Date: Tue, 11 Feb 2025 18:35:56 +0800 Subject: [PATCH] vault backup: 2025-02-11 18:35:56 --- .../various-complements/histories.json | 2 +- .../RenderingPipeline/Lighting/Lighting.md | 237 ++++++++++++++++++ 2 files changed, 238 insertions(+), 1 deletion(-) diff --git a/.obsidian/plugins/various-complements/histories.json b/.obsidian/plugins/various-complements/histories.json index 4478701..a7262cd 100644 --- a/.obsidian/plugins/various-complements/histories.json +++ b/.obsidian/plugins/various-complements/histories.json @@ -1 +1 @@ -{"c++内存泄漏分析工具":{"c++内存泄漏分析工具":{"internalLink":{"count":1,"lastUpdated":1737361366503}}},"tonemapping":{"tonemapping":{"currentFile":{"count":1,"lastUpdated":1737367609064}}},"body01":{"body01":{"currentFile":{"count":1,"lastUpdated":1738243350947}}},"Games":{"Games":{"currentFile":{"count":1,"lastUpdated":1738586917474}}},"Camera":{"Camera":{"currentFile":{"count":1,"lastUpdated":1739168843622}}}} \ No newline at end of file +{"c++内存泄漏分析工具":{"c++内存泄漏分析工具":{"internalLink":{"count":1,"lastUpdated":1737361366503}}},"tonemapping":{"tonemapping":{"currentFile":{"count":1,"lastUpdated":1737367609064}}},"body01":{"body01":{"currentFile":{"count":1,"lastUpdated":1738243350947}}},"Games":{"Games":{"currentFile":{"count":1,"lastUpdated":1738586917474}}},"Camera":{"Camera":{"currentFile":{"count":1,"lastUpdated":1739168843622}}},"DeferredLightVertexShaders":{"DeferredLightVertexShaders":{"currentFile":{"count":1,"lastUpdated":1739267675471}}}} \ No newline at end of file diff --git a/03-UnrealEngine/Rendering/RenderingPipeline/Lighting/Lighting.md b/03-UnrealEngine/Rendering/RenderingPipeline/Lighting/Lighting.md index d02bd0b..2775c48 100644 --- a/03-UnrealEngine/Rendering/RenderingPipeline/Lighting/Lighting.md +++ b/03-UnrealEngine/Rendering/RenderingPipeline/Lighting/Lighting.md @@ -213,3 +213,240 @@ FComputeLightGridOutput FDeferredShadingSceneRenderer::GatherLightsAndComputeLig # RenderLights() -> RenderLight() ## InternalRenderLight() + +## DeferredLightVertexShaders +```c++ +// 输入参数. +struct FInputParams +{ + float2 PixelPos; + float4 ScreenPosition; + float2 ScreenUV; + float3 ScreenVector; +}; + +// 派生参数. +struct FDerivedParams +{ + float3 CameraVector; + float3 WorldPosition; +}; + +// 获取派生参数. +FDerivedParams GetDerivedParams(in FInputParams Input, in float SceneDepth) +{ + FDerivedParams Out; +#if LIGHT_SOURCE_SHAPE > 0 + // With a perspective projection, the clip space position is NDC * Clip.w + // With an orthographic projection, clip space is the same as NDC + float2 ClipPosition = Input.ScreenPosition.xy / Input.ScreenPosition.w * (View.ViewToClip[3][3] < 1.0f ? SceneDepth : 1.0f); + Out.WorldPosition = mul(float4(ClipPosition, SceneDepth, 1), View.ScreenToWorld).xyz; + Out.CameraVector = normalize(Out.WorldPosition - View.WorldCameraOrigin); +#else + Out.WorldPosition = Input.ScreenVector * SceneDepth + View.WorldCameraOrigin; + Out.CameraVector = normalize(Input.ScreenVector); +#endif + return Out; +} + +Texture2D LightingChannelsTexture; + +uint GetLightingChannelMask(float2 UV) +{ + uint2 IntegerUV = UV * View.BufferSizeAndInvSize.xy; + return LightingChannelsTexture.Load(uint3(IntegerUV, 0)).x; +} + +float GetExposure() +{ + return View.PreExposure; +} +``` + +向往文章中的SetupLightDataForStandardDeferred()变为InitDeferredLightFromUniforms()。位于LightDataUniform.ush。 +```c++ +FDeferredLightData InitDeferredLightFromUniforms(uint InLightType) +{ + const bool bIsRadial = InLightType != LIGHT_TYPE_DIRECTIONAL; + + FDeferredLightData Out; + Out.TranslatedWorldPosition = GetDeferredLightTranslatedWorldPosition(); + Out.InvRadius = DeferredLightUniforms.InvRadius; + Out.Color = DeferredLightUniforms.Color; + Out.FalloffExponent = DeferredLightUniforms.FalloffExponent; + Out.Direction = DeferredLightUniforms.Direction; + Out.Tangent = DeferredLightUniforms.Tangent; + Out.SpotAngles = DeferredLightUniforms.SpotAngles; + Out.SourceRadius = DeferredLightUniforms.SourceRadius; + Out.SourceLength = bIsRadial ? DeferredLightUniforms.SourceLength : 0; + Out.SoftSourceRadius = DeferredLightUniforms.SoftSourceRadius; + Out.SpecularScale = DeferredLightUniforms.SpecularScale; + Out.ContactShadowLength = abs(DeferredLightUniforms.ContactShadowLength); + Out.ContactShadowLengthInWS = DeferredLightUniforms.ContactShadowLength < 0.0f; + Out.ContactShadowCastingIntensity = DeferredLightUniforms.ContactShadowCastingIntensity; + Out.ContactShadowNonCastingIntensity = DeferredLightUniforms.ContactShadowNonCastingIntensity; + Out.DistanceFadeMAD = DeferredLightUniforms.DistanceFadeMAD; + Out.ShadowMapChannelMask = DeferredLightUniforms.ShadowMapChannelMask; + Out.ShadowedBits = DeferredLightUniforms.ShadowedBits; + Out.bInverseSquared = bIsRadial && DeferredLightUniforms.FalloffExponent == 0; // Directional lights don't use 'inverse squared attenuation' + Out.bRadialLight = bIsRadial; + Out.bSpotLight = InLightType == LIGHT_TYPE_SPOT; + Out.bRectLight = InLightType == LIGHT_TYPE_RECT; + + Out.RectLightData.BarnCosAngle = DeferredLightUniforms.RectLightBarnCosAngle; + Out.RectLightData.BarnLength = DeferredLightUniforms.RectLightBarnLength; + Out.RectLightData.AtlasData.AtlasMaxLevel = DeferredLightUniforms.RectLightAtlasMaxLevel; + Out.RectLightData.AtlasData.AtlasUVOffset = DeferredLightUniforms.RectLightAtlasUVOffset; + Out.RectLightData.AtlasData.AtlasUVScale = DeferredLightUniforms.RectLightAtlasUVScale; + + Out.HairTransmittance = InitHairTransmittanceData(); + return Out; +} +``` + +### DeferredLightPixelMain + +```c++ +void DeferredLightPixelMain( +#if LIGHT_SOURCE_SHAPE > 0 + float4 InScreenPosition : TEXCOORD0, +#else + float2 ScreenUV : TEXCOORD0, + float3 ScreenVector : TEXCOORD1, +#endif + float4 SVPos : SV_POSITION, + out float4 OutColor : SV_Target0 +#if STRATA_OPAQUE_ROUGH_REFRACTION_ENABLED + , out float3 OutOpaqueRoughRefractionSceneColor : SV_Target1 + , out float3 OutSubSurfaceSceneColor : SV_Target2 +#endif + ) +{ + const float2 PixelPos = SVPos.xy; + OutColor = 0; +#if STRATA_OPAQUE_ROUGH_REFRACTION_ENABLED + OutOpaqueRoughRefractionSceneColor = 0; + OutSubSurfaceSceneColor = 0; +#endif + + // Convert input data (directional/local light) + // 计算屏幕UV + FInputParams InputParams = (FInputParams)0; + InputParams.PixelPos = SVPos.xy; +#if LIGHT_SOURCE_SHAPE > 0 + InputParams.ScreenPosition = InScreenPosition; + InputParams.ScreenUV = InScreenPosition.xy / InScreenPosition.w * View.ScreenPositionScaleBias.xy + View.ScreenPositionScaleBias.wz; + InputParams.ScreenVector = 0; +#else + InputParams.ScreenPosition = 0; + InputParams.ScreenUV = ScreenUV; + InputParams.ScreenVector = ScreenVector; +#endif + +#if STRATA_ENABLED + + FStrataAddressing StrataAddressing = GetStrataPixelDataByteOffset(PixelPos, uint2(View.BufferSizeAndInvSize.xy), Strata.MaxBytesPerPixel); + FStrataPixelHeader StrataPixelHeader = UnpackStrataHeaderIn(Strata.MaterialTextureArray, StrataAddressing, Strata.TopLayerTexture); + + BRANCH + if (StrataPixelHeader.BSDFCount > 0 // This test is also enough to exclude sky pixels +#if USE_LIGHTING_CHANNELS + //灯光通道逻辑 + && (GetLightingChannelMask(InputParams.ScreenUV) & DeferredLightUniforms.LightingChannelMask) +#endif + ) + { + //通过SceneDepth获取的CameraVector以及当前像素的世界坐标 + const float SceneDepth = CalcSceneDepth(InputParams.ScreenUV); + const FDerivedParams DerivedParams = GetDerivedParams(InputParams, SceneDepth); + + FDeferredLightData LightData = InitDeferredLightFromUniforms(CURRENT_LIGHT_TYPE); + UpdateLightDataColor(LightData, InputParams, DerivedParams); + + float3 V =-DerivedParams.CameraVector; + float3 L = LightData.Direction; // Already normalized + float3 ToLight = L; + float LightMask = 1; + if (LightData.bRadialLight) + { + LightMask = GetLocalLightAttenuation(DerivedParams.TranslatedWorldPosition, LightData, ToLight, L); + } + + if (LightMask > 0) + { + FShadowTerms ShadowTerms = { StrataGetAO(StrataPixelHeader), 1.0, 1.0, InitHairTransmittanceData() }; + float4 LightAttenuation = GetLightAttenuationFromShadow(InputParams, SceneDepth); + + float Dither = InterleavedGradientNoise(InputParams.PixelPos, View.StateFrameIndexMod8); + const uint FakeShadingModelID = 0; + const float FakeContactShadowOpacity = 1.0f; + float4 PrecomputedShadowFactors = StrataReadPrecomputedShadowFactors(StrataPixelHeader, PixelPos, SceneTexturesStruct.GBufferETexture); + GetShadowTerms(SceneDepth, PrecomputedShadowFactors, FakeShadingModelID, FakeContactShadowOpacity, + LightData, DerivedParams.TranslatedWorldPosition, L, LightAttenuation, Dither, ShadowTerms); + + FStrataDeferredLighting StrataLighting = StrataDeferredLighting( + LightData, + V, + L, + ToLight, + LightMask, + ShadowTerms, + Strata.MaterialTextureArray, + StrataAddressing, + StrataPixelHeader); + + OutColor += StrataLighting.SceneColor; +#if STRATA_OPAQUE_ROUGH_REFRACTION_ENABLED + OutOpaqueRoughRefractionSceneColor += StrataLighting.OpaqueRoughRefractionSceneColor; + OutSubSurfaceSceneColor += StrataLighting.SubSurfaceSceneColor; +#endif + } + } + +#else // STRATA_ENABLED + + FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(InputParams.ScreenUV); + // Only light pixels marked as using deferred shading + BRANCH if (ScreenSpaceData.GBuffer.ShadingModelID > 0 +#if USE_LIGHTING_CHANNELS + && (GetLightingChannelMask(InputParams.ScreenUV) & DeferredLightUniforms.LightingChannelMask) +#endif + ) + { + const float SceneDepth = CalcSceneDepth(InputParams.ScreenUV); + const FDerivedParams DerivedParams = GetDerivedParams(InputParams, SceneDepth); + + FDeferredLightData LightData = InitDeferredLightFromUniforms(CURRENT_LIGHT_TYPE); + UpdateLightDataColor(LightData, InputParams, DerivedParams); + + #if USE_HAIR_COMPLEX_TRANSMITTANCE + if (ScreenSpaceData.GBuffer.ShadingModelID == SHADINGMODELID_HAIR && ShouldUseHairComplexTransmittance(ScreenSpaceData.GBuffer)) + { + LightData.HairTransmittance = EvaluateDualScattering(ScreenSpaceData.GBuffer, DerivedParams.CameraVector, -DeferredLightUniforms.Direction); + } + #endif + + float Dither = InterleavedGradientNoise(InputParams.PixelPos, View.StateFrameIndexMod8); + + float SurfaceShadow = 1.0f; + + float4 LightAttenuation = GetLightAttenuationFromShadow(InputParams, SceneDepth); + float4 Radiance = GetDynamicLighting(DerivedParams.TranslatedWorldPosition, DerivedParams.CameraVector, ScreenSpaceData.GBuffer, ScreenSpaceData.AmbientOcclusion, ScreenSpaceData.GBuffer.ShadingModelID, LightData, LightAttenuation, Dither, uint2(InputParams.PixelPos), SurfaceShadow); + + OutColor += Radiance; + } + +#endif // STRATA_ENABLED + + // RGB:SceneColor Specular and Diffuse + // A:Non Specular SceneColor Luminance + // So we need PreExposure for both color and alpha + OutColor.rgba *= GetExposure(); +#if STRATA_OPAQUE_ROUGH_REFRACTION_ENABLED + // Idem + OutOpaqueRoughRefractionSceneColor *= GetExposure(); + OutSubSurfaceSceneColor *= GetExposure(); +#endif +} +#endif +``` \ No newline at end of file