# Custom Depth for opaque material

**URL:** <https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594>\
**Category:** Rendering\
**Tags:** Render, custom-depth, unreal-engine, UE4, Blueprint, question\
**Created:** [March 11, 2017, 8:08am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594 "2017-03-11T08:08:06Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![gardenlee\_27](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@gardenlee\_27](https://forums.unrealengine.com/u/gardenlee_27)\
**Post date:** [March 11, 2017, 8:08am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/1 "2017-03-11T08:08:06Z")

</div>

Hey guys,

I am trying to use unrealAR plugin to develop sth. I want to achieve the occlusion between real and virtual objects. One viable way is to pre-render the mesh of real objects into depth buffer and then render the virtual objects which should pass that depth buffer. I ve tried CustomDepth but it does not available for opaque material.

I achieved following effect. I want to know how to give the chair an opaque material instead of translucent. Any idea?

 ![129530-qq截图20170311160540.png](https://d3kjluh73b9h9o.cloudfront.net/original/4X/a/b/7/ab72cee099ff01d350e014bd6bb46b4553c60cdc.png)

 ![129541-qq截图20170311160349.png](https://d3kjluh73b9h9o.cloudfront.net/original/4X/e/d/f/edf8c05595099489aafe937910a571604c6b2559.png)

Another viable optioin is to control what part of the object should be rendered. Is that possible?

---

<div class="post-metadata">

**Author:** ![anonymous\_user\_fbe2d247](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@anonymous\_user\_fbe2d247](https://forums.unrealengine.com/u/anonymous_user_fbe2d247)\
**Post date:** [March 12, 2018, 2:47pm UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/2 "2018-03-12T14:47:41Z")

</div>

We really need this too. There should’t be any technical reasons to not to allow this. Custom depth is totally separate rendering pass so there isn’t any dependencies. Seems that only reason is that CustomDepth is under the scene texture which can be used for scene color and other buffers that are only available after basepass.

---

<div class="post-metadata">

**Author:** ![Deathrey](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Deathrey](https://forums.unrealengine.com/u/Deathrey)\
**Post date:** [March 13, 2018, 7:37am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/3 "2018-03-13T07:37:16Z")

</div>

I don’t see any reason either why you would not be able to read custom depth in material, that is not writing to it. Should be fixed.

---

<div class="post-metadata">

**Author:** ![Chosker](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/chosker/32/710746_2.png) [@Chosker](https://forums.unrealengine.com/u/Chosker)\
**Post date:** [April 18, 2018, 8:36pm UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/4 "2018-04-18T20:36:53Z")

</div>

+1 to this!

---

<div class="post-metadata">

**Author:** ![Ibprofen98](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Ibprofen98](https://forums.unrealengine.com/u/Ibprofen98)\
**Post date:** [March 7, 2022, 6:06am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/5 "2022-03-07T06:06:36Z")

</div>

Same, this would solve my problem so easily. Is there a way to force it?

---

<div class="post-metadata">

**Author:** ![NeoWang9999](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/neowang9999/32/88706_2.png) [@NeoWang9999](https://forums.unrealengine.com/u/NeoWang9999)\
**Post date:** [July 12, 2022, 5:35am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/6 "2022-07-12T05:35:35Z")

</div>

does it fixed now in 2022?

---

<div class="post-metadata">

**Author:** ![SlavaDev](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@SlavaDev](https://forums.unrealengine.com/u/SlavaDev)\
**Post date:** [January 12, 2023, 2:14am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/7 "2023-01-12T02:14:48Z")

</div>

Any updates?

---

<div class="post-metadata">

**Author:** ![Azad\_N](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Azad\_N](https://forums.unrealengine.com/u/Azad_N)\
**Post date:** [July 30, 2023, 9:28am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/9 "2023-07-30T09:28:20Z")

</div>

Here you can use vertex distance from camera to create a depth map

 ![image](https://d3kjluh73b9h9o.cloudfront.net/original/4X/e/b/d/ebd4ef3703c2e45f9096899a0df814acb7024cb1.png)  
If you want to mask a whole object better use distance from camera per object like so  
 ![image](https://d3kjluh73b9h9o.cloudfront.net/original/4X/c/8/f/c8f3c5fded8cd8c2b6e1593a22deb1c7ceb72426.png)

---

<div class="post-metadata">

**Author:** ![Seedonator](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/seedonator/32/480464_2.png) [@Seedonator](https://forums.unrealengine.com/u/Seedonator)\
**Post date:** [February 3, 2025, 10:13am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/10 "2025-02-03T10:13:34Z")

</div>

Really need this as well

---

<div class="post-metadata">

**Author:** ![BananableOffense](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@BananableOffense](https://forums.unrealengine.com/u/BananableOffense)\
**Post date:** [February 3, 2025, 3:44pm UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/11 "2025-02-03T15:44:21Z")

</div>

There is sort of a janky way to do this using decals. The custom depth can be read by a decal material, and the decal can be read by the opaque material with the dbuffer node.

---

<div class="post-metadata">

**Author:** ![Seedonator](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/seedonator/32/480464_2.png) [@Seedonator](https://forums.unrealengine.com/u/Seedonator)\
**Post date:** [February 4, 2025, 5:12am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/12 "2025-02-04T05:12:32Z")

</div>

Okay can confirm this works, kinda ridiculous but it’ll have to do for now. Cheers

---

<div class="post-metadata">

**Author:** ![StapledBattery](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@StapledBattery](https://forums.unrealengine.com/u/StapledBattery)\
**Post date:** [January 28, 2026, 8:46pm UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/13 "2026-01-28T20:46:07Z")

</div>

Supporting this is only a few lines of code change to the engine if you are building it from source.

> **Patch file**
>
> To apply the patch, copy it to a file (e.g. `opaquestencil.patch`) then run `git apply opaquestencil.patch` in the engine source tree.
> 
> ```cpp
> Engine/Shaders/Private/BasePassPixelShader.usf | 5 +++++
> Engine/Shaders/Private/BasePassVertexCommon.ush | 2 ++
> .../Engine/Private/Materials/HLSLMaterialTranslator.cpp | 2 +-
> .../Source/Runtime/Renderer/Private/BasePassRendering.cpp | 1 +
> Engine/Source/Runtime/Renderer/Private/BasePassRendering.h | 1 +
> .../Runtime/Renderer/Private/CustomDepthRendering.cpp | 6 +++---
> 6 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/Engine/Shaders/Private/BasePassPixelShader.usf b/Engine/Shaders/Private/BasePassPixelShader.usf
> index f9fa4da66ed3..405eadecaf50 100644
> --- a/Engine/Shaders/Private/BasePassPixelShader.usf
> +++ b/Engine/Shaders/Private/BasePassPixelShader.usf
> @@ -42,6 +42,11 @@
> #define SubstrateStruct OpaqueBasePass.Substrate
> #define LightFunctionAtlasStruct OpaqueBasePass.Shared.LightFunctionAtlas
>  
> +	#if MATERIALBLENDING_SOLID || MATERIALBLENDING_MASKED
> + #define SceneTexturesStruct OpaqueBasePass.SceneTextures
> +
> +	#endif // MATERIALBLENDING_SOLID
> +
> // Material setting to allow forward shading (including mobile) to use preintegrated GF lut for simple IBL.
> #if MATERIAL_SHADINGMODEL_SINGLELAYERWATER || (FORWARD_SHADING && MATERIAL_USE_PREINTEGRATED_GF)
> #define PreIntegratedGF OpaqueBasePass.PreIntegratedGFTexture
> diff --git a/Engine/Shaders/Private/BasePassVertexCommon.ush b/Engine/Shaders/Private/BasePassVertexCommon.ush
> index 603848cbac15..18b8509660b9 100644
> --- a/Engine/Shaders/Private/BasePassVertexCommon.ush
> +++ b/Engine/Shaders/Private/BasePassVertexCommon.ush
> @@ -10,6 +10,8 @@
> // Reroute SceneTexturesStruct uniform buffer references to the appropriate base pass uniform buffer
> #if MATERIALBLENDING_TRANSLUCENT || MATERIALBLENDING_ADDITIVE || MATERIALBLENDING_MODULATE
> #define SceneTexturesStruct TranslucentBasePass.SceneTextures
> +#elif MATERIALBLENDING_SOLID || MATERIALBLENDING_MASKED
> +	#define SceneTexturesStruct OpaqueBasePass.SceneTextures
> #endif 
>  
> #include "/Engine/Generated/Material.ush"
> diff --git a/Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp b/Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp
> index d1aa3ee53aa9..f00f28e1351a 100644
> --- a/Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp
> +++ b/Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp
> @@ -2005,7 +2005,7 @@ void FHLSLMaterialTranslator::TranslateMaterial()
> if (!MaterialShadingModels.HasShadingModel(MSM_SingleLayerWater) && IsOpaqueOrMaskedBlendMode(BlendMode))
> {
> // In opaque pass, none of the textures are available
> - Errorf(TEXT("SceneTexture expressions cannot be used in opaque materials except if used with the Single Layer Water shading model."));
> + //Errorf(TEXT("SceneTexture expressions cannot be used in opaque materials except if used with the Single Layer Water shading model."));
> }
> else if (bNeedsSceneTexturePostProcessInputs)
> {
> diff --git a/Engine/Source/Runtime/Renderer/Private/BasePassRendering.cpp b/Engine/Source/Runtime/Renderer/Private/BasePassRendering.cpp
> index bad99bd5f5bb..069795137021 100644
> --- a/Engine/Source/Runtime/Renderer/Private/BasePassRendering.cpp
> +++ b/Engine/Source/Runtime/Renderer/Private/BasePassRendering.cpp
> @@ -820,6 +820,7 @@ TRDGUniformBufferRef<FOpaqueBasePassUniformParameters> CreateOpaqueBasePassUnifo
> {
> FOpaqueBasePassUniformParameters& BasePassParameters = *GraphBuilder.AllocParameters<FOpaqueBasePassUniformParameters>();
> SetupSharedBasePassParameters(GraphBuilder, View, ViewIndex, bLumenGIEnabled, BasePassParameters.Shared);
> +	SetupSceneTextureUniformParameters(GraphBuilder, View.GetSceneTexturesChecked(), View.FeatureLevel, ESceneTextureSetupMode::CustomDepth, BasePassParameters.SceneTextures);
>  
> const FRDGSystemTextures& SystemTextures = FRDGSystemTextures::Get(GraphBuilder);
>  
> diff --git a/Engine/Source/Runtime/Renderer/Private/BasePassRendering.h b/Engine/Source/Runtime/Renderer/Private/BasePassRendering.h
> index cb560f0f00db..29d796d5c62d 100644
> --- a/Engine/Source/Runtime/Renderer/Private/BasePassRendering.h
> +++ b/Engine/Source/Runtime/Renderer/Private/BasePassRendering.h
> @@ -89,6 +89,7 @@ END_GLOBAL_SHADER_PARAMETER_STRUCT()
>  
> BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FOpaqueBasePassUniformParameters,)
> SHADER_PARAMETER_STRUCT(FSharedBasePassUniformParameters, Shared)
> +	SHADER_PARAMETER_STRUCT(FSceneTextureUniformParameters, SceneTextures)
> SHADER_PARAMETER_STRUCT(FSubstrateBasePassUniformParameters, Substrate)
> // Forward shading 
> SHADER_PARAMETER(int32, UseForwardScreenSpaceShadowMask)
> diff --git a/Engine/Source/Runtime/Renderer/Private/CustomDepthRendering.cpp b/Engine/Source/Runtime/Renderer/Private/CustomDepthRendering.cpp
> index 334db63787be..2d58e689f57b 100644
> --- a/Engine/Source/Runtime/Renderer/Private/CustomDepthRendering.cpp
> +++ b/Engine/Source/Runtime/Renderer/Private/CustomDepthRendering.cpp
> @@ -14,11 +14,11 @@
>  
> static TAutoConsoleVariable<int32> CVarCustomDepthOrder(
> TEXT("r.CustomDepth.Order"),
> -	2,
> +	0,
> TEXT("When CustomDepth (and CustomStencil) is getting rendered\n")
> -	TEXT(" 0: Before Base Pass (Allows samping in DBuffer pass. Can be more efficient with AsyncCompute.)\n")
> +	TEXT(" 0: Default. Before Base Pass (Allows samping in DBuffer pass. Can be more efficient with AsyncCompute.)\n")
> TEXT(" 1: After Base Pass\n")
> -	TEXT(" 2: Default (Before Base Pass if DBuffer enabled.)\n"),
> +	TEXT(" 2: Before Base Pass if DBuffer enabled.\n"),
> ECVF_RenderThreadSafe);
>  
> static TAutoConsoleVariable<int32> CVarCustomDepthTemporalAAJitter(
> 
> ```

Caveats:

- I have only tested this with the desktop forward renderer, although there’s no particular reason it shouldn’t work with the deferred renderer and with nanite.
- If you try and use SceneTextures other than CustomDepth and CustomStencil from your opaque material, you won’t get an error message anymore. They just won’t work.

---

<div class="post-metadata">

**Author:** ![Seedonator](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/seedonator/32/480464_2.png) [@Seedonator](https://forums.unrealengine.com/u/Seedonator)\
**Post date:** [August 27, 2026, 5:55am UTC](https://forums.unrealengine.com/t/custom-depth-for-opaque-material/387594/14 "2026-08-27T05:55:13Z")

</div>

Heya, just chiming in to confirm that this does indeed work on the deferred renderer, thanks for sharing \<3
