HDRP OnRenderImage

Hi, (Unity 2021.2.16f1 & HDRP 12.1.6)

I am trying to convert the following built-in code to HDRP.
The idea is to display the camera render on a mesh to distort the render.

void OnRenderImage(RenderTexture source, RenderTexture destination)
{
        _material.SetTexture("_MainTex", source);
        _material.SetPass(0);

            RenderTexture previousTex = RenderTexture.active;
            RenderTexture.active = _RT;
            GL.PushMatrix();
            GL.LoadPixelMatrix(0.0f, 1.0f, 0.0f, 1.0f);
            Graphics.DrawMeshNow(_gridMesh, _gridMeshGO.transform.localToWorldMatrix);
            GL.PopMatrix();
            RenderTexture.active = previousTex;
}

So far I have:

Then I have two issues:

1/ In the Execute method of the Custom Pass I have:

_material.SetTexture("_ColorMap", ctx.cameraColorBuffer);

Which makes me need to modify the template shader so that the _ColorMap is a 2DArray:

_ColorMap("ColorMap", 2DArray) = "white" {}
TEXTURE2D(_ColorMap);

I only get a white texture, as if the colormap is not assigned.
I tried to use TEXTURE2D_X instead which seems to be the correct function to be able to sample 2DArrays,
but it is not defined in Custom Renderers Pass shaders, only in Full screen shader (which I don’t think is what I want to use).

I tried to include CustomPassCommon.hlsl but then I get errors like : redefinition of ‘_CustomPassInjectionPoint’

How can I fix this ?

2/ Currently I am using

ctx.cmd.DrawMesh(_script._gridMesh, _script._gridMeshGO.transform.localToWorldMatrix, _Material);

to draw my mesh, but of course it is rendered using the current perspective camera.

In the built-in pipeline I used GL.LoadPixelMatrix(0.0f, 1.0f, 0.0f, 1.0f);

To get around this I tried created an ortho camera and use CustomPassUtils.RenderFromCamera
The rendering works correctly but now I see that the effect of an ortho projection is not the same as the LoadPixelMatrix

How can I replicate this in HDRP ?
Thanks in advance!

Hi Seb :slight_smile:

As you correctly noticed,
the color buffer of the camera may be a texture array, which is not anticipated by the renderer pass shader template. Indeed, to be resilient to this possibility, you should use TEXTURE2D_X .

That macro is defined in com.unity.render-pipelines.high-definition\Runtime\ShaderLibrary\TextureXR.hlsl so you can probably include that directly. In general files like CustomPassCommon.hlsl will expose you things through their own includes so it’s always a possibility to cut the middleman and include the relevant file directly.

Your use case is a bit atypical, so it’s probably better not to lean on HDRP utilities and write the commands directly. Like using CommandBuffer.SetViewport, CommandBuffer.SetViewProjectionMatrices and CommandBuffer.DrawMesh.

com.unity.render-pipelines.core\Runtime\Utilities\CoreUtils.cs and com.unity.render-pipelines.high-definition\Runtime\RenderPipeline\Utility\HDUtils.cs contain a lot of useful rendering utilities, but I would use them for reference only in this case.

Note that when doing full screen rendering, vertices usually aren’t transformed using the view and projection matrices, they directly have the final desired value. You can probably setup your mesh in this way. however as mentioned above you can also set your view and projection using the command buffer.

It’s totally OK to also modify the vertex shader. In the template it comes from com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForwardUnlit.hlsl. You could copy/paste/modify it if needed. In general that process of copy/paste/modify is not an anti pattern when one needs to step outside of the most anticipated use cases.