├── Config └── DefaultEngine.ini ├── Content ├── FogMask.uasset ├── NewMap.umap └── NewMap_BuiltData.uasset ├── LICENSE ├── MaskFog.uproject ├── Plugins └── MaskFogPostProcess │ ├── Content │ └── MaskFog │ │ ├── MaskFog.uasset │ │ ├── PP_MaskFog_Inst.uasset │ │ └── PP_SH_MaskFog.uasset │ ├── MaskFogPostProcess.uplugin │ ├── Resources │ └── Icon128.png │ ├── Shaders │ ├── FogMaskPixelShader.usf │ └── GaussianBlurPixelShader.usf │ └── Source │ └── MaskFogPostProcess │ ├── MaskFogPostProcess.Build.cs │ ├── Private │ ├── FogMaskPixelShader.cpp │ ├── MaskFogActor.cpp │ └── MaskFogPostProcess.cpp │ └── Public │ ├── FogMaskPixelShader.h │ ├── MaskFogActor.h │ └── MaskFogPostProcess.h ├── README.md └── Source ├── MaskFog.Target.cs ├── MaskFog ├── MaskFog.Build.cs ├── MaskFog.cpp ├── MaskFog.h ├── MaskFogGameModeBase.cpp └── MaskFogGameModeBase.h └── MaskFogEditor.Target.cs /Config/DefaultEngine.ini: -------------------------------------------------------------------------------- 1 | 2 | 3 | [/Script/EngineSettings.GameMapsSettings] 4 | EditorStartupMap=/Game/NewMap.NewMap 5 | GameDefaultMap=/Game/NewMap.NewMap 6 | 7 | -------------------------------------------------------------------------------- /Content/FogMask.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jinsek/UE4MultipassPostprocess/152c5b325deeeb5701725f7588c299c869f8ec97/Content/FogMask.uasset -------------------------------------------------------------------------------- /Content/NewMap.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jinsek/UE4MultipassPostprocess/152c5b325deeeb5701725f7588c299c869f8ec97/Content/NewMap.umap -------------------------------------------------------------------------------- /Content/NewMap_BuiltData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jinsek/UE4MultipassPostprocess/152c5b325deeeb5701725f7588c299c869f8ec97/Content/NewMap_BuiltData.uasset -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 DevilBro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MaskFog.uproject: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "EngineAssociation": "4.27", 4 | "Category": "", 5 | "Description": "", 6 | "Modules": [ 7 | { 8 | "Name": "MaskFog", 9 | "Type": "Runtime", 10 | "LoadingPhase": "Default" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Content/MaskFog/MaskFog.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jinsek/UE4MultipassPostprocess/152c5b325deeeb5701725f7588c299c869f8ec97/Plugins/MaskFogPostProcess/Content/MaskFog/MaskFog.uasset -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Content/MaskFog/PP_MaskFog_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jinsek/UE4MultipassPostprocess/152c5b325deeeb5701725f7588c299c869f8ec97/Plugins/MaskFogPostProcess/Content/MaskFog/PP_MaskFog_Inst.uasset -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Content/MaskFog/PP_SH_MaskFog.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jinsek/UE4MultipassPostprocess/152c5b325deeeb5701725f7588c299c869f8ec97/Plugins/MaskFogPostProcess/Content/MaskFog/PP_SH_MaskFog.uasset -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/MaskFogPostProcess.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "MaskFogPostProcess", 6 | "Description": "Customized Post Process", 7 | "Category": "Other", 8 | "CreatedBy": "Devil Bro", 9 | "CreatedByURL": "", 10 | "DocsURL": "", 11 | "MarketplaceURL": "", 12 | "SupportURL": "", 13 | "CanContainContent": true, 14 | "IsBetaVersion": false, 15 | "IsExperimentalVersion": false, 16 | "Installed": false, 17 | "Modules": [ 18 | { 19 | "Name": "MaskFogPostProcess", 20 | "Type": "Runtime", 21 | "LoadingPhase" : "PostConfigInit" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jinsek/UE4MultipassPostprocess/152c5b325deeeb5701725f7588c299c869f8ec97/Plugins/MaskFogPostProcess/Resources/Icon128.png -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Shaders/FogMaskPixelShader.usf: -------------------------------------------------------------------------------- 1 | // Copyright 2016-2020 Cadic AB. All Rights Reserved. 2 | // @Author Fredrik Lindh [Temaran] (temaran@gmail.com) {https://github.com/Temaran} 3 | /////////////////////////////////////////////////////////////////////////////////////// 4 | 5 | #include "/Engine/Public/Platform.ush" 6 | 7 | // VERTEX SHADER 8 | //////////////// 9 | 10 | void MainVertexShader(float4 InPosition : ATTRIBUTE0, float2 InUV : ATTRIBUTE1, out float2 OutUV : TEXCOORD0, out float4 OutPosition : SV_POSITION) 11 | { 12 | OutPosition = InPosition; 13 | OutUV = InUV; 14 | } 15 | 16 | // PIXEL SHADER 17 | /////////////// 18 | float2 TextureSize; 19 | float4 InvDeviceZToWorldZTransform; 20 | float2 ScreenUVSize; 21 | Texture2D SrcRT; 22 | SamplerState SrcRTSampler; 23 | Texture2D SceneDepthTexture; 24 | SamplerState SceneDepthSampler; 25 | 26 | float ConvertFromDeviceZ(float DeviceZ) 27 | { 28 | // Supports ortho and perspective, see CreateInvDeviceZToWorldZTransform() 29 | return DeviceZ * InvDeviceZToWorldZTransform[0] + InvDeviceZToWorldZTransform[1] + 1.0f / (DeviceZ * InvDeviceZToWorldZTransform[2] - InvDeviceZToWorldZTransform[3]); 30 | } 31 | 32 | void MainPixelShader(in float2 uv : TEXCOORD0, out float4 OutColor : SV_Target0) 33 | { 34 | float PixelDepth = SrcRT.SampleLevel(SrcRTSampler, uv, 0).r; 35 | float SceneDepth = ConvertFromDeviceZ(SceneDepthTexture.SampleLevel(SceneDepthSampler, uv * ScreenUVSize, 0).r); 36 | if (PixelDepth < SceneDepth) 37 | OutColor = 1; 38 | else 39 | OutColor = 0; 40 | } 41 | -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Shaders/GaussianBlurPixelShader.usf: -------------------------------------------------------------------------------- 1 | // Copyright 2016-2020 Cadic AB. All Rights Reserved. 2 | // @Author Fredrik Lindh [Temaran] (temaran@gmail.com) {https://github.com/Temaran} 3 | /////////////////////////////////////////////////////////////////////////////////////// 4 | 5 | #include "/Engine/Public/Platform.ush" 6 | 7 | // PIXEL SHADER 8 | /////////////// 9 | float2 BlurOffset; 10 | Texture2D SrcRT; 11 | SamplerState SrcRTSampler; 12 | 13 | void MainPixelShader(in float2 uv : TEXCOORD0, out float4 OutColor : SV_Target0) 14 | { 15 | float4 uv01 = uv.xyxy + BlurOffset.xyxy * float4(1, 1, -1, -1); 16 | float4 uv23 = uv.xyxy + BlurOffset.xyxy * float4(1, 1, -1, -1) * 2.0; 17 | float4 uv45 = uv.xyxy + BlurOffset.xyxy * float4(1, 1, -1, -1) * 6.0; 18 | float color = 0; 19 | 20 | color += 0.40 * SrcRT.SampleLevel(SrcRTSampler, uv, 0).r; 21 | color += 0.15 * SrcRT.SampleLevel(SrcRTSampler, uv01.xy, 0).r; 22 | color += 0.15 * SrcRT.SampleLevel(SrcRTSampler, uv01.zw, 0).r; 23 | color += 0.10 * SrcRT.SampleLevel(SrcRTSampler, uv23.xy, 0).r; 24 | color += 0.10 * SrcRT.SampleLevel(SrcRTSampler, uv23.zw, 0).r; 25 | color += 0.05 * SrcRT.SampleLevel(SrcRTSampler, uv45.xy, 0).r; 26 | color += 0.05 * SrcRT.SampleLevel(SrcRTSampler, uv45.zw, 0).r; 27 | OutColor = color; 28 | } 29 | 30 | // Final Combine PIXEL SHADER 31 | /////////////// 32 | Texture2D MaskRT; 33 | SamplerState MaskRTSampler; 34 | Texture2D BlurRT; 35 | SamplerState BlurRTSampler; 36 | float MulFactor; 37 | 38 | void CombinePixelShader(in float2 uv : TEXCOORD0, out float4 OutColor : SV_Target0) 39 | { 40 | float color = MaskRT.SampleLevel(MaskRTSampler, uv, 0).r; 41 | color += BlurRT.SampleLevel(BlurRTSampler, uv, 0).r * MulFactor; 42 | OutColor = saturate(color); 43 | } -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Source/MaskFogPostProcess/MaskFogPostProcess.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class MaskFogPostProcess : ModuleRules 6 | { 7 | public MaskFogPostProcess(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | // ... add public include paths required here ... 14 | } 15 | ); 16 | 17 | 18 | PrivateIncludePaths.AddRange( 19 | new string[] { 20 | // ... add other private include paths required here ... 21 | } 22 | ); 23 | 24 | 25 | PublicDependencyModuleNames.AddRange( 26 | new string[] 27 | { 28 | "Core", 29 | // ... add other public dependencies that you statically link with here ... 30 | } 31 | ); 32 | 33 | 34 | PrivateDependencyModuleNames.AddRange( 35 | new string[] 36 | { 37 | "Core", 38 | "CoreUObject", 39 | "Engine", 40 | "Renderer", 41 | "RenderCore", 42 | "RHI", 43 | "Projects" 44 | } 45 | ); 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Source/MaskFogPostProcess/Private/FogMaskPixelShader.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "FogMaskPixelShader.h" 5 | 6 | #include "ShaderParameterUtils.h" 7 | #include "RHIStaticStates.h" 8 | #include "Shader.h" 9 | #include "GlobalShader.h" 10 | #include "RenderGraphBuilder.h" 11 | #include "RenderGraphUtils.h" 12 | #include "ShaderParameterMacros.h" 13 | #include "ShaderParameterStruct.h" 14 | #include "UniformBuffer.h" 15 | #include "RHICommandList.h" 16 | #include "Containers/DynamicRHIResourceArray.h" 17 | #include "Runtime/RenderCore/Public/PixelShaderUtils.h" 18 | 19 | /************************************************************************/ 20 | /* Simple static vertex buffer. */ 21 | /************************************************************************/ 22 | class FSimpleScreenVertexBuffer : public FVertexBuffer 23 | { 24 | public: 25 | /** Initialize the RHI for this rendering resource */ 26 | void InitRHI() 27 | { 28 | TResourceArray Vertices; 29 | Vertices.SetNumUninitialized(6); 30 | 31 | Vertices[0].Position = FVector4(-1, 1, 0, 1); 32 | Vertices[0].UV = FVector2D(0, 0); 33 | 34 | Vertices[1].Position = FVector4(1, 1, 0, 1); 35 | Vertices[1].UV = FVector2D(1, 0); 36 | 37 | Vertices[2].Position = FVector4(-1, -1, 0, 1); 38 | Vertices[2].UV = FVector2D(0, 1); 39 | 40 | Vertices[3].Position = FVector4(1, -1, 0, 1); 41 | Vertices[3].UV = FVector2D(1, 1); 42 | 43 | // Create vertex buffer. Fill buffer with initial data upon creation 44 | FRHIResourceCreateInfo CreateInfo(&Vertices); 45 | VertexBufferRHI = RHICreateVertexBuffer(Vertices.GetResourceDataSize(), BUF_Static, CreateInfo); 46 | } 47 | }; 48 | TGlobalResource GSimpleScreenVertexBuffer; 49 | 50 | /************************************************************************/ 51 | /* A simple passthrough vertexshader that we will use. */ 52 | /************************************************************************/ 53 | class FSimplePassThroughVS : public FGlobalShader 54 | { 55 | public: 56 | DECLARE_GLOBAL_SHADER(FSimplePassThroughVS); 57 | 58 | public: 59 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 60 | { 61 | return true; 62 | } 63 | 64 | FSimplePassThroughVS() { } 65 | FSimplePassThroughVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer) : FGlobalShader(Initializer) { } 66 | }; 67 | 68 | /**********************************************************************************************/ 69 | /* This class carries our parameter declarations and acts as the bridge between cpp and HLSL. */ 70 | /**********************************************************************************************/ 71 | class FFogMaskPixelShaderPS : public FGlobalShader 72 | { 73 | public: 74 | DECLARE_GLOBAL_SHADER(FFogMaskPixelShaderPS); 75 | SHADER_USE_PARAMETER_STRUCT(FFogMaskPixelShaderPS, FGlobalShader); 76 | 77 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 78 | SHADER_PARAMETER_TEXTURE(Texture2D, SrcRT) 79 | SHADER_PARAMETER_SAMPLER(SamplerState, SrcRTSampler) 80 | SHADER_PARAMETER_TEXTURE(Texture2D, SceneDepthTexture) 81 | SHADER_PARAMETER_SAMPLER(SamplerState, SceneDepthSampler) 82 | SHADER_PARAMETER(FVector2D, TextureSize) // Metal doesn't support GetDimensions(), so we send in this data via our parameters. 83 | SHADER_PARAMETER(FVector4, InvDeviceZToWorldZTransform) 84 | SHADER_PARAMETER(FVector2D, ScreenUVSize) 85 | END_SHADER_PARAMETER_STRUCT() 86 | 87 | public: 88 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 89 | { 90 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 91 | } 92 | }; 93 | 94 | // This will tell the engine to create the shader and where the shader entry point is. 95 | // ShaderType ShaderPath Shader function name Type 96 | IMPLEMENT_GLOBAL_SHADER(FSimplePassThroughVS, "/Shaders/FogMaskPixelShader.usf", "MainVertexShader", SF_Vertex); 97 | IMPLEMENT_GLOBAL_SHADER(FFogMaskPixelShaderPS, "/Shaders/FogMaskPixelShader.usf", "MainPixelShader", SF_Pixel); 98 | 99 | void FogMaskPixelShader::DrawToRenderTarget_RenderThread(FRHICommandListImmediate& RHICmdList, const FShaderFogMaskParameters& DrawParameters) 100 | { 101 | QUICK_SCOPE_CYCLE_COUNTER(STAT_ShaderPlugin_PixelShader); // Used to gather CPU profiling data for the UE4 session frontend 102 | SCOPED_DRAW_EVENT(RHICmdList, ShaderPlugin_Pixel); // Used to profile GPU activity and add metadata to be consumed by for example RenderDoc 103 | 104 | FRHIRenderPassInfo RenderPassInfo(DrawParameters.RTDest->GetRenderTargetResource()->GetRenderTargetTexture(), ERenderTargetActions::Clear_Store); 105 | RHICmdList.BeginRenderPass(RenderPassInfo, TEXT("ShaderPlugin_OutputToRenderTarget")); 106 | 107 | auto ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); 108 | TShaderMapRef VertexShader(ShaderMap); 109 | TShaderMapRef PixelShader(ShaderMap); 110 | 111 | // Set the graphic pipeline state. 112 | FGraphicsPipelineStateInitializer GraphicsPSOInit; 113 | RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit); 114 | GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI(); 115 | GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI(); 116 | GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState::GetRHI(); 117 | GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI; 118 | GraphicsPSOInit.BoundShaderState.VertexShaderRHI = VertexShader.GetVertexShader(); 119 | GraphicsPSOInit.BoundShaderState.PixelShaderRHI = PixelShader.GetPixelShader(); 120 | GraphicsPSOInit.PrimitiveType = PT_TriangleStrip; 121 | SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit); 122 | 123 | // Setup the pixel shader 124 | FFogMaskPixelShaderPS::FParameters PassParameters; 125 | PassParameters.SrcRT = DrawParameters.RTSrc->GetRenderTargetResource()->GetRenderTargetTexture(); 126 | PassParameters.SrcRTSampler = TStaticSamplerState<>::GetRHI(); 127 | PassParameters.SceneDepthTexture = DrawParameters.SceneDepth; 128 | PassParameters.SceneDepthSampler = TStaticSamplerState<>::GetRHI(); 129 | PassParameters.TextureSize = FVector2D(DrawParameters.GetRenderTargetSize().X, DrawParameters.GetRenderTargetSize().Y); 130 | PassParameters.InvDeviceZToWorldZTransform = DrawParameters.InvDeviceZToWorldZTransform; 131 | PassParameters.ScreenUVSize = FVector2D(DrawParameters.ViewSize.X / DrawParameters.SceneDepth->GetSizeXYZ().X, 132 | DrawParameters.ViewSize.Y / DrawParameters.SceneDepth->GetSizeXYZ().Y); 133 | SetShaderParameters(RHICmdList, PixelShader, PixelShader.GetPixelShader(), PassParameters); 134 | 135 | // Draw 136 | RHICmdList.SetStreamSource(0, GSimpleScreenVertexBuffer.VertexBufferRHI, 0); 137 | RHICmdList.DrawPrimitive(0, 2, 1); 138 | 139 | RHICmdList.EndRenderPass(); 140 | } 141 | 142 | 143 | /**********************************************************************************************/ 144 | /* This class carries our parameter declarations and acts as the bridge between cpp and HLSL. */ 145 | /**********************************************************************************************/ 146 | class FGaussianBlurPixelShaderPS : public FGlobalShader 147 | { 148 | public: 149 | DECLARE_GLOBAL_SHADER(FGaussianBlurPixelShaderPS); 150 | SHADER_USE_PARAMETER_STRUCT(FGaussianBlurPixelShaderPS, FGlobalShader); 151 | 152 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 153 | SHADER_PARAMETER_TEXTURE(Texture2D, SrcRT) 154 | SHADER_PARAMETER_SAMPLER(SamplerState, SrcRTSampler) 155 | SHADER_PARAMETER(FVector2D, BlurOffset) 156 | END_SHADER_PARAMETER_STRUCT() 157 | 158 | public: 159 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 160 | { 161 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 162 | } 163 | }; 164 | 165 | // This will tell the engine to create the shader and where the shader entry point is. 166 | // ShaderType ShaderPath Shader function name Type 167 | IMPLEMENT_GLOBAL_SHADER(FGaussianBlurPixelShaderPS, "/Shaders/GaussianBlurPixelShader.usf", "MainPixelShader", SF_Pixel); 168 | 169 | void FogMaskPixelShader::BlurToRenderTarget_RenderThread(FRHICommandListImmediate& RHICmdList, 170 | UTextureRenderTarget2D* RTSrc, UTextureRenderTarget2D* RTDest, const FVector2D& BlurOffset) 171 | { 172 | QUICK_SCOPE_CYCLE_COUNTER(STAT_ShaderPlugin_PixelShader); // Used to gather CPU profiling data for the UE4 session frontend 173 | SCOPED_DRAW_EVENT(RHICmdList, ShaderPlugin_Pixel); // Used to profile GPU activity and add metadata to be consumed by for example RenderDoc 174 | 175 | FRHIRenderPassInfo RenderPassInfo(RTDest->GetRenderTargetResource()->GetRenderTargetTexture(), ERenderTargetActions::Clear_Store); 176 | RHICmdList.BeginRenderPass(RenderPassInfo, TEXT("ShaderPlugin_OutputToRenderTarget")); 177 | 178 | auto ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); 179 | TShaderMapRef VertexShader(ShaderMap); 180 | TShaderMapRef PixelShader(ShaderMap); 181 | 182 | // Set the graphic pipeline state. 183 | FGraphicsPipelineStateInitializer GraphicsPSOInit; 184 | RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit); 185 | GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI(); 186 | GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI(); 187 | GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState::GetRHI(); 188 | GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI; 189 | GraphicsPSOInit.BoundShaderState.VertexShaderRHI = VertexShader.GetVertexShader(); 190 | GraphicsPSOInit.BoundShaderState.PixelShaderRHI = PixelShader.GetPixelShader(); 191 | GraphicsPSOInit.PrimitiveType = PT_TriangleStrip; 192 | SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit); 193 | 194 | // Setup the pixel shader 195 | FGaussianBlurPixelShaderPS::FParameters PassParameters; 196 | PassParameters.SrcRT = RTSrc->GetRenderTargetResource()->GetRenderTargetTexture(); 197 | PassParameters.SrcRTSampler = TStaticSamplerState<>::GetRHI(); 198 | PassParameters.BlurOffset = BlurOffset; 199 | 200 | SetShaderParameters(RHICmdList, PixelShader, PixelShader.GetPixelShader(), PassParameters); 201 | 202 | // Draw 203 | RHICmdList.SetStreamSource(0, GSimpleScreenVertexBuffer.VertexBufferRHI, 0); 204 | RHICmdList.DrawPrimitive(0, 2, 1); 205 | 206 | RHICmdList.EndRenderPass(); 207 | } 208 | 209 | class FFinalCombinePixelShaderPS : public FGlobalShader 210 | { 211 | public: 212 | DECLARE_GLOBAL_SHADER(FFinalCombinePixelShaderPS); 213 | SHADER_USE_PARAMETER_STRUCT(FFinalCombinePixelShaderPS, FGlobalShader); 214 | 215 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 216 | SHADER_PARAMETER_TEXTURE(Texture2D, MaskRT) 217 | SHADER_PARAMETER_SAMPLER(SamplerState, MaskRTSampler) 218 | SHADER_PARAMETER_TEXTURE(Texture2D, BlurRT) 219 | SHADER_PARAMETER_SAMPLER(SamplerState, BlurRTSampler) 220 | SHADER_PARAMETER(float, MulFactor) 221 | END_SHADER_PARAMETER_STRUCT() 222 | 223 | public: 224 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 225 | { 226 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 227 | } 228 | }; 229 | 230 | // This will tell the engine to create the shader and where the shader entry point is. 231 | // ShaderType ShaderPath Shader function name Type 232 | IMPLEMENT_GLOBAL_SHADER(FFinalCombinePixelShaderPS, "/Shaders/GaussianBlurPixelShader.usf", "CombinePixelShader", SF_Pixel); 233 | 234 | void FogMaskPixelShader::CombineToRenderTarget_RenderThread(FRHICommandListImmediate& RHICmdList, 235 | UTextureRenderTarget2D* RTSrc, UTextureRenderTarget2D* RTBlur, UTextureRenderTarget2D* RTDest, const float MulFactor) 236 | { 237 | QUICK_SCOPE_CYCLE_COUNTER(STAT_ShaderPlugin_PixelShader); // Used to gather CPU profiling data for the UE4 session frontend 238 | SCOPED_DRAW_EVENT(RHICmdList, ShaderPlugin_Pixel); // Used to profile GPU activity and add metadata to be consumed by for example RenderDoc 239 | 240 | FRHIRenderPassInfo RenderPassInfo(RTDest->GetRenderTargetResource()->GetRenderTargetTexture(), ERenderTargetActions::Clear_Store); 241 | RHICmdList.BeginRenderPass(RenderPassInfo, TEXT("ShaderPlugin_OutputToRenderTarget")); 242 | 243 | auto ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); 244 | TShaderMapRef VertexShader(ShaderMap); 245 | TShaderMapRef PixelShader(ShaderMap); 246 | 247 | // Set the graphic pipeline state. 248 | FGraphicsPipelineStateInitializer GraphicsPSOInit; 249 | RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit); 250 | GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI(); 251 | GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI(); 252 | GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState::GetRHI(); 253 | GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI; 254 | GraphicsPSOInit.BoundShaderState.VertexShaderRHI = VertexShader.GetVertexShader(); 255 | GraphicsPSOInit.BoundShaderState.PixelShaderRHI = PixelShader.GetPixelShader(); 256 | GraphicsPSOInit.PrimitiveType = PT_TriangleStrip; 257 | SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit); 258 | 259 | // Setup the pixel shader 260 | FFinalCombinePixelShaderPS::FParameters PassParameters; 261 | PassParameters.MaskRT = RTSrc->GetRenderTargetResource()->GetRenderTargetTexture(); 262 | PassParameters.MaskRTSampler = TStaticSamplerState<>::GetRHI(); 263 | PassParameters.BlurRT = RTBlur->GetRenderTargetResource()->GetRenderTargetTexture(); 264 | PassParameters.BlurRTSampler = TStaticSamplerState<>::GetRHI(); 265 | PassParameters.MulFactor = MulFactor; 266 | 267 | SetShaderParameters(RHICmdList, PixelShader, PixelShader.GetPixelShader(), PassParameters); 268 | 269 | // Draw 270 | RHICmdList.SetStreamSource(0, GSimpleScreenVertexBuffer.VertexBufferRHI, 0); 271 | RHICmdList.DrawPrimitive(0, 2, 1); 272 | 273 | RHICmdList.EndRenderPass(); 274 | } -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Source/MaskFogPostProcess/Private/MaskFogActor.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "MaskFogActor.h" 5 | #include "MaskFogPostProcess.h" 6 | #include "Components/SceneCaptureComponent2D.h" 7 | #include "Engine/PostProcessVolume.h" 8 | 9 | // Sets default values 10 | AMaskFogActor::AMaskFogActor() 11 | { 12 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 13 | PrimaryActorTick.bCanEverTick = true; 14 | SceneCapture = CreateDefaultSubobject(TEXT("MaskSceneCaptureComponent2D")); 15 | SceneCapture->SetupAttachment(RootComponent); 16 | 17 | } 18 | 19 | UTextureRenderTarget2D* AMaskFogActor::CreateRT(const TEnumAsByte RenderTargetFormat) 20 | { 21 | UTextureRenderTarget2D* RT = NewObject(this); 22 | RT->ClearColor = FLinearColor(0.0f, 0.0f, 0.0f, 0.0f); 23 | RT->RenderTargetFormat = RenderTargetFormat; 24 | RT->InitAutoFormat(RTInitSize, RTInitSize); 25 | return RT; 26 | } 27 | 28 | void AMaskFogActor::InitRT() 29 | { 30 | RTMaskBG = CreateRT(RTF_R32f); 31 | FinalMask = CreateRT(RTF_R8); 32 | RTBlurTemp01 = CreateRT(RTF_R8); 33 | RTBlurTemp = CreateRT(RTF_R8); 34 | } 35 | 36 | // Called when the game starts or when spawned 37 | void AMaskFogActor::BeginPlay() 38 | { 39 | Super::BeginPlay(); 40 | if (SceneCapture != nullptr && PPMaterialMaskFog != nullptr && GlobalPPV != nullptr) { 41 | InitRT(); 42 | SceneCapture->CaptureSource = ESceneCaptureSource::SCS_SceneDepth; 43 | SceneCapture->TextureTarget = RTMaskBG; 44 | UMaterialInstanceDynamic* MID = UMaterialInstanceDynamic::Create(PPMaterialMaskFog, this); 45 | MID->SetTextureParameterValue("Mask", (UTexture*)FinalMask); 46 | GlobalPPV->Settings.AddBlendable(MID, 1.0f); 47 | FMaskFogPostProcessModule::Get().BeginRendering(); 48 | } 49 | } 50 | 51 | void AMaskFogActor::BeginDestroy() 52 | { 53 | if (SceneCapture) { 54 | SceneCapture->TextureTarget = nullptr; 55 | } 56 | if (RTMaskBG) { 57 | RTMaskBG->ReleaseResource(); 58 | RTMaskBG = nullptr; 59 | } 60 | if (FinalMask) { 61 | FinalMask->ReleaseResource(); 62 | FinalMask = nullptr; 63 | } 64 | if (RTBlurTemp) { 65 | RTBlurTemp->ReleaseResource(); 66 | RTBlurTemp = nullptr; 67 | } 68 | if (RTBlurTemp01) { 69 | RTBlurTemp01->ReleaseResource(); 70 | RTBlurTemp01 = nullptr; 71 | } 72 | FMaskFogPostProcessModule::Get().EndRendering(); 73 | Super::BeginDestroy(); 74 | } 75 | 76 | // Called every frame 77 | void AMaskFogActor::Tick(float DeltaTime) 78 | { 79 | Super::Tick(DeltaTime); 80 | FShaderFogMaskParameters DrawParameters(SceneCapture->TextureTarget, RTBlurTemp, RTBlurTemp01, FinalMask); 81 | DrawParameters.BlurRadius = BlurRadius; 82 | DrawParameters.RimFactor = RimFactor; 83 | DrawParameters.Iterations = Iterations; 84 | // If doing this for realsies, you should avoid doing this every frame unless you have to of course. 85 | // We set it every frame here since we're updating the end color and simulation state. Boop. 86 | FMaskFogPostProcessModule::Get().UpdateParameters(DrawParameters); 87 | if (RTMaskBG && DrawParameters.ViewSize.X > 0 && DrawParameters.ViewSize.Y > 0) 88 | { 89 | uint32 ResX = FMath::FloorToInt(DrawParameters.ViewSize.X * ResolutionScale); 90 | uint32 ResY = FMath::FloorToInt(DrawParameters.ViewSize.Y * ResolutionScale); 91 | if (ResX <= 0 || ResX > 4096 || ResY <= 0 || ResY > 4096) 92 | return; 93 | if (ResX != RTMaskBG->SizeX && ResY != RTMaskBG->SizeY && BlurResolutionScale > 0) { 94 | UE_LOG(LogTemp, Log, TEXT("Resize RT : %d, %d"), ResX, ResY); 95 | RTMaskBG->ResizeTarget(ResX, ResY); 96 | FinalMask->ResizeTarget(ResX, ResY); 97 | RTBlurTemp->ResizeTarget(ResX * BlurResolutionScale, ResY * BlurResolutionScale); 98 | RTBlurTemp01->ResizeTarget(ResX * BlurResolutionScale, ResY * BlurResolutionScale); 99 | } 100 | } 101 | } 102 | 103 | -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Source/MaskFogPostProcess/Private/MaskFogPostProcess.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "MaskFogPostProcess.h" 4 | #include "FogMaskPixelShader.h" 5 | 6 | #include "Misc/Paths.h" 7 | #include "Misc/FileHelper.h" 8 | #include "RHI.h" 9 | #include "GlobalShader.h" 10 | #include "RHICommandList.h" 11 | #include "RenderGraphBuilder.h" 12 | #include "RenderTargetPool.h" 13 | #include "Runtime/Core/Public/Modules/ModuleManager.h" 14 | #include "Interfaces/IPluginManager.h" 15 | #include "Runtime/Renderer/Private/PostProcess/SceneRenderTargets.h" 16 | #include "Runtime/Renderer/Private/SceneRendering.h" 17 | 18 | #define LOCTEXT_NAMESPACE "FMaskFogPostProcessModule" 19 | 20 | DECLARE_GPU_STAT_NAMED(ShaderPlugin_Render, TEXT("ShaderPlugin: Root Render")); 21 | DECLARE_GPU_STAT_NAMED(ShaderPlugin_Pixel, TEXT("ShaderPlugin: Render Pixel Shader")); 22 | 23 | void FMaskFogPostProcessModule::StartupModule() 24 | { 25 | OnPostResolvedSceneColorHandle.Reset(); 26 | bCachedParametersValid = false; 27 | 28 | // Maps virtual shader source directory to the plugin's actual shaders directory. 29 | FString PluginShaderDir = FPaths::Combine(IPluginManager::Get().FindPlugin(TEXT("MaskFogPostProcess"))->GetBaseDir(), TEXT("Shaders")); 30 | AddShaderSourceDirectoryMapping(TEXT("/Shaders"), PluginShaderDir); 31 | } 32 | 33 | void FMaskFogPostProcessModule::ShutdownModule() 34 | { 35 | EndRendering(); 36 | } 37 | 38 | void FMaskFogPostProcessModule::BeginRendering() 39 | { 40 | if (OnPostResolvedSceneColorHandle.IsValid()) 41 | { 42 | return; 43 | } 44 | bCachedParametersValid = false; 45 | const FName RendererModuleName("Renderer"); 46 | IRendererModule* RendererModule = FModuleManager::GetModulePtr(RendererModuleName); 47 | if (RendererModule) 48 | { 49 | OnPostResolvedSceneColorHandle = RendererModule->GetResolvedSceneColorCallbacks().AddRaw(this, 50 | &FMaskFogPostProcessModule::PostResolveSceneColor_RenderThread); 51 | OnPostOpaqueRenderDelegateHandle = RendererModule->RegisterPostOpaqueRenderDelegate( 52 | FPostOpaqueRenderDelegate::CreateRaw(this, &FMaskFogPostProcessModule::PostOpaqueRender_RenderThread)); 53 | } 54 | } 55 | 56 | void FMaskFogPostProcessModule::EndRendering() 57 | { 58 | if (!OnPostResolvedSceneColorHandle.IsValid()) 59 | { 60 | return; 61 | } 62 | const FName RendererModuleName("Renderer"); 63 | IRendererModule* RendererModule = FModuleManager::GetModulePtr(RendererModuleName); 64 | if (RendererModule) 65 | { 66 | RendererModule->GetResolvedSceneColorCallbacks().Remove(OnPostResolvedSceneColorHandle); 67 | RendererModule->RemovePostOpaqueRenderDelegate(OnPostOpaqueRenderDelegateHandle); 68 | } 69 | OnPostResolvedSceneColorHandle.Reset(); 70 | } 71 | 72 | void FMaskFogPostProcessModule::UpdateParameters(FShaderFogMaskParameters& DrawParameters) 73 | { 74 | FVector2D ViewSize; 75 | RenderEveryFrameLock.Lock(); 76 | ViewSize = CachedFogMaskParameters.ViewSize; 77 | CachedFogMaskParameters = DrawParameters; 78 | bCachedParametersValid = true; 79 | RenderEveryFrameLock.Unlock(); 80 | if (bIsGameView && !bIsSceneCapture) 81 | DrawParameters.ViewSize = ViewSize; 82 | } 83 | 84 | void FMaskFogPostProcessModule::PostResolveSceneColor_RenderThread(FRHICommandListImmediate& RHICmdList, class FSceneRenderTargets& SceneContext) 85 | { 86 | if (!bCachedParametersValid || !bIsGameView) 87 | { 88 | return; 89 | } 90 | 91 | // Depending on your data, you might not have to lock here, just added this code to show how you can do it if you have to. 92 | RenderEveryFrameLock.Lock(); 93 | FShaderFogMaskParameters Copy = CachedFogMaskParameters; 94 | const FTexture2DRHIRef& RHISceneDepth = 95 | (const FTexture2DRHIRef&)SceneContext.SceneDepthZ->GetRenderTargetItem().ShaderResourceTexture; 96 | Copy.SceneDepth = RHISceneDepth; 97 | RenderEveryFrameLock.Unlock(); 98 | 99 | Draw_RenderThread(Copy); 100 | } 101 | 102 | void FMaskFogPostProcessModule::PostOpaqueRender_RenderThread(FPostOpaqueRenderParameters& Parameters) 103 | { 104 | if (!bCachedParametersValid) 105 | { 106 | return; 107 | } 108 | 109 | // Depending on your data, you might not have to lock here, just added this code to show how you can do it if you have to. 110 | RenderEveryFrameLock.Lock(); 111 | const FViewInfo* View =(FViewInfo*)Parameters.Uid; 112 | bIsGameView = View->bIsGameView; 113 | bIsSceneCapture = View->bIsSceneCapture; 114 | if (bIsGameView && !bIsSceneCapture) 115 | { 116 | CachedFogMaskParameters.InvDeviceZToWorldZTransform = View->InvDeviceZToWorldZTransform; 117 | CachedFogMaskParameters.ViewSize = Parameters.ViewportRect.Size(); 118 | } 119 | RenderEveryFrameLock.Unlock(); 120 | } 121 | 122 | void FMaskFogPostProcessModule::Draw_RenderThread(const FShaderFogMaskParameters& DrawParameters) 123 | { 124 | check(IsInRenderingThread()); 125 | 126 | if (!bIsGameView || bIsSceneCapture || !DrawParameters.RTDest || !DrawParameters.RTSrc || !DrawParameters.RTBlurTemp || 127 | DrawParameters.ViewSize.X <= 0 || DrawParameters.ViewSize.Y <= 0) 128 | { 129 | return; 130 | } 131 | 132 | FRHICommandListImmediate& RHICmdList = GRHICommandList.GetImmediateCommandList(); 133 | 134 | QUICK_SCOPE_CYCLE_COUNTER(STAT_ShaderPlugin_Render); // Used to gather CPU profiling data for the UE4 session frontend 135 | SCOPED_DRAW_EVENT(RHICmdList, ShaderPlugin_Render); // Used to profile GPU activity and add metadata to be consumed by for example RenderDoc 136 | 137 | FogMaskPixelShader::DrawToRenderTarget_RenderThread(RHICmdList, DrawParameters); 138 | float BlurOffsetX = FMath::Max(0.0001f, DrawParameters.BlurRadius) / DrawParameters.RTBlurTemp->SizeX; 139 | float BlurOffsetY = FMath::Max(0.0001f, DrawParameters.BlurRadius) / DrawParameters.RTBlurTemp->SizeY; 140 | // 141 | FogMaskPixelShader::BlurToRenderTarget_RenderThread(RHICmdList, DrawParameters.RTDest, 142 | DrawParameters.RTBlurTemp01, FVector2D(BlurOffsetX, 0)); 143 | FogMaskPixelShader::BlurToRenderTarget_RenderThread(RHICmdList, DrawParameters.RTBlurTemp01, 144 | DrawParameters.RTBlurTemp, FVector2D(0, BlurOffsetY)); 145 | int Iteration = FMath::Max(0, DrawParameters.Iterations); 146 | for (int i = 1; i < Iteration; ++i) { 147 | FogMaskPixelShader::BlurToRenderTarget_RenderThread(RHICmdList, DrawParameters.RTBlurTemp, 148 | DrawParameters.RTBlurTemp01, FVector2D(BlurOffsetX, 0)); 149 | FogMaskPixelShader::BlurToRenderTarget_RenderThread(RHICmdList, DrawParameters.RTBlurTemp01, 150 | DrawParameters.RTBlurTemp, FVector2D(0, BlurOffsetY)); 151 | } 152 | //combine 153 | FogMaskPixelShader::CombineToRenderTarget_RenderThread(RHICmdList, DrawParameters.RTDest, 154 | DrawParameters.RTBlurTemp, DrawParameters.RTBlurTemp01, DrawParameters.RimFactor); 155 | FogMaskPixelShader::CombineToRenderTarget_RenderThread(RHICmdList, DrawParameters.RTBlurTemp01, 156 | DrawParameters.RTBlurTemp, DrawParameters.RTDest, 0); 157 | } 158 | 159 | #undef LOCTEXT_NAMESPACE 160 | 161 | IMPLEMENT_MODULE(FMaskFogPostProcessModule, MaskFogPostProcess) -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Source/MaskFogPostProcess/Public/FogMaskPixelShader.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "MaskFogPostProcess.h" 7 | 8 | class FogMaskPixelShader 9 | { 10 | public: 11 | static void DrawToRenderTarget_RenderThread(FRHICommandListImmediate& RHICmdList, const FShaderFogMaskParameters& DrawParameters); 12 | static void BlurToRenderTarget_RenderThread(FRHICommandListImmediate& RHICmdList, 13 | class UTextureRenderTarget2D* RTSrc, class UTextureRenderTarget2D* RTDest, const FVector2D& BlurOffset); 14 | static void CombineToRenderTarget_RenderThread(FRHICommandListImmediate& RHICmdList, 15 | class UTextureRenderTarget2D* RTSrc, class UTextureRenderTarget2D* RTBlur, class UTextureRenderTarget2D* RTDest, const float MulFactor); 16 | }; 17 | -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Source/MaskFogPostProcess/Public/MaskFogActor.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "Engine/TextureRenderTarget2D.h" 8 | #include "MaskFogActor.generated.h" 9 | 10 | UCLASS() 11 | class MASKFOGPOSTPROCESS_API AMaskFogActor : public AActor 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | // Sets default values for this actor's properties 17 | AMaskFogActor(); 18 | public: 19 | 20 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MaskFog") 21 | class UMaterialInterface* PPMaterialMaskFog; 22 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MaskFog") 23 | class APostProcessVolume* GlobalPPV; 24 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MaskFog") 25 | float ResolutionScale = 0.5f; 26 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MaskFog") 27 | float BlurResolutionScale = 0.5f; 28 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MaskFog") 29 | float BlurRadius = 8.f; 30 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MaskFog") 31 | float RimFactor = 2.f; 32 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MaskFog") 33 | int32 Iterations = 5; 34 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MaskFog") 35 | class USceneCaptureComponent2D* SceneCapture; 36 | 37 | protected: 38 | // Called when the game starts or when spawned 39 | virtual void BeginPlay() override; 40 | virtual void BeginDestroy() override; 41 | void InitRT(); 42 | UTextureRenderTarget2D* CreateRT(const TEnumAsByte RenderTargetFormat); 43 | 44 | UPROPERTY(transient) 45 | UTextureRenderTarget2D* FinalMask = nullptr; 46 | UPROPERTY(transient) 47 | UTextureRenderTarget2D* RTMaskBG = nullptr; 48 | UPROPERTY(transient) 49 | UTextureRenderTarget2D* RTBlurTemp = nullptr; 50 | UPROPERTY(transient) 51 | UTextureRenderTarget2D* RTBlurTemp01 = nullptr; 52 | uint32 RTInitSize = 512; 53 | public: 54 | // Called every frame 55 | virtual void Tick(float DeltaTime) override; 56 | 57 | }; 58 | -------------------------------------------------------------------------------- /Plugins/MaskFogPostProcess/Source/MaskFogPostProcess/Public/MaskFogPostProcess.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Modules/ModuleManager.h" 7 | 8 | #include "RenderGraphResources.h" 9 | #include "Runtime/Engine/Classes/Engine/TextureRenderTarget2D.h" 10 | 11 | // This struct contains all the data we need to pass from the game thread to draw our effect. 12 | struct FShaderFogMaskParameters 13 | { 14 | UTextureRenderTarget2D* RTDest; 15 | UTextureRenderTarget2D* RTSrc; 16 | UTextureRenderTarget2D* RTBlurTemp; 17 | UTextureRenderTarget2D* RTBlurTemp01; 18 | //transient 19 | FTextureRHIRef SceneDepth; 20 | FVector2D ViewSize; 21 | FVector4 InvDeviceZToWorldZTransform; 22 | float BlurRadius; 23 | float RimFactor; 24 | int Iterations; 25 | 26 | FIntPoint GetRenderTargetSize() const 27 | { 28 | return CachedRenderTargetSize; 29 | } 30 | 31 | FShaderFogMaskParameters() { } 32 | FShaderFogMaskParameters(UTextureRenderTarget2D* Src, UTextureRenderTarget2D* Temp, 33 | UTextureRenderTarget2D* Temp01, UTextureRenderTarget2D* Dest) 34 | : RTSrc(Src) 35 | , RTBlurTemp(Temp) 36 | , RTBlurTemp01(Temp01) 37 | , RTDest(Dest) 38 | { 39 | CachedRenderTargetSize = RTDest ? FIntPoint(RTDest->SizeX, RTDest->SizeY) : FIntPoint::ZeroValue; 40 | } 41 | 42 | private: 43 | FIntPoint CachedRenderTargetSize; 44 | }; 45 | 46 | class FMaskFogPostProcessModule : public IModuleInterface 47 | { 48 | public: 49 | static inline FMaskFogPostProcessModule& Get() 50 | { 51 | return FModuleManager::LoadModuleChecked("MaskFogPostProcess"); 52 | } 53 | 54 | static inline bool IsAvailable() 55 | { 56 | return FModuleManager::Get().IsModuleLoaded("MaskFogPostProcess"); 57 | } 58 | public: 59 | /** IModuleInterface implementation */ 60 | virtual void StartupModule() override; 61 | virtual void ShutdownModule() override; 62 | public: 63 | // Call this when you want to hook onto the renderer and start drawing. The shader will be executed once per frame. 64 | void BeginRendering(); 65 | 66 | // When you are done, call this to stop drawing. 67 | void EndRendering(); 68 | 69 | // Call this whenever you have new parameters to share. You could set this up to update different sets of properties at 70 | // different intervals to save on locking and GPU transfer time. 71 | void UpdateParameters(FShaderFogMaskParameters& DrawParameters); 72 | 73 | private: 74 | FShaderFogMaskParameters CachedFogMaskParameters; 75 | FDelegateHandle OnPostResolvedSceneColorHandle; 76 | FDelegateHandle OnPostOpaqueRenderDelegateHandle; 77 | FCriticalSection RenderEveryFrameLock; 78 | volatile bool bCachedParametersValid; 79 | volatile bool bIsGameView = false; 80 | volatile bool bIsSceneCapture = false; 81 | 82 | void PostResolveSceneColor_RenderThread(FRHICommandListImmediate& RHICmdList, class FSceneRenderTargets& SceneContext); 83 | void Draw_RenderThread(const FShaderFogMaskParameters& DrawParameters); 84 | void PostOpaqueRender_RenderThread(FPostOpaqueRenderParameters& Parameters); 85 | }; 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UE4MultipassPostprocess 2 | this is sample project for multipass gaussion blur plugin for UE427. 3 | ![fogmask01](https://user-images.githubusercontent.com/4982625/171999310-f27748d4-6a67-4229-872e-6cbaded5b509.png) 4 | -------------------------------------------------------------------------------- /Source/MaskFog.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class MaskFogTarget : TargetRules 7 | { 8 | public MaskFogTarget( TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Game; 11 | DefaultBuildSettings = BuildSettingsVersion.V2; 12 | ExtraModuleNames.AddRange( new string[] { "MaskFog" } ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/MaskFog/MaskFog.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class MaskFog : ModuleRules 6 | { 7 | public MaskFog(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); 12 | 13 | PrivateDependencyModuleNames.AddRange(new string[] { }); 14 | 15 | // Uncomment if you are using Slate UI 16 | // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); 17 | 18 | // Uncomment if you are using online features 19 | // PrivateDependencyModuleNames.Add("OnlineSubsystem"); 20 | 21 | // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/MaskFog/MaskFog.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "MaskFog.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, MaskFog, "MaskFog" ); 7 | -------------------------------------------------------------------------------- /Source/MaskFog/MaskFog.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | -------------------------------------------------------------------------------- /Source/MaskFog/MaskFogGameModeBase.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | 4 | #include "MaskFogGameModeBase.h" 5 | 6 | -------------------------------------------------------------------------------- /Source/MaskFog/MaskFogGameModeBase.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameModeBase.h" 7 | #include "MaskFogGameModeBase.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class MASKFOG_API AMaskFogGameModeBase : public AGameModeBase 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Source/MaskFogEditor.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class MaskFogEditorTarget : TargetRules 7 | { 8 | public MaskFogEditorTarget( TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Editor; 11 | DefaultBuildSettings = BuildSettingsVersion.V2; 12 | ExtraModuleNames.AddRange( new string[] { "MaskFog" } ); 13 | } 14 | } 15 | --------------------------------------------------------------------------------