精選文章

SmallBurger Asset Home

  SmallBurger

2025年5月12日 星期一

Exploring Base Camera Overlay Rendering in Unity URP

Experienced users of URP should be aware that Camera Stacking is essential for handling camera overlay rendering. Rendering our UI in Screen Space — Overlay poses no issues whatsoever. However, if there’s a requirement to display icons or 3D text and you intend to render them using a separate camera, then Camera Stacking becomes indispensable.

However, the approach of Camera Stacking directs the rendering of this camera towards the RenderTarget of the MainCamera. When we scale down the RenderScale for performance reasons, it can result in the icons or text in our UI becoming blurry.


I believe a better approach is to directly set the camera in Camera Stacking as the rendering target of the FrameBuffer, rather than specifying it to a render texture. This is because essentially this camera doesn’t need to involve complex rendering processes. Additionally, this approach can reduce the need for an additional larger-sized render texture, thereby decreasing memory usage. So, how can we implement this?

Firstly, I carefully examined the underlying code of URP and discovered the IntermediateTexture property. It’s used to control whether URP always renders using render textures. We set it to Auto to allow URP the opportunity to render directly to the FrameBuffer.


Additionally, we need to turn off the OpaqueTexture and DepthTexture flags in the Rendering properties of the camera, and set HDR to Off. These properties will trigger URP to switch to render texture mode.


In addition, there is another property, which is the BackgroundType in the Environment. Here we set it to Uninitialized so that it won’t clear the rendering result of MainCamera’s FinalPass drawn into the FrameBuffer.


Finally, there is one crucial aspect: when rendering with the camera, RenderScale must be set to 1.0. Failure to do so will result in URP rendering to RenderTexture instead of FrameBuffer. Here, we have written a simple script to address this issue.

//...
private void OnBeginCameraRendering(ScriptableRenderContext context,
Camera camera)

{
if (cachedCamera == camera)
{
m_originalScaleRatio = UniversalRenderPipeline.asset.renderScale;
UniversalRenderPipeline.asset.renderScale = 1.0f;
}
}

//add by akilar
private void OnEndCameraRendering(ScriptableRenderContext context,
Camera camera)

{
if (cachedCamera == camera)
UniversalRenderPipeline.asset.renderScale = m_originalScaleRatio;
}
//...


Here you can find the corresponding GitHub repository:

FitRenderScaleURP

沒有留言:

張貼留言