diff --git a/.obsidian/plugins/various-complements/histories.json b/.obsidian/plugins/various-complements/histories.json index 50e5da0..a54f457 100644 --- a/.obsidian/plugins/various-complements/histories.json +++ b/.obsidian/plugins/various-complements/histories.json @@ -1 +1 @@ -{"SequoiaCamShotEvalTemplate":{"SequoiaCamShotEvalTemplate":{"currentFile":{"count":1,"lastUpdated":1732609264076}}},"c++内存泄漏分析工具":{"c++内存泄漏分析工具":{"internalLink":{"count":1,"lastUpdated":1733137754779}}},"Lights":{"Lights":{"currentFile":{"count":1,"lastUpdated":1733637911876}}},"FShadowProjectionNoTransformVS(ShadowProjectionNoTransformVS)、FShadowVolumeBoundProjectionVS(ShadowVolumeBoundProjectionVS)":{"FShadowProjectionNoTransformVS(ShadowProjectionNoTransformVS)、FShadowVolumeBoundProjectionVS(ShadowVolumeBoundProjectionVS)":{"currentFile":{"count":1,"lastUpdated":1734345863513}}},"DecodeLightAttenuation":{"DecodeLightAttenuation":{"currentFile":{"count":1,"lastUpdated":1734406452310}}},"clamped":{"clamped":{"currentFile":{"count":1,"lastUpdated":1734590559877}}},"R失效判定:":{"R失效判定:":{"currentFile":{"count":1,"lastUpdated":1734935678402}}}} \ No newline at end of file +{"R失效判定:":{"R失效判定:":{"currentFile":{"count":1,"lastUpdated":1734935678402}}},"c++内存泄漏分析工具":{"c++内存泄漏分析工具":{"internalLink":{"count":1,"lastUpdated":1737361366503}}}} \ No newline at end of file diff --git a/03-UnrealEngine/卡通渲染相关资料/渲染功能/阴影控制/ToonShadow.md b/03-UnrealEngine/卡通渲染相关资料/渲染功能/阴影控制/ToonShadow.md index 715fe80..e56b30b 100644 --- a/03-UnrealEngine/卡通渲染相关资料/渲染功能/阴影控制/ToonShadow.md +++ b/03-UnrealEngine/卡通渲染相关资料/渲染功能/阴影控制/ToonShadow.md @@ -91,30 +91,89 @@ PS.很有可能在FProjectedShadowInfo::RenderProjection()阶段进行判断以 ```c++ const FMaterialRenderProxy* MaterialRenderProxy = MeshBatch.MaterialRenderProxy; bool bEnableToonMeshDrawOutline = MaterialRenderProxy->GetToonOutlineDataAssetRT()->Settings.bEnableToonMeshDrawOutline; - ``` FProjectedShadowInfo->Scene FPrimitiveSceneProxy ## 深度偏移 -### 方法一 +### ~~方法一~~ 1. FProjectedShadowInfo添加变量。 FSceneRenderer::RenderShadowDepthMaps() => RenderShadowDepthMapAtlases() => ProjectedShadowInfo->RenderDepth() 已放弃,FProjectedShadowInfo无法判断MeshSection。 -### 方法二 +### 方法二(最终实现方法) 在材质中使用ShadowPassSwitch再对ViewSpace的Z轴方向(使用DirectionalLightVector比较可以只对方向光进行偏移)进行WPO偏移实现。 其优点就是可以用贴图来控制偏移过渡。 ## DirectionOffsetToViewShadow -1. 在FProjectedShadowInfo添加变量。 -FSceneRenderer::CreateDynamicShadows() => SetupInteractionShadows(),在CreatePerObjectProjectedShadow()添加相关逻辑。 +### 最终实现方法 +1. 在**FProjectionShadowInfo**中添加**bDirectionOffsetToViewShadow**标记以及对应的判断函数IsDirectionOffsetToViewShadow()来判断是否是DirectionOffsetToViewShadow。 + 1. 在**FSceneRenderer::CreatePerObjectProjectedShadow()** 中再次调用SetupPerObjectProjection()逻辑创建**DirectionOffsetToViewShadow**时将FProjectedShadowInfo的***bDirectionOffsetToViewShadow设置成true***。 +2. 在PrimitiveSceneProxy.h 中添加DirectionOffsetToViewShadowAlpha变量作为偏移Alpha,同事添加函数UseDirectionOffsetToViewShadow()来判断是否开启这个功能。 + 1. 在**FSceneRenderer::CreatePerObjectProjectedShadow()** 中取得PrimitiveSceneProxy中的DirectionOffsetToViewShadowAlpha,最后计算向量来设置***ShadowInitializer.WorldToLight***。大致为[[#DirectionOffsetToViewShadow Direction Code]] +3. 在ToonDataAsset中添加RecivedViewOffsetShadow作为是否接收DirectionOffsetToViewShadow的依据。 + 1. 将数据渲染到ToonDataAsset Texture中。 + 2. 最终在ShadowProjectionPixelShader.usf获取并且计算。代码如下: -CreatePerObjectProjectedShadow() => ProjectedPreShadowInfo->SetupPerObjectProjection -- GetBestShadowTransform() +```c++ + //BlueRose Modify +#if SHADING_PATH_DEFERRED && !FORWARD_SHADING && !SUBPIXEL_SHADOW && !STRATA_ENABLED /*&& !USE_TRANSMISSION*/ + FGBufferData GBufferData_Toon = GetGBufferData(ScreenUV); + const uint ToonDataAssetID = GetToonDataAssetIDFromGBuffer(GBufferData_Toon); + float RecivedViewOffsetShadow = GetRecivedViewOffsetShadow(ToonDataAssetID); + + if (IsDirectionOffsetToViewShadow > 0)//ViewShadow ProjectionShadowInfo + { + /*if (RecivedViewOffsetShadow > 0)//ViewOffsetShadow + { + PerObjectDistanceFadeFraction *= 1.0; + }*/ + if (RecivedViewOffsetShadow == 0) + { + PerObjectDistanceFadeFraction *= 0.0; + } + }else//Normal ProjectionShadowInfo + { + if (RecivedViewOffsetShadow > 0) + { + PerObjectDistanceFadeFraction *= 0.0; + } + } +#endif + //BlueRose Modify End + float FadedShadow = lerp(1.0f, Shadow, ShadowFadeFraction * PerObjectDistanceFadeFraction); -### 思路一 -ENGINE_API virtual void PreEditChange(FProperty* PropertyAboutToChange) override; -ENGINE_API virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; -ENGINE_API virtual bool CanEditChange(const FProperty* InProperty) const override; -ENGINE_API virtual bool Modify(bool bAlwaysMarkDirty = true) override; \ No newline at end of file +#if FORWARD_SHADING || SHADING_PATH_MOBILE + float LightInfluenceMask = GetLightInfluenceMask(TranslateWorldPosition); + // Constrain shadowing from this light to pixels inside the light's influence, since other non-overlapping lights are packed into the same channel + FadedShadow = lerp(1, FadedShadow, LightInfluenceMask); + // Write into all channels, the write mask will constrain to the correct one + OutColor = EncodeLightAttenuation(FadedShadow); +#else + float FadedSSSShadow = lerp(1.0f, SSSTransmission, ShadowFadeFraction * PerObjectDistanceFadeFraction); + + // the channel assignment is documented in ShadowRendering.cpp (look for Light Attenuation channel assignment) + OutColor = EncodeLightAttenuation(half4(FadedShadow, FadedSSSShadow, FadedShadow, FadedSSSShadow)); +#endif +``` +#### DirectionOffsetToViewShadow Direction Code +```c++ +... +bool bToonDirectionOffsetToViewShadow = ToonDirectionOffsetToViewShadowCVar->GetValueOnRenderThread(); +float LightViewBlendFactor = PrimitiveSceneInfo->Proxy->DirectionOffsetToViewShadowAlpha; +if (bToonDirectionOffsetToViewShadow && LightSceneInfo->Proxy->GetLightType() == LightType_Directional && LightViewBlendFactor > 0.0f) +{ + //计算半程向量,针对每个View都会生成一个FProjectedShadowInfo,之后在RenderShadowProjection()中判断? + for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) + { + const FViewInfo& View = Views[ViewIndex]; + const FMatrix& ViewMatrix = View.ShadowViewMatrices.GetViewMatrix(); + FVector LightDirection = LightSceneInfo->Proxy->GetDirection(); + const FVector CameraDirection = ViewMatrix.GetColumn(2).GetSafeNormal(); + FVector HalfViewLightDir = (LightDirection * ( 1 - LightViewBlendFactor) + CameraDirection * LightViewBlendFactor).GetSafeNormal(); + FMatrix FinalCombineMatrix = FInverseRotationMatrix(HalfViewLightDir.Rotation()); + ShadowInitializer.WorldToLight = FinalCombineMatrix; + ... + } +} +``` \ No newline at end of file