Skip to content

Game.UI.Thumbnails.ThumbnailCustomPass

Assembly:
Assembly-CSharp.dll

Namespace:
Game.UI.Thumbnails

Type:
public class ThumbnailCustomPass

Base:
UnityEngine.Rendering.HighDefinition.CustomPass

Summary:
A custom HDRP rendering pass used to render small thumbnail previews of scene objects into an off-screen color+depth buffer. The pass restricts rendering by a LayerMask (m_ThumbnailLayer) and uses a RendererList with specific ShaderTagIds (Forward, ForwardOnly, SRPDefaultUnlit). It allocates and manages RTHandle-backed render targets (color + depth), temporarily disables an "INFOVIEW_ON" shader keyword while rendering, and restores the previous global state after drawing. Designed for use in Cities: Skylines 2 UI thumbnail generation where a compact, correctly depth-tested offscreen render is required.


Fields

  • public LayerMask m_ThumbnailLayer = 0
    Layer mask used to filter which objects are drawn into the thumbnail. Set this to the layer(s) containing the objects you want to capture.

  • private ShaderTagId[] m_ShaderTags
    Array of shader tag identifiers used to build the RendererList. Initialized in Setup to include "Forward", "ForwardOnly" and "SRPDefaultUnlit" so that typical lit and unlit shaders are considered.

  • private RTHandle m_ThumbnailBuffer
    RTHandle for the color buffer. Backed by an HDRP RTHandle wrapper; allocate with AllocateRTHandles(width, height) before use. The actual RenderTexture can be accessed via GetBuffer().

  • private RTHandle m_ThumbnailDepthBuffer
    RTHandle for the depth buffer. Allocated alongside the color buffer. Uses a 16-bit depth format in the current implementation.

  • private bool m_CanRender
    Flag indicating whether render targets are allocated and the pass is ready to execute. Set to true by AllocateRTHandles, and false by Release/Cleanup.

Properties

  • (none)

Constructors

  • public ThumbnailCustomPass()
    No explicit constructor is defined in the source; default parameterless constructor is used. Initialization dependent on HDRP lifecycle methods (Setup/Execute/Cleanup). Ensure AllocateRTHandles is called before expecting RenderTexture output.

Methods

  • protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
    Initializes shader tag list used to create RendererListDesc. This is called once by HDRP when the custom pass is created. It sets up m_ShaderTags to include "Forward", "ForwardOnly", and "SRPDefaultUnlit".

Notes: - Do not attempt to access RTHandles here — allocation is handled explicitly via AllocateRTHandles. - Called on the render thread by HDRP as part of pass lifecycle.

  • public void AllocateRTHandles(int width, int height)
    Allocates or re-allocates the color and depth RTHandles used for thumbnail rendering. Behavior:
  • If existing RTHandles exist but have different dimensions, they are released and re-created.
  • Color RTHandle uses GraphicsFormat.R8G8B8A8_UNorm and is created with point filtering, automatic mip generation disabled (autoGenerateMips: true flagged in call but useMipMap: false), dynamic scaling enabled.
  • Depth RTHandle uses GraphicsFormat.R16_UInt with Depth16.
  • Sets m_CanRender = true when allocation is complete.

Important: - Call this with the desired thumbnail resolution before expecting the pass to render. - Be mindful of memory usage; choose compact sizes (thumbnails usually small). - The code calls QualitySettings.GetRenderPipelineAssetAt(...) — this can be a NO-OP in some contexts but is present in the shipped implementation.

  • protected override void Execute(CustomPassContext ctx)
    Primary render method invoked each frame by HDRP when the custom pass runs. If m_CanRender is true, it:
  • Builds a RendererListDesc configured with m_ShaderTags, ctx.cullingResults and ctx.hdCamera.camera.
  • Sets rendererConfiguration to include LightProbe, LightProbeProxyVolume and Lightmaps per-object data.
  • Uses RenderQueueRange.all and sorts BackToFront (suitable for transparent geometry).
  • Applies a layerMask = m_ThumbnailLayer to limit rendered objects.
  • Sets a depth state (write enabled, CompareFunction.LessEqual) in a RenderStateBlock for correct depth testing.
  • Temporarily disables the "INFOVIEW_ON" keyword and sets global int "colossal_InfoviewOn" to 0 to avoid infoview overlays in thumbnails; it stores and restores the previous global int value afterwards.
  • Sets the render target to the allocated color+depth RTHandles (clearing both) and draws the RendererList via CoreUtils.DrawRendererList.

Notes and cautions: - The pass uses SortingCriteria.BackToFront — if you want opaque-only rendering change renderQueueRange and sorting accordingly. - The code assumes m_ThumbnailBuffer and m_ThumbnailDepthBuffer are valid RTHandles when m_CanRender is true. - Global shader state is modified briefly; the previous int value is restored, but be careful about multithreaded or nested pass interactions.

  • public RenderTexture GetBuffer()
    Returns the underlying RenderTexture of the color RTHandle: m_ThumbnailBuffer.rt. Use this to sample or blit the thumbnail into UI textures or encode to PNG, etc.

Notes: - Ensure AllocateRTHandles has been called and the RTHandle is still valid (not released). - The returned RenderTexture is owned by the RTHandle system — do not Release() it directly; call Release() on the ThumbnailCustomPass when done.

  • public void Release()
    Releases both color and depth RTHandles if they exist and sets m_CanRender to false. Should be called when the pass no longer needs to render thumbnails (for example on UI teardown or quality changes).

  • protected override void Cleanup()
    HDRP lifecycle cleanup; calls Release() to free RTHandles and disable further rendering.

Usage Example

// Example usage inside a MonoBehaviour that sets up the pass and requests a thumbnail.
public class ThumbnailController : MonoBehaviour
{
    public ThumbnailCustomPass thumbnailPass;
    public int thumbWidth = 256;
    public int thumbHeight = 256;
    public LayerMask thumbnailLayer;

    void Start()
    {
        if (thumbnailPass == null)
            return;

        // Configure the target layer(s) and allocate buffers
        thumbnailPass.m_ThumbnailLayer = thumbnailLayer;
        thumbnailPass.AllocateRTHandles(thumbWidth, thumbHeight);

        // The custom pass will be executed by HDRP as part of the pipeline.
        // After a frame, get the RenderTexture:
        // RenderTexture tex = thumbnailPass.GetBuffer();
        // Use Graphics.Blit or read pixels to a Texture2D as needed.
    }

    void OnDestroy()
    {
        // Ensure resources are freed
        if (thumbnailPass != null)
            thumbnailPass.Release();
    }
}

Additional tips: - Call AllocateRTHandles again if you need a different thumbnail size (it will reallocate if dimensions differ). - Prefer small thumbnail sizes to reduce memory and GPU cost; release when not needed. - If you need opaque-only thumbnails, modify rendererListDesc.renderQueueRange to only opaque queues and adjust sorting. - When integrating into Cities: Skylines 2, ensure HDRP custom passes are registered and the CustomPass volume/configuration includes this pass so HDRP will call Setup/Execute/Cleanup.