Reputation: 55
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
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
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