Mher Didaryan
Mher Didaryan

Reputation: 55

How to export FTexture2DRHIRef to png?

As Unreal Engine documentation mentions here documentation

Textures are images that are used in Materials.They are mapped to the surfaces the Material is applied to.

Is there a reverse option, a way to export textures to file (.png for example)? Suppose we have FTexture2DRHIRef texture, how can we get the raw data of texture and save it in file?

Also there are too many kind of texture classes in Unreal Engine UTexture2D, FRHITexture2D and some more. Where can I find a detailed explanation about textures and their differences in Unreal Engine?

Upvotes: 1

Views: 4739

Answers (2)

user1974194
user1974194

Reputation: 51

First, you need to get UTexture from FTexture2DRHIRef. I use this code to create texture from a current game viewport:

 void UScenarioBP_Library::CopyViewportToRenderTarget(UObject* WorldRef, UTextureRenderTarget2D* RenderTarget)
{
    UGameViewportClient* ViewportClient = WorldRef->GetWorld()->GetGameViewport();
    FSceneViewport* Viewport = ViewportClient->GetGameViewport();
    FTexture2DRHIRef Texture = Viewport->GetRenderTargetTexture();
    FRHITexture2D* TextureRHI = Texture->GetTexture2D();

    ENQUEUE_RENDER_COMMAND(ReadSurfaceCommand)(
        [Texture, RenderTarget](FRHICommandListImmediate& RHICmdList)
    {
        FTexture2DRHIRef destTexture = RenderTarget->GetRenderTargetResource()->GetRenderTargetTexture();
        FResolveParams param;
        RHICmdList.CopyToResolveTarget(Texture, destTexture, param);
    });
}

Upvotes: 0

yzz
yzz

Reputation: 148

Of course it is the option to save texture to file, but first of all you need to know what is the difference between RHI structs and UTexture objects.

Rendering Hardware Interface (RHI) is a high-level platform independent rendering code. It provides an API for low-level platform-dependent parts of the engine / renderer.

I am not sure, how to properly define UTexture, but in general there are objects used in a game, editor code, materials, etc. They have got references for RHI structs.

And in answer to your question, to save texture to a file you should use one of the methods from FFileHelper structure, i.e. SaveArrayToFile, as input you need to have raw texture data (or compressed bitmap FImageUtils::CompressImageArray) and probably this is another problem. Some kind of textures (like RenderTargets) has methods ReadPixels, which returns an array of pixels, but what to do when your texture has not that method?

You need to dig deep into RHI API and enqueue some renderer commands, for example:

void GetTexturePixels(FTexture2DRHIRef Texture, TArray<FColor>& OutPixels)
{
    struct FReadSurfaceContext
    {
        FTexture2DRHIRef Texture;
        TArray<FColor>* OutData;
        FIntRect Rect;
        FReadSurfaceDataFlags Flags;
    };

    OutPixels.Reset();
    FReadSurfaceContext ReadSurfaceContext =
    {
        Texture,
        &OutPixels,
        FIntRect(0, 0, Texture->GetSizeXY().X, Texture->GetSizeXY().Y),
        FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX)
    };

    ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
        ReadSurfaceCommand,
        FReadSurfaceContext, Context, ReadSurfaceContext,
        {
            RHICmdList.ReadSurfaceData(
                Context.Texture,
                Context.Rect,
                *Context.OutData,
                Context.Flags
            );
        });
    FlushRenderingCommands();
}

Upvotes: 3

Related Questions