• UE4后处理:PostProcessMaterial


    1. // Post Process Material Chain - Before Translucency
    2. {
    3. const FPostProcessMaterialChain MaterialChain = GetPostProcessMaterialChain(View, BL_BeforeTranslucency);
    4. if (MaterialChain.Num())
    5. {
    6. SceneColor = AddPostProcessMaterialChain(GraphBuilder, View, GetPostProcessMaterialInputs(SceneColor), MaterialChain);
    7. }
    8. }
    9. FScreenPassTexture AddPostProcessMaterialChain(
    10. FRDGBuilder& GraphBuilder,
    11. const FViewInfo& View,
    12. const FPostProcessMaterialInputs& InputsTemplate,
    13. const FPostProcessMaterialChain& Materials)
    14. {
    15. FScreenPassTexture Outputs = InputsTemplate.GetInput(EPostProcessMaterialInput::SceneColor);
    16. bool bFirstMaterialInChain = true;
    17. for (const UMaterialInterface* MaterialInterface : Materials)
    18. {
    19. FPostProcessMaterialInputs Inputs = InputsTemplate;
    20. Inputs.SetInput(EPostProcessMaterialInput::SceneColor, Outputs);
    21. // Only the first material in the chain needs to decode the input color
    22. Inputs.bMetalMSAAHDRDecode = Inputs.bMetalMSAAHDRDecode && bFirstMaterialInChain;
    23. bFirstMaterialInChain = false;
    24. // Certain inputs are only respected by the final post process material in the chain.
    25. if (MaterialInterface != Materials.Last())
    26. {
    27. Inputs.OverrideOutput = FScreenPassRenderTarget();
    28. Inputs.bFlipYAxis = false;
    29. }
    30. Outputs = AddPostProcessMaterialPass(GraphBuilder, View, Inputs, MaterialInterface);
    31. }
    32. return Outputs;
    33. }
    1. FScreenPassTexture AddPostProcessMaterialPass(
    2. FRDGBuilder& GraphBuilder,
    3. const FViewInfo& View,
    4. const FPostProcessMaterialInputs& Inputs,
    5. const UMaterialInterface* MaterialInterface)
    6. {
    7. Inputs.Validate();
    8. const FScreenPassTexture SceneColor = Inputs.GetInput(EPostProcessMaterialInput::SceneColor);
    9. const ERHIFeatureLevel::Type FeatureLevel = View.GetFeatureLevel();
    10. const FMaterial* Material = nullptr;
    11. const FMaterialRenderProxy* MaterialRenderProxy = nullptr;
    12. const FMaterialShaderMap* MaterialShaderMap = nullptr;
    13. GetMaterialInfo(MaterialInterface, FeatureLevel, Inputs.OutputFormat, Material, MaterialRenderProxy, MaterialShaderMap);
    14. FRHIDepthStencilState* DefaultDepthStencilState = FScreenPassPipelineState::FDefaultDepthStencilState::GetRHI();
    15. FRHIDepthStencilState* DepthStencilState = DefaultDepthStencilState;
    16. FRDGTextureRef DepthStencilTexture = nullptr;
    17. // Allocate custom depth stencil texture(s) and depth stencil state.
    18. const ECustomDepthPolicy CustomStencilPolicy = GetMaterialCustomDepthPolicy(Material, FeatureLevel);
    19. if (CustomStencilPolicy == ECustomDepthPolicy::Enabled)
    20. {
    21. check(Inputs.CustomDepthTexture);
    22. DepthStencilTexture = Inputs.CustomDepthTexture;
    23. DepthStencilState = GetMaterialStencilState(Material);
    24. }
    25. FRHIBlendState* DefaultBlendState = FScreenPassPipelineState::FDefaultBlendState::GetRHI();
    26. FRHIBlendState* BlendState = DefaultBlendState;
    27. if (IsMaterialBlendEnabled(Material))
    28. {
    29. BlendState = GetMaterialBlendState(Material);
    30. }
    31. // Blend / Depth Stencil usage requires that the render target have primed color data.
    32. const bool bCompositeWithInput = DepthStencilState != DefaultDepthStencilState || BlendState != DefaultBlendState;
    33. // We only prime color on the output texture if we are using fixed function Blend / Depth-Stencil,
    34. // or we need to retain previously rendered views.
    35. const bool bPrimeOutputColor = bCompositeWithInput || !View.IsFirstInFamily();
    36. // Inputs.OverrideOutput is used to force drawing directly to the backbuffer. OpenGL doesn't support using the backbuffer color target with a custom depth/stencil
    37. // buffer, so in that case we must draw to an intermediate target and copy to the backbuffer at the end. Ideally, we would test if Inputs.OverrideOutput.Texture
    38. // is actually the backbuffer (as returned by AndroidEGL::GetOnScreenColorRenderBuffer() and such), but it's not worth doing all the plumbing and increasing the
    39. // RHI surface area just for this hack.
    40. const bool bBackbufferWithDepthStencil = (DepthStencilTexture != nullptr && !GRHISupportsBackBufferWithCustomDepthStencil && Inputs.OverrideOutput.IsValid());
    41. // The other case when we must render to an intermediate target is when we have to flip the image vertically because we're the last postprocess pass on mobile OpenGL.
    42. // We can't simply output a flipped image, because the parts of the input image which show through the stencil mask or are blended in must also be flipped. In that case,
    43. // we render normally to the intermediate target and flip the image when we copy to the output target.
    44. const bool bCompositeWithInputAndFlipY = bCompositeWithInput && Inputs.bFlipYAxis;
    45. // We need to decode the target color for blending material, force it rendering to an intermediate render target and decode the color.
    46. const bool bCompositeWithInputAndDecode = Inputs.bMetalMSAAHDRDecode && bCompositeWithInput;
    47. const bool bForceIntermediateTarget = bBackbufferWithDepthStencil || bCompositeWithInputAndFlipY || bCompositeWithInputAndDecode;
    48. FScreenPassRenderTarget Output = Inputs.OverrideOutput;
    49. // We can re-use the scene color texture as the render target if we're not simultaneously reading from it.
    50. // This is only necessary to do if we're going to be priming content from the render target since it avoids
    51. // the copy. Otherwise, we just allocate a new render target.
    52. if (!Output.IsValid() && !MaterialShaderMap->UsesSceneTexture(PPI_PostProcessInput0) && bPrimeOutputColor && !bForceIntermediateTarget && Inputs.bAllowSceneColorInputAsOutput)
    53. {
    54. Output = FScreenPassRenderTarget(SceneColor, ERenderTargetLoadAction::ELoad);
    55. }
    56. else
    57. {
    58. // Allocate new transient output texture if none exists.
    59. if (!Output.IsValid() || bForceIntermediateTarget)
    60. {
    61. FRDGTextureDesc OutputDesc = SceneColor.Texture->Desc;
    62. OutputDesc.Reset();
    63. if (Inputs.OutputFormat != PF_Unknown)
    64. {
    65. OutputDesc.Format = Inputs.OutputFormat;
    66. }
    67. OutputDesc.ClearValue = FClearValueBinding(FLinearColor::Black);
    68. OutputDesc.Flags |= GFastVRamConfig.PostProcessMaterial;
    69. Output = FScreenPassRenderTarget(GraphBuilder.CreateTexture(OutputDesc, TEXT("PostProcessMaterial")), SceneColor.ViewRect, View.GetOverwriteLoadAction());
    70. }
    71. if (bPrimeOutputColor || bForceIntermediateTarget)
    72. {
    73. // Copy existing contents to new output and use load-action to preserve untouched pixels.
    74. if (Inputs.bMetalMSAAHDRDecode)
    75. {
    76. AddMobileMSAADecodeAndDrawTexturePass(GraphBuilder, View, SceneColor, Output);
    77. }
    78. else
    79. {
    80. AddDrawTexturePass(GraphBuilder, View, SceneColor, Output);
    81. }
    82. Output.LoadAction = ERenderTargetLoadAction::ELoad;
    83. }
    84. }
    85. const FScreenPassTextureViewport SceneColorViewport(SceneColor);
    86. const FScreenPassTextureViewport OutputViewport(Output);
    87. RDG_EVENT_SCOPE(GraphBuilder, "PostProcessMaterial %dx%d Material=%s", SceneColorViewport.Rect.Width(), SceneColorViewport.Rect.Height(), *Material->GetFriendlyName());
    88. const uint32 MaterialStencilRef = Material->GetStencilRefValue();
    89. const bool bMobilePlatform = IsMobilePlatform(View.GetShaderPlatform());
    90. FPostProcessMaterialParameters* PostProcessMaterialParameters = GraphBuilder.AllocParameters();
    91. PostProcessMaterialParameters->SceneTextures = Inputs.SceneTextures;
    92. PostProcessMaterialParameters->View = View.ViewUniformBuffer;
    93. if (bMobilePlatform)
    94. {
    95. PostProcessMaterialParameters->EyeAdaptationBuffer = GetEyeAdaptationBuffer(View);
    96. }
    97. else
    98. {
    99. PostProcessMaterialParameters->EyeAdaptationTexture = GetEyeAdaptationTexture(GraphBuilder, View);
    100. }
    101. PostProcessMaterialParameters->PostProcessOutput = GetScreenPassTextureViewportParameters(OutputViewport);
    102. PostProcessMaterialParameters->MobileCustomStencilTexture = DepthStencilTexture;
    103. PostProcessMaterialParameters->MobileCustomStencilTextureSampler = TStaticSamplerState::GetRHI();
    104. PostProcessMaterialParameters->MobileStencilValueRef = MaterialStencilRef;
    105. PostProcessMaterialParameters->RenderTargets[0] = Output.GetRenderTargetBinding();
    106. // The target color will be decoded if bForceIntermediateTarget is true in any case, but we might still need to decode the input color
    107. PostProcessMaterialParameters->bMetalMSAAHDRDecode = Inputs.bMetalMSAAHDRDecode ? 1 : 0;
    108. if (DepthStencilTexture && !bMobilePlatform)
    109. {
    110. PostProcessMaterialParameters->RenderTargets.DepthStencil = FDepthStencilBinding(
    111. DepthStencilTexture,
    112. ERenderTargetLoadAction::ELoad,
    113. ERenderTargetLoadAction::ELoad,
    114. FExclusiveDepthStencil::DepthRead_StencilRead);
    115. }
    116. else if (!DepthStencilTexture && bMobilePlatform && Material->IsStencilTestEnabled()) // we have to set a default texture for MobileStencilTexture and override the MobileStencilValueRef to make all function to pass the stencil test
    117. {
    118. PostProcessMaterialParameters->MobileCustomStencilTexture = GSystemTextures.GetBlackDummy(GraphBuilder);
    119. switch (Material->GetStencilCompare())
    120. {
    121. case EMaterialStencilCompare::MSC_Less:
    122. PostProcessMaterialParameters->MobileStencilValueRef = -1;
    123. break;
    124. case EMaterialStencilCompare::MSC_LessEqual:
    125. case EMaterialStencilCompare::MSC_GreaterEqual:
    126. case EMaterialStencilCompare::MSC_Equal:
    127. PostProcessMaterialParameters->MobileStencilValueRef = 0;
    128. break;
    129. case EMaterialStencilCompare::MSC_Greater:
    130. case EMaterialStencilCompare::MSC_NotEqual:
    131. PostProcessMaterialParameters->MobileStencilValueRef = 1;
    132. break;
    133. case EMaterialStencilCompare::MSC_Always:
    134. PostProcessMaterialParameters->MobileStencilValueRef = 256;
    135. break;
    136. default:
    137. break;
    138. }
    139. }
    140. PostProcessMaterialParameters->PostProcessInput_BilinearSampler = TStaticSamplerState::GetRHI();;
    141. const FScreenPassTexture BlackDummy(GSystemTextures.GetBlackDummy(GraphBuilder));
    142. // This gets passed in whether or not it's used.
    143. GraphBuilder.RemoveUnusedTextureWarning(BlackDummy.Texture);
    144. FRHISamplerState* PointClampSampler = TStaticSamplerState::GetRHI();
    145. for (uint32 InputIndex = 0; InputIndex < kPostProcessMaterialInputCountMax; ++InputIndex)
    146. {
    147. FScreenPassTexture Input = Inputs.GetInput((EPostProcessMaterialInput)InputIndex);
    148. // Need to provide valid textures for when shader compilation doesn't cull unused parameters.
    149. if (!Input.Texture || !MaterialShaderMap->UsesSceneTexture(PPI_PostProcessInput0 + InputIndex))
    150. {
    151. Input = BlackDummy;
    152. }
    153. PostProcessMaterialParameters->PostProcessInput[InputIndex] = GetScreenPassTextureInput(Input, PointClampSampler);
    154. }
    155. const bool bIsMobile = FeatureLevel <= ERHIFeatureLevel::ES3_1;
    156. PostProcessMaterialParameters->bFlipYAxis = Inputs.bFlipYAxis && !bForceIntermediateTarget;
    157. FPostProcessMaterialShader::FPermutationDomain PermutationVector;
    158. PermutationVector.Set(bIsMobile);
    159. TShaderRef VertexShader = MaterialShaderMap->GetShader(PermutationVector);
    160. TShaderRef PixelShader = MaterialShaderMap->GetShader(PermutationVector);
    161. ClearUnusedGraphResources(VertexShader, PixelShader, PostProcessMaterialParameters);
    162. EScreenPassDrawFlags ScreenPassFlags = EScreenPassDrawFlags::AllowHMDHiddenAreaMask;
    163. if (PostProcessMaterialParameters->bFlipYAxis)
    164. {
    165. ScreenPassFlags |= EScreenPassDrawFlags::FlipYAxis;
    166. }
    167. AddDrawScreenPass(
    168. GraphBuilder,
    169. RDG_EVENT_NAME("PostProcessMaterial"),
    170. View,
    171. OutputViewport,
    172. SceneColorViewport,
    173. FScreenPassPipelineState(VertexShader, PixelShader, BlendState, DepthStencilState),
    174. PostProcessMaterialParameters,
    175. ScreenPassFlags,
    176. [&View, VertexShader, PixelShader, MaterialRenderProxy, PostProcessMaterialParameters, MaterialStencilRef](FRHICommandListImmediate& RHICmdList)
    177. {
    178. FPostProcessMaterialVS::SetParameters(RHICmdList, VertexShader, View, MaterialRenderProxy, *PostProcessMaterialParameters);
    179. FPostProcessMaterialPS::SetParameters(RHICmdList, PixelShader, View, MaterialRenderProxy, *PostProcessMaterialParameters);
    180. RHICmdList.SetStencilRef(MaterialStencilRef);
    181. });
    182. if (bForceIntermediateTarget && !bCompositeWithInputAndDecode)
    183. {
    184. if (!Inputs.bFlipYAxis)
    185. {
    186. // We shouldn't get here unless we had an override target.
    187. check(Inputs.OverrideOutput.IsValid());
    188. AddDrawTexturePass(GraphBuilder, View, Output.Texture, Inputs.OverrideOutput.Texture);
    189. Output = Inputs.OverrideOutput;
    190. }
    191. else
    192. {
    193. FScreenPassRenderTarget TempTarget = Output;
    194. if (Inputs.OverrideOutput.IsValid())
    195. {
    196. Output = Inputs.OverrideOutput;
    197. }
    198. else
    199. {
    200. Output = FScreenPassRenderTarget(SceneColor, ERenderTargetLoadAction::ENoAction);
    201. }
    202. AddCopyAndFlipTexturePass(GraphBuilder, View, TempTarget.Texture, Output.Texture);
    203. }
    204. }
    205. return MoveTemp(Output);
    206. }
    1. /** Render graph variant of more advanced DrawScreenPass function. Does *not* clear unused graph
    2. * resources, since the parameters might be shared between the vertex and pixel shaders.
    3. */
    4. template <typename TSetupFunction, typename TPassParameterStruct>
    5. FORCEINLINE void AddDrawScreenPass(
    6. FRDGBuilder& GraphBuilder,
    7. FRDGEventName&& PassName,
    8. const FViewInfo& View,
    9. const FScreenPassTextureViewport& OutputViewport,
    10. const FScreenPassTextureViewport& InputViewport,
    11. const FScreenPassPipelineState& PipelineState,
    12. TPassParameterStruct* PassParameterStruct,
    13. EScreenPassDrawFlags Flags,
    14. TSetupFunction SetupFunction)
    15. {
    16. PipelineState.Validate();
    17. check(PassParameterStruct);
    18. GraphBuilder.AddPass(
    19. Forward(PassName),
    20. PassParameterStruct,
    21. ERDGPassFlags::Raster,
    22. [&View, OutputViewport, InputViewport, PipelineState, SetupFunction, Flags] (FRHICommandListImmediate& RHICmdList)
    23. {
    24. DrawScreenPass(RHICmdList, View, OutputViewport, InputViewport, PipelineState, Flags, SetupFunction);
    25. });
    26. }
    27. /** More advanced variant of screen pass drawing. Supports overriding blend / depth stencil
    28. * pipeline state, and providing a custom vertex shader. Shader parameters are not bound by
    29. * this method, instead the user provides a setup function that is called prior to draw, but
    30. * after setting the PSO. This setup function should assign shader parameters.
    31. */
    32. template<typename TSetupFunction>
    33. void DrawScreenPass(
    34. FRHICommandListImmediate& RHICmdList,
    35. const FViewInfo& View,
    36. const FScreenPassTextureViewport& OutputViewport,
    37. const FScreenPassTextureViewport& InputViewport,
    38. const FScreenPassPipelineState& PipelineState,
    39. EScreenPassDrawFlags Flags,
    40. TSetupFunction SetupFunction)
    41. {
    42. PipelineState.Validate();
    43. const FIntRect InputRect = InputViewport.Rect;
    44. const FIntPoint InputSize = InputViewport.Extent;
    45. const FIntRect OutputRect = OutputViewport.Rect;
    46. const FIntPoint OutputSize = OutputRect.Size();
    47. RHICmdList.SetViewport(OutputRect.Min.X, OutputRect.Min.Y, 0.0f, OutputRect.Max.X, OutputRect.Max.Y, 1.0f);
    48. SetScreenPassPipelineState(RHICmdList, PipelineState);
    49. SetupFunction(RHICmdList);
    50. FIntPoint LocalOutputPos(FIntPoint::ZeroValue);
    51. FIntPoint LocalOutputSize(OutputSize);
    52. EDrawRectangleFlags DrawRectangleFlags = EDRF_UseTriangleOptimization;
    53. const bool bFlipYAxis = (Flags & EScreenPassDrawFlags::FlipYAxis) == EScreenPassDrawFlags::FlipYAxis;
    54. if (bFlipYAxis)
    55. {
    56. // Draw the quad flipped. Requires that the cull mode be disabled.
    57. LocalOutputPos.Y = OutputSize.Y;
    58. LocalOutputSize.Y = -OutputSize.Y;
    59. // Triangle optimization currently doesn't work when flipped.
    60. DrawRectangleFlags = EDRF_Default;
    61. }
    62. const bool bUseHMDHiddenAreaMask = (Flags & EScreenPassDrawFlags::AllowHMDHiddenAreaMask) == EScreenPassDrawFlags::AllowHMDHiddenAreaMask
    63. ? View.bHMDHiddenAreaMaskActive
    64. : false;
    65. DrawPostProcessPass(
    66. RHICmdList,
    67. LocalOutputPos.X, LocalOutputPos.Y, LocalOutputSize.X, LocalOutputSize.Y,
    68. InputRect.Min.X, InputRect.Min.Y, InputRect.Width(), InputRect.Height(),
    69. OutputSize,
    70. InputSize,
    71. PipelineState.VertexShader,
    72. View.StereoPass,
    73. bUseHMDHiddenAreaMask,
    74. DrawRectangleFlags);
    75. }
    1. void DrawPostProcessPass(
    2. FRHICommandList& RHICmdList,
    3. float X,
    4. float Y,
    5. float SizeX,
    6. float SizeY,
    7. float U,
    8. float V,
    9. float SizeU,
    10. float SizeV,
    11. FIntPoint TargetSize,
    12. FIntPoint TextureSize,
    13. const TShaderRef& VertexShader,
    14. EStereoscopicPass StereoView,
    15. bool bHasCustomMesh,
    16. EDrawRectangleFlags Flags)
    17. {
    18. if (bHasCustomMesh && IStereoRendering::IsStereoEyePass(StereoView))
    19. {
    20. DrawHmdMesh(RHICmdList, X, Y, SizeX, SizeY, U, V, SizeU, SizeV, TargetSize, TextureSize, StereoView, VertexShader);
    21. }
    22. else
    23. {
    24. DrawRectangle(RHICmdList, X, Y, SizeX, SizeY, U, V, SizeU, SizeV, TargetSize, TextureSize, VertexShader, Flags);
    25. }
    26. }
    27. void DrawRectangle(
    28. FRHICommandList& RHICmdList,
    29. float X,
    30. float Y,
    31. float SizeX,
    32. float SizeY,
    33. float U,
    34. float V,
    35. float SizeU,
    36. float SizeV,
    37. FIntPoint TargetSize,
    38. FIntPoint TextureSize,
    39. const TShaderRef& VertexShader,
    40. EDrawRectangleFlags Flags,
    41. uint32 InstanceCount
    42. )
    43. {
    44. InternalDrawRectangle(RHICmdList, X, Y, SizeX, SizeY, U, V, SizeU, SizeV, TargetSize, TextureSize, VertexShader, Flags, InstanceCount);
    45. }
    46. template <typename TRHICommandList>
    47. static inline void InternalDrawRectangle(
    48. TRHICommandList& RHICmdList,
    49. float X,
    50. float Y,
    51. float SizeX,
    52. float SizeY,
    53. float U,
    54. float V,
    55. float SizeU,
    56. float SizeV,
    57. FIntPoint TargetSize,
    58. FIntPoint TextureSize,
    59. const TShaderRef& VertexShader,
    60. EDrawRectangleFlags Flags,
    61. uint32 InstanceCount
    62. )
    63. {
    64. float ClipSpaceQuadZ = 0.0f;
    65. DoDrawRectangleFlagOverride(Flags);
    66. // triangle if extending to left and top of the given rectangle, if it's not left top of the viewport it can cause artifacts
    67. if(X > 0.0f || Y > 0.0f)
    68. {
    69. // don't use triangle optimization
    70. Flags = EDRF_Default;
    71. }
    72. // Set up vertex uniform parameters for scaling and biasing the rectangle.
    73. // Note: Use DrawRectangle in the vertex shader to calculate the correct vertex position and uv.
    74. FDrawRectangleParameters Parameters;
    75. Parameters.PosScaleBias = FVector4(SizeX, SizeY, X, Y);
    76. Parameters.UVScaleBias = FVector4(SizeU, SizeV, U, V);
    77. Parameters.InvTargetSizeAndTextureSize = FVector4(
    78. 1.0f / TargetSize.X, 1.0f / TargetSize.Y,
    79. 1.0f / TextureSize.X, 1.0f / TextureSize.Y);
    80. SetUniformBufferParameterImmediate(RHICmdList, VertexShader.GetVertexShader(), VertexShader->GetUniformBufferParameter(), Parameters);
    81. if(Flags == EDRF_UseTesselatedIndexBuffer)
    82. {
    83. // no vertex buffer needed as we compute it in VS
    84. RHICmdList.SetStreamSource(0, NULL, 0);
    85. RHICmdList.DrawIndexedPrimitive(
    86. GTesselatedScreenRectangleIndexBuffer.IndexBufferRHI,
    87. /*BaseVertexIndex=*/ 0,
    88. /*MinIndex=*/ 0,
    89. /*NumVertices=*/ GTesselatedScreenRectangleIndexBuffer.NumVertices(),
    90. /*StartIndex=*/ 0,
    91. /*NumPrimitives=*/ GTesselatedScreenRectangleIndexBuffer.NumPrimitives(),
    92. /*NumInstances=*/ InstanceCount
    93. );
    94. }
    95. else
    96. {
    97. if (Flags == EDRF_UseTriangleOptimization)
    98. {
    99. FPixelShaderUtils::DrawFullscreenTriangle(RHICmdList, InstanceCount);
    100. }
    101. else
    102. {
    103. FPixelShaderUtils::DrawFullscreenQuad(RHICmdList, InstanceCount);
    104. }
    105. }
    106. }

    shader :PostProcessMaterialShaders.usf

    1. #if NUM_TEX_COORD_INTERPOLATORS
    2. void GetMaterialCustomizedUVs(FMaterialVertexParameters Parameters, inout float2 OutTexCoords[NUM_TEX_COORD_INTERPOLATORS])
    3. {
    4. OutTexCoords[0] = Parameters.TexCoords[0].xy;
    5. }
    6. void GetCustomInterpolators(FMaterialVertexParameters Parameters, inout float2 OutTexCoords[NUM_TEX_COORD_INTERPOLATORS])
    7. {
    8. }
    9. #endif
    1. // Copyright Epic Games, Inc. All Rights Reserved.
    2. /*=============================================================================
    3. PostProcessMaterialShaders.usf: Shaders for rendering post process materials
    4. =============================================================================*/
    5. #include "Common.ush"
    6. #include "ScreenPass.ush"
    7. #ifndef POST_PROCESS_MATERIAL
    8. #define POST_PROCESS_MATERIAL 0
    9. #endif
    10. #ifndef POST_PROCESS_MATERIAL_MOBILE
    11. #define POST_PROCESS_MATERIAL_MOBILE 0
    12. #endif
    13. #if (POST_PROCESS_MATERIAL == 0)
    14. #error POST_PROCESS_MATERIAL must be defined to non-zero in the shader compilation environment.
    15. #endif
    16. #if (FEATURE_LEVEL <= FEATURE_LEVEL_ES3_1) != POST_PROCESS_MATERIAL_MOBILE
    17. #error POST_PROCESS_MATERIAL_MOBILE define does not match feature level.
    18. #endif
    19. // Must match ESceneTextureId
    20. #define PPI_PostProcessInput0 14
    21. #define PPI_PostProcessInput1 15
    22. #define PPI_PostProcessInput2 16
    23. #define PPI_PostProcessInput3 17
    24. #define PPI_PostProcessInput4 18
    25. SCREEN_PASS_TEXTURE_VIEWPORT(PostProcessInput_0)
    26. SCREEN_PASS_TEXTURE_VIEWPORT(PostProcessInput_1)
    27. SCREEN_PASS_TEXTURE_VIEWPORT(PostProcessInput_2)
    28. SCREEN_PASS_TEXTURE_VIEWPORT(PostProcessInput_3)
    29. SCREEN_PASS_TEXTURE_VIEWPORT(PostProcessInput_4)
    30. SCREEN_PASS_TEXTURE_VIEWPORT(PostProcessOutput)
    31. Texture2D PostProcessInput_0_Texture;
    32. Texture2D PostProcessInput_1_Texture;
    33. Texture2D PostProcessInput_2_Texture;
    34. Texture2D PostProcessInput_3_Texture;
    35. Texture2D PostProcessInput_4_Texture;
    36. SamplerState PostProcessInput_0_Sampler;
    37. SamplerState PostProcessInput_1_Sampler;
    38. SamplerState PostProcessInput_2_Sampler;
    39. SamplerState PostProcessInput_3_Sampler;
    40. SamplerState PostProcessInput_4_Sampler;
    41. SamplerState PostProcessInput_BilinearSampler;
    42. #if SUPPORTS_INDEPENDENT_SAMPLERS
    43. #define PostProcessInput_0_SharedSampler PostProcessInput_0_Sampler
    44. #define PostProcessInput_1_SharedSampler PostProcessInput_0_Sampler
    45. #define PostProcessInput_2_SharedSampler PostProcessInput_0_Sampler
    46. #define PostProcessInput_3_SharedSampler PostProcessInput_0_Sampler
    47. #define PostProcessInput_4_SharedSampler PostProcessInput_0_Sampler
    48. #else
    49. #define PostProcessInput_0_SharedSampler PostProcessInput_0_Sampler
    50. #define PostProcessInput_1_SharedSampler PostProcessInput_1_Sampler
    51. #define PostProcessInput_2_SharedSampler PostProcessInput_2_Sampler
    52. #define PostProcessInput_3_SharedSampler PostProcessInput_3_Sampler
    53. #define PostProcessInput_4_SharedSampler PostProcessInput_4_Sampler
    54. #endif
    55. #define EYE_ADAPTATION_LOOSE_PARAMETERS 1
    56. #include "/Engine/Generated/Material.ush"
    57. struct FPostProcessMaterialVSToPS
    58. {
    59. float4 Position : SV_POSITION;
    60. #if NUM_TEX_COORD_INTERPOLATORS
    61. float4 TexCoords[(NUM_TEX_COORD_INTERPOLATORS+1)/2] : TEXCOORD0;
    62. #endif
    63. };
    64. #if NUM_TEX_COORD_INTERPOLATORS
    65. float2 GetUV(FPostProcessMaterialVSToPS Interpolants, int UVIndex)
    66. {
    67. float4 UVVector = Interpolants.TexCoords[UVIndex / 2];
    68. return Mod(UVIndex, 2) == 1 ? UVVector.zw : UVVector.xy;
    69. }
    70. void SetUV(inout FPostProcessMaterialVSToPS Interpolants, int UVIndex, float2 InValue)
    71. {
    72. FLATTEN
    73. if (Mod(UVIndex, 2) == 1)
    74. {
    75. Interpolants.TexCoords[UVIndex / 2].zw = InValue;
    76. }
    77. else
    78. {
    79. Interpolants.TexCoords[UVIndex / 2].xy = InValue;
    80. }
    81. }
    82. #endif
    83. FMaterialVertexParameters GetPostProcessMaterialVSParameters(float2 UV)
    84. {
    85. // Most params irrelevant so not a lot to fill out here
    86. FMaterialVertexParameters Result = (FMaterialVertexParameters)0;
    87. Result.VertexColor = 1.f.xxxx;
    88. Result.WorldPosition = float3(UV, 0.f);
    89. #if NUM_MATERIAL_TEXCOORDS_VERTEX
    90. UNROLL
    91. for (int CoordinateIndex = 0; CoordinateIndex < NUM_MATERIAL_TEXCOORDS_VERTEX; CoordinateIndex++)
    92. {
    93. Result.TexCoords[CoordinateIndex] = UV;
    94. }
    95. #endif
    96. return Result;
    97. }
    98. #if (FEATURE_LEVEL > FEATURE_LEVEL_ES3_1)
    99. #if VERTEXSHADER
    100. void MainVS(
    101. in float4 InPosition : ATTRIBUTE0,
    102. out FPostProcessMaterialVSToPS Output
    103. )
    104. {
    105. Output = (FPostProcessMaterialVSToPS)0;
    106. DrawRectangle(InPosition, Output.Position);
    107. #if NUM_TEX_COORD_INTERPOLATORS
    108. FMaterialVertexParameters VertexParameters = GetPostProcessMaterialVSParameters(InPosition.xy);
    109. float2 CustomizedUVs[NUM_TEX_COORD_INTERPOLATORS];
    110. GetMaterialCustomizedUVs(VertexParameters, CustomizedUVs);
    111. GetCustomInterpolators(VertexParameters, CustomizedUVs);
    112. {
    113. UNROLL
    114. for (int CoordinateIndex = 0; CoordinateIndex < NUM_MATERIAL_TEXCOORDS; CoordinateIndex++)
    115. {
    116. SetUV(Output, CoordinateIndex, InPosition.xy);
    117. }
    118. }
    119. {
    120. UNROLL
    121. for (int CoordinateIndex = NUM_MATERIAL_TEXCOORDS; CoordinateIndex < NUM_TEX_COORD_INTERPOLATORS; CoordinateIndex++)
    122. {
    123. SetUV(Output, CoordinateIndex, CustomizedUVs[CoordinateIndex]);
    124. }
    125. }
    126. #endif
    127. }
    128. void MainVS_VideoOverlay(
    129. in float4 InPosition : ATTRIBUTE0,
    130. in float2 InTexCoord : ATTRIBUTE1,
    131. out float2 OutUV : TEXCOORD0,
    132. out float4 OutPosition : SV_POSITION
    133. )
    134. {
    135. DrawRectangle(InPosition, InTexCoord, OutPosition, OutUV);
    136. }
    137. #elif PIXELSHADER
    138. void MainPS(
    139. in FPostProcessMaterialVSToPS Input,
    140. out float4 OutColor : SV_Target0
    141. )
    142. {
    143. ResolvedView = ResolveView();
    144. FMaterialPixelParameters Parameters = MakeInitializedMaterialPixelParameters();
    145. FPixelMaterialInputs PixelMaterialInputs;
    146. // can be optimized
    147. float4 SvPosition = Input.Position;
    148. float2 ViewportUV = (SvPosition.xy - PostProcessOutput_ViewportMin.xy) * PostProcessOutput_ViewportSizeInverse.xy;
    149. #if NUM_TEX_COORD_INTERPOLATORS
    150. {
    151. UNROLL
    152. for (int CoordinateIndex = 0; CoordinateIndex < NUM_MATERIAL_TEXCOORDS; CoordinateIndex++)
    153. {
    154. Parameters.TexCoords[CoordinateIndex] = ViewportUV;
    155. }
    156. }
    157. {
    158. UNROLL
    159. for (int CoordinateIndex = NUM_MATERIAL_TEXCOORDS; CoordinateIndex < NUM_TEX_COORD_INTERPOLATORS; CoordinateIndex++)
    160. {
    161. Parameters.TexCoords[CoordinateIndex] = GetUV(Input, CoordinateIndex);
    162. }
    163. }
    164. #endif
    165. Parameters.VertexColor = 1;
    166. SvPosition.z = LookupDeviceZ(ViewportUVToBufferUV(ViewportUV));
    167. SvPosition.z = max(SvPosition.z, 1e-18);
    168. // fill out other related material parameters
    169. CalcMaterialParametersPost(Parameters, PixelMaterialInputs, SvPosition, true);
    170. // Grab emissive colour as output
    171. #if MATERIAL_OUTPUT_OPACITY_AS_ALPHA
    172. const float Alpha = GetMaterialOpacity(PixelMaterialInputs);
    173. #else
    174. const float Alpha = 1.0f;
    175. #endif
    176. OutColor = float4(GetMaterialEmissive(PixelMaterialInputs), Alpha );
    177. #if !MATERIALBLENDING_MODULATE && USE_PREEXPOSURE && POST_PROCESS_MATERIAL_BEFORE_TONEMAP
    178. OutColor.xyz *= View.PreExposure;
    179. #endif
    180. }
    181. void MainPS_VideoOverlay(
    182. in float2 InUV : TEXCOORD0,
    183. in float4 SvPosition : SV_Position, // after all interpolators
    184. out float4 OutColor : SV_Target0
    185. )
    186. {
    187. ResolvedView = ResolveView();
    188. FMaterialPixelParameters Parameters = MakeInitializedMaterialPixelParameters();
    189. FPixelMaterialInputs PixelMaterialInputs;
    190. float2 ViewportUV = InUV;
    191. #if NUM_MATERIAL_TEXCOORDS
    192. for(int CoordinateIndex = 0;CoordinateIndex < NUM_MATERIAL_TEXCOORDS;CoordinateIndex++)
    193. {
    194. Parameters.TexCoords[CoordinateIndex] = ViewportUV;
    195. }
    196. #endif
    197. Parameters.VertexColor = 1;
    198. SvPosition.z = LookupDeviceZ(ViewportUVToBufferUV(ViewportUV));
    199. SvPosition.z = max(SvPosition.z, 1e-18);
    200. // fill out other related material parameters
    201. CalcMaterialParametersPost(Parameters, PixelMaterialInputs, SvPosition, true);
    202. // Grab emissive colour as output
    203. #if MATERIAL_OUTPUT_OPACITY_AS_ALPHA
    204. const float Alpha = GetMaterialOpacity(PixelMaterialInputs);
    205. #else
    206. const float Alpha = 1.0f;
    207. #endif
    208. OutColor = float4(GetMaterialEmissive(PixelMaterialInputs), Alpha );
    209. }
    210. #else // !VERTEXSHADER && !PIXELSHADER
    211. #error Wrong shader domain.
    212. #endif
    213. #else // FEATURE_LEVEL_ES3_1
    214. Texture2D MobileCustomStencilTexture;
    215. SamplerState MobileCustomStencilTextureSampler;
    216. int MobileStencilValueRef; // Use integer cause it has to be negative to make the less function to pass the test as always
    217. uint bFlipYAxis;
    218. //
    219. // Mobile version
    220. //
    221. void MainVS(
    222. in float4 InPosition : ATTRIBUTE0,
    223. in float2 InTexCoord : ATTRIBUTE1,
    224. out FPostProcessMaterialVSToPS Output
    225. )
    226. {
    227. Output = (FPostProcessMaterialVSToPS)0;
    228. float2 OutUV;
    229. DrawRectangle(InPosition, InTexCoord, Output.Position, OutUV);
    230. #if NUM_TEX_COORD_INTERPOLATORS
    231. FMaterialVertexParameters VertexParameters = GetPostProcessMaterialVSParameters(InPosition.xy);
    232. float2 CustomizedUVs[NUM_TEX_COORD_INTERPOLATORS];
    233. GetMaterialCustomizedUVs(VertexParameters, CustomizedUVs);
    234. GetCustomInterpolators(VertexParameters, CustomizedUVs);
    235. UNROLL
    236. for (int CoordinateIndex = 0; CoordinateIndex < NUM_MATERIAL_TEXCOORDS; CoordinateIndex++)
    237. {
    238. #if POST_PROCESS_AR_PASSTHROUGH
    239. SetUV(Output, CoordinateIndex, OutUV);
    240. #else
    241. SetUV(Output, CoordinateIndex, InPosition.xy);
    242. #endif
    243. }
    244. UNROLL
    245. for (int CoordinateIndex = NUM_MATERIAL_TEXCOORDS; CoordinateIndex < NUM_TEX_COORD_INTERPOLATORS; CoordinateIndex++)
    246. {
    247. SetUV(Output, CoordinateIndex, CustomizedUVs[CoordinateIndex]);
    248. }
    249. #endif
    250. }
    251. #define MOBILE_STENCIL_COMPARE_LESS 0
    252. #define MOBILE_STENCIL_COMPARE_LESSEQUAL 1
    253. #define MOBILE_STENCIL_COMPARE_GREATE 2
    254. #define MOBILE_STENCIL_COMPARE_GREATEEQUAL 3
    255. #define MOBILE_STENCIL_COMPARE_EQUAL 4
    256. #define MOBILE_STENCIL_COMPARE_NOTEQUAL 5
    257. #define MOBILE_STENCIL_COMPARE_NEVER 6
    258. #define MOBILE_STENCIL_COMPARE_ALWAYS 7
    259. #ifndef MOBILE_STENCIL_COMPARE_FUNCTION
    260. #define MOBILE_STENCIL_COMPARE_FUNCTION MOBILE_STENCIL_COMPARE_NEVER
    261. #endif
    262. void MainPS(
    263. in FPostProcessMaterialVSToPS Input,
    264. out half4 OutColor : SV_Target0
    265. )
    266. {
    267. ResolvedView = ResolveView();
    268. FMaterialPixelParameters Parameters = MakeInitializedMaterialPixelParameters();
    269. FPixelMaterialInputs PixelMaterialInputs;
    270. // can be optimized
    271. float4 SvPosition = Input.Position;
    272. if (bFlipYAxis)
    273. {
    274. SvPosition.y = PostProcessOutput_ViewportSize.y - SvPosition.y;
    275. }
    276. float2 ViewportUV = (SvPosition - PostProcessOutput_ViewportMin) * PostProcessOutput_ViewportSizeInverse;
    277. float2 BufferUV = ViewportUVToBufferUV(ViewportUV);
    278. #if NUM_TEX_COORD_INTERPOLATORS
    279. UNROLL
    280. for (int CoordinateIndex = 0; CoordinateIndex < NUM_MATERIAL_TEXCOORDS; CoordinateIndex++)
    281. {
    282. #if POST_PROCESS_AR_PASSTHROUGH
    283. Parameters.TexCoords[CoordinateIndex] = GetUV(Input, CoordinateIndex);
    284. #else
    285. Parameters.TexCoords[CoordinateIndex] = ViewportUV;
    286. #endif
    287. }
    288. UNROLL
    289. for (int CoordinateIndex = NUM_MATERIAL_TEXCOORDS; CoordinateIndex < NUM_TEX_COORD_INTERPOLATORS; CoordinateIndex++)
    290. {
    291. Parameters.TexCoords[CoordinateIndex] = GetUV(Input, CoordinateIndex);
    292. }
    293. #endif
    294. Parameters.VertexColor = 1;
    295. float ClipValue = 1.0f;
    296. #if MOBILE_STENCIL_COMPARE_FUNCTION != MOBILE_STENCIL_COMPARE_NEVER && MOBILE_STENCIL_COMPARE_FUNCTION != MOBILE_STENCIL_COMPARE_ALWAYS
    297. int MobileStencilValue = floor(Texture2DSample(MobileCustomStencilTexture, MobileCustomStencilTextureSampler, BufferUV).r*255.0f + 0.5f);
    298. #endif
    299. #if MOBILE_STENCIL_COMPARE_FUNCTION == MOBILE_STENCIL_COMPARE_LESS
    300. ClipValue = MobileStencilValueRef < MobileStencilValue ? 1.0f : -1.0f;
    301. #elif MOBILE_STENCIL_COMPARE_FUNCTION == MOBILE_STENCIL_COMPARE_LESSEQUAL
    302. ClipValue = MobileStencilValueRef <= MobileStencilValue ? 1.0f : -1.0f;
    303. #elif MOBILE_STENCIL_COMPARE_FUNCTION == MOBILE_STENCIL_COMPARE_GREATE
    304. ClipValue = MobileStencilValueRef > MobileStencilValue ? 1.0f : -1.0f;
    305. #elif MOBILE_STENCIL_COMPARE_FUNCTION == MOBILE_STENCIL_COMPARE_GREATEEQUAL
    306. ClipValue = MobileStencilValueRef >= MobileStencilValue ? 1.0f : -1.0f;
    307. #elif MOBILE_STENCIL_COMPARE_FUNCTION == MOBILE_STENCIL_COMPARE_EQUAL
    308. ClipValue = MobileStencilValueRef == MobileStencilValue ? 1.0f : -1.0f;
    309. #elif MOBILE_STENCIL_COMPARE_FUNCTION == MOBILE_STENCIL_COMPARE_NOTEQUAL
    310. ClipValue = MobileStencilValueRef != MobileStencilValue ? 1.0f : -1.0f;
    311. #elif MOBILE_STENCIL_COMPARE_FUNCTION == MOBILE_STENCIL_COMPARE_NEVER
    312. #elif MOBILE_STENCIL_COMPARE_FUNCTION == MOBILE_STENCIL_COMPARE_ALWAYS
    313. ClipValue = MobileStencilValueRef == 256 ? 1.0f : -1.0f;
    314. #endif
    315. #if MOBILE_STENCIL_COMPARE_FUNCTION != MOBILE_STENCIL_COMPARE_NEVER
    316. clip(ClipValue);
    317. #endif
    318. float DeviceZ = LookupDeviceZ(BufferUV);
    319. SvPosition.z = DeviceZ;
    320. SvPosition.z = max(SvPosition.z, 1e-18);
    321. // fill out other related material parameters
    322. CalcMaterialParametersPost(Parameters, PixelMaterialInputs, SvPosition, true);
    323. // Grab emissive colour as output
    324. half3 EmissiveColor = GetMaterialEmissive(PixelMaterialInputs);
    325. #if MATERIAL_OUTPUT_OPACITY_AS_ALPHA
    326. half Alpha = GetMaterialOpacity(PixelMaterialInputs);
    327. #else
    328. half Alpha = Parameters.BackupSceneColorAlpha;
    329. #endif
    330. half4 FullSceneColor = half4(EmissiveColor, Alpha);
    331. #if POST_PROCESS_MATERIAL_BEFORE_TONEMAP
    332. #if OUTPUT_GAMMA_SPACE
    333. FullSceneColor.rgb = sqrt(FullSceneColor.rgb);
    334. #endif
    335. #if !MATERIALBLENDING_MODULATE && USE_PREEXPOSURE
    336. FullSceneColor.xyz *= View.PreExposure;
    337. #endif
    338. #endif
    339. OutColor = FullSceneColor;
    340. }
    341. #endif //(FEATURE_LEVEL > FEATURE_LEVEL_ES3_1)

  • 相关阅读:
    使用kubectl连接远程Kubernetes(k8s)集群
    【云原生之k8s】kubernetes核心组件
    诚迈科技发布OpenHarmony发行版鸿诚志远HongZOS
    慕思股份深交所上市:靠床垫和“洋老头”走红 市值224亿
    初学者必备——三大类18条Java正则表达式语法
    基于MATLAB的BP神经网络太阳辐射预测
    Python测试框架 Pytest —— mock使用(pytest-mock)
    Lock锁以及解决生产者消费者的方案
    智慧城市与数字孪生:实现城市可持续发展的关键
    IAB视频广告标准《数字视频和有线电视广告格式指南》之 概述- IAB受众和技术标准 - 我为什么要翻译介绍美国人工智能科技公司IAB系列(2)
  • 原文地址:https://blog.csdn.net/sh15285118586/article/details/127036430