【问题标题】:How to export FTexture2DRHIRef to png?如何将 FTexture2DRHIRef 导出为 png?
【发布时间】:2017-07-21 13:35:54
【问题描述】:

正如虚幻引擎文档在这里提到的documentation

纹理是在材质中使用的图像。它们被映射到 材质应用到的表面。

是否有反向选项,一种将纹理导出到文件(例如.png)的方法?假设我们有FTexture2DRHIRef texture,我们如何获取纹理的原始数据并将其保存在文件中?

虚幻引擎UTexture2DFRHITexture2D 等还有太多的纹理类。在哪里可以找到有关虚幻引擎中纹理及其差异的详细说明?

【问题讨论】:

    标签: c++ textures unreal-engine4


    【解决方案1】:

    当然可以选择将纹理保存到文件,但首先你需要知道RHI 结构和UTexture 对象之间的区别。

    渲染硬件接口 (RHI) 是一个独立于平台的高级渲染代码。它为引擎/渲染器的低级平台相关部分提供 API。

    我不确定,如何正确定义UTexture,但一般来说,游戏中使用的对象、编辑器代码、材质等。他们有RHI结构的引用。

    为了回答您的问题,要将纹理保存到文件中,您应该使用FFileHelper 结构中的一种方法,即SaveArrayToFile,作为输入,您需要拥有原始纹理数据(或压缩位图FImageUtils::CompressImageArray ),这可能是另一个问题。某种纹理(如 RenderTargets)有方法 ReadPixels,它返回一个像素数组,但是当你的纹理没有那个方法时怎么办?

    您需要深入挖掘RHI API 并将一些渲染器命令排入队列,例如:

    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();
    }
    

    【讨论】:

    • OutPixels.Reset(); 有必要吗?为什么?
    • 我认为没有必要。可能所有方法的实现(我只检查了几个)在设置数据之前都会清除输出向量。
    【解决方案2】:

    首先,您需要从 FTexture2DRHIRef 获取 UTexture。我使用此代码从当前游戏视口创建纹理:

     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);
        });
    }
    

    【讨论】:

    • 这一步之后应该怎么做才能得到.png文件?
    猜你喜欢
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    相关资源
    最近更新 更多