Generating Mipmaps for Render Targets in UE4

Posted December 24th, 2020 in game-development

TLDR; use UTextureRenderTarget2D::UpdateResourceImmediate after updating your RT. Ensure you set bAutoGenerateMips to true on your render target instance.

When you create the RT, you pass it a UCanvasRenderTarget2D derived class; so you can blueprint this class and set bAutoGenerateMips on it in the editor, rather than doing this in code.

UClass* RenderTargetClass = UCanvasRenderTarget2D::StaticClass();

// Create the RT
UCanvasRenderTarget2D* RenderTarget = UCanvasRenderTarget2D::CreateCanvasRenderTarget2D(RenderTargetClass, 1024, 1024);

// Enable generation (if not enabled on RenderTargetClass)
RenderTarget.bAutoGenerateMips = true;

When updating the RT, you just need to call UpdateResourceImmediate. This method eventually calls down to FGenerateMips::Execute.

// Update the RT somehow

// Tell the engine it is updated and re-generate the mipmaps
RenderTarget->UpdateResourceImmediate(false);

Blueprints

I was not able to find an equivalent method exposed in Blueprints. The closest I could see was UpdateResource, but this also clears the RT so doesn't achieve the same effect.

It is trivial to expose this to Blueprints though, here's an example to put in your UBlueprintFunctionLibrary:

// MyGameplayStatics.h
UFUNCTION(BlueprintCallable, Category = RenderTexture)
static void UpdateResourceImmediate(class UTextureRenderTarget2D* RenderTarget, bool bClearRenderTarget);

// MyGameplayStatics.cpp
#include "Engine/TextureRenderTarget2D.h"

void UMyGameplayStatics::UpdateResourceImmediate(UTextureRenderTarget2D* RenderTarget, bool bClearRenderTarget)
{
   if (RenderTarget != nullptr)
   {
      RenderTarget->UpdateResourceImmediate(bClearRenderTarget);
   }
}

Platform Support

In terms of support, it looks like FGenerateMips uses a compute shader to generate the mipmaps, or if that is not supported by the RHI, the RHI itself. Therefore, I would assume that if that RHI can generate mipmaps, this will work.

It also looks like Epic attempted to deprecate mipmap generation in the RHI layer in 4.23, but then backed out of that since the deprecation notice is commented out as of 4.26. It probably means that they do want to get rid of it from the RHIs, but haven't removed all usages yet.

Performance

I haven't done any performance testing around how expensive generating mip-maps is, but I assume the compute shader is more efficient than the RHI path. In any case, it feels to me like this shouldn't be called every frame.

Comments