TL;DR: How to blit from RenderTexture asset onto screen using RTHandle API?
I’m making a pixel art game.
-
The camera renders to a lo-res RenderTexture.
-
A custom render pass applies a post-processing material.
-
The same custom render pass blits the processed texture to the screen.
In older versions of URP, I wrote this:
// src is the lo-res RenderTexture.
// dest is the camera's color target.
Blit(src, dest, material);
I have tried converting this to the new APIs.
// In the feature file:
public override void SetupRenderPasses(ScriptableRenderer renderer, in RenderingData renderingData)
{
_retroDrawPass.ConfigureInput(ScriptableRenderPassInput.Color);
_retroDrawPass.SetTarget(renderer.cameraColorTargetHandle, drawSettings.src);
}
// In the pass file:
public void SetTarget(RTHandle colorHandle, RenderTexture src)
{
// These are both of type RTHandle.
_colorTarget = colorHandle;
_srcTarget = RTHandles.Alloc(src);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
// After setup and profiling...
Blitter.BlitCameraTexture(cmd, _srcTarget, _colorTarget, _passSettings.postMat, 0);
}
This results in three errors.
[Error] Assertion failed
// The assertion is this: Debug.Assert(handle.m_ExternalTexture != null || handle.rt != null);
// It fails when checking _srcTarget. However, logging _srcTarget.rt == null immediately before blitting prints "False."
[Error] ArgumentNullException: Value cannot be null.
// Once again, this is _srcTarget. See above.
[Warning] Render Pipeline error : the XR layout still contains active passes. Executing XRSystem.EndLayout() right now.
// This is not an XR game, and I am not using any XR features. I don't quite understand this one.
I am probably using RTHandles incorrectly. I have combed through documentation to no avail. Some more details:
- I have tried calling ConfigureTarget for _colorTarget as well as for both _colorTarget and _srcTarget. No difference.
- I get the same errors when writing
Blitter.BlitCameraTexture(cmd, _colorTarget, _colorTarget, _passSettings.postMat, 0);
. This suggests that it has nothing to do with _srcTarget. - These errors also appear when running Unity’s example pass.
- This is the closest I’ve come to success:
Blitter.BlitCameraTexture(cmd, _srcTarget, _srcTarget, _passSettings.postMat, 0);
Blitter.BlitCameraTexture(cmd, _srcTarget, _colorTarget);
This results in the image being drawn to the screen. The material is not applied.
Please advise – I have probably made an obvious mistake.