当前位置:网站首页>Copytexture, copytoresolvetarget of UE4 engine
Copytexture, copytoresolvetarget of UE4 engine
2022-07-23 07:38:00 【Elder martial brother Dai Dai】
Preface
In various algorithms of graphics rendering , Especially for 2D Texture processing , There is often a situation , We need to copy part of one texture to another . As shown below :

UE4 Provides CopyTexture and CopyToResolveTarget To realize the similar function of copying a part of a texture to another texture .
CopyTexture
CopyTexture Basic introduction of

struct FRHICopyTextureInfo
{
// Number of texels to copy. By default it will copy the whole resource if no size is specified.
FIntVector Size = FIntVector::ZeroValue;
// Position of the copy from the source texture/to destination texture
FIntVector SourcePosition = FIntVector::ZeroValue;
FIntVector DestPosition = FIntVector::ZeroValue;
uint32 SourceSliceIndex = 0;
uint32 DestSliceIndex = 0;
uint32 NumSlices = 1;
// Mips to copy and destination mips
uint32 SourceMipIndex = 0;
uint32 DestMipIndex = 0;
uint32 NumMips = 1;
};CopyTexture Of SourceTextureRHI and DestTextureRHI Apply to UE4 Of UTexture2D, UTextureRenderTarget2D, UTexture2DArray And other texture types .
Copy texture parameters FRHICopyTextureInfo
FRHICopyTextureInfo It's about CopySrcTexture and CopyDestTexture Various setting parameters
Size: Copy the size of the texture part
SourcePosition:SrcTexture The starting position of the copy part
DestPosition:DestTexture The starting position of the copy part
SourceSliceIndex:SrcTexture Where the copied part is SrcTexture Array of texture arrays index( Ordinary texture is the array size 1 Texture array , Default SliceIndex be equal to 0)
DestSliceIndex:DestTexture Where the copied part is DestTexture Array of texture arrays index( Ordinary texture is the array size 1 Texture array , Default SliceIndex be equal to 0)
SourceMipIndex: SrcTexture The copied part is the current SrcTexture Which texture Mip level
DestMipIndex: DestMipIndex The copied part is the current DestMipIndex Which texture Mip level
NumMips: This time N level Mip A copy of the ( Usually , This is 1, Generally, only one level is copied at a time Mip)
summary : take SrcTexture The first of an array of SourceSliceIndex The first texture SourceMipIndexMip Class [SourcePosition, SourcePosition+Size] Copy the scope to DestTexture The first of an array of DestSliceIndex The first texture DestMipIndex Class [DestPosition, DestPosition+Size] Range
Example
Put a Texture Each level of Mip Copy the upper left quarter to one RenderTexture Corresponding Mip The upper left corner of level
UFUNCTION(BlueprintCallable, Category = "Test Shader", meta = (WorldContext = "WorldContextObject"))
static void CopyTextureToRenderTextureAllMips(
const UObject* WorldContextObject,
const UTexture2D* InTexture,
class UTextureRenderTarget2D* OutputRenderTarget);void UTestCopyRenderFunctionLibrary::CopyTextureToRenderTextureAllMips(
const UObject* WorldContextObject,
const UTexture2D* InTexture,
class UTextureRenderTarget2D* OutputRenderTargetA)
{
UWorld* World = WorldContextObject->GetWorld();
ERHIFeatureLevel::Type FeatureLevel = World->Scene->GetFeatureLevel();
if (FeatureLevel < ERHIFeatureLevel::SM5)
{
UE_LOG(LogTemp, Warning, TEXT("FeatureLevel < ERHIFeatureLevel::SM5"));
return;
}
if (nullptr == InTexture)
{
UE_LOG(LogTemp, Warning, TEXT("InTexture Is NULL"));
return;
}
FTextureRenderTargetResource* TextureRenderTargetSource = OutputRenderTargetA->GameThread_GetRenderTargetResource();
FTexture* TextureSource = InTexture->Resource;
int32 CommonMip = FMath::Min(TextureRenderTargetSource->TextureRHI->GetNumMips(), TextureSource->TextureRHI->GetNumMips());
ENQUEUE_RENDER_COMMAND(TestShaderCommand)(
[TextureSource, TextureRenderTargetSource, FeatureLevel, CommonMip](FRHICommandListImmediate& RHICmdList)
{
if (CommonMip >= 2)
{
//Test Copy Subregion
for (int32 MipIndex = 0; MipIndex < CommonMip - 1; ++MipIndex)
{
FRHICopyTextureInfo CopyInfo;
CopyInfo.SourcePosition = FIntVector(0, 0, 0);
CopyInfo.DestPosition = FIntVector(0, 0, 0);
CopyInfo.SourceMipIndex = MipIndex;
CopyInfo.DestMipIndex = MipIndex;
CopyInfo.Size = FIntVector(TextureSource->GetSizeX() / FMath::Pow(2, MipIndex + 1), TextureSource->GetSizeY() / FMath::Pow(2, MipIndex + 1), TextureSource->GetSizeZ() / FMath::Pow(2, MipIndex + 1));
RHICmdList.Transition(FRHITransitionInfo(TextureRenderTargetSource->TextureRHI, ERHIAccess::Unknown, ERHIAccess::CopyDest));
RHICmdList.Transition(FRHITransitionInfo(TextureSource->TextureRHI, ERHIAccess::SRVMask, ERHIAccess::CopySrc));
FRHITexture* Test = TextureSource->TextureRHI.GetReference();
RHICmdList.CopyTexture(TextureSource->TextureRHI, TextureRenderTargetSource->TextureRHI, CopyInfo);
RHICmdList.Transition(FRHITransitionInfo(TextureRenderTargetSource->TextureRHI, ERHIAccess::CopyDest, ERHIAccess::SRVMask));
RHICmdList.Transition(FRHITransitionInfo(TextureRenderTargetSource->TextureRHI, ERHIAccess::CopySrc, ERHIAccess::SRVMask));
}
}
else
{
FRHICopyTextureInfo CopyInfo;
CopyInfo.SourcePosition = FIntVector(0, 0, 0);
CopyInfo.DestPosition = FIntVector(0, 0, 0);
CopyInfo.Size = FIntVector(TextureSource->GetSizeX() / 2, TextureSource->GetSizeY() /2, TextureSource->GetSizeZ() / 2);
RHICmdList.Transition(FRHITransitionInfo(TextureRenderTargetSource->TextureRHI, ERHIAccess::Unknown, ERHIAccess::CopyDest));
RHICmdList.Transition(FRHITransitionInfo(TextureSource->TextureRHI, ERHIAccess::SRVMask, ERHIAccess::CopySrc));
RHICmdList.CopyTexture(TextureSource->TextureRHI, TextureRenderTargetSource->TextureRHI, CopyInfo);
RHICmdList.Transition(FRHITransitionInfo(TextureRenderTargetSource->TextureRHI, ERHIAccess::CopyDest, ERHIAccess::SRVMask));
RHICmdList.Transition(FRHITransitionInfo(TextureRenderTargetSource->TextureRHI, ERHIAccess::CopySrc, ERHIAccess::SRVMask));
}
}
);
FlushRenderingCommands();
}SrcTexture: 512 * 512 The existence of 10 level Mip Of Texture
DestTexture: 512 * 512 The existence of 10 level Mip Of RenderTexture



CopyTexture Precautions for use of
[1]SrcTexture and DestTexture Array format match , For example, they all say RGBA8 perhaps RGBA16, Format mismatch may cause the program to crash
[2] image MipIndex,SliceIndex, Szie Be careful not to cross the boundary when waiting for parameters ( For example, texture array Size by 5, Specify in the program SliceIndex = 5), It may also cause the program to crash .
[3] When CopySize by 0 when , It will automatically copy all levels Mip, Make an overall copy , Refer to the following
CopyTexture The underlying principle of
UE4 CopyTexture Use RHI Layer of things , There are different implementations on different platforms , stay DX11 With the implementation of the :
CopySubresourceRegion(CopySize Not for 0 when ) and CopyResource(CopySize be equal to 0 when )

CopyToResolveTarget
CopyToResolveTarget stay UE4 Rendering threads often use , Function is also used to copy FTextureRHI, Function and CopyTexture Is very similar .


Use case code
void UTestCopyRenderFunctionLibrary::CopyToResolveTarget(
const UObject* WorldContextObject,
class UTexture2D* InTexture,
const UTexture2D* OutTexture,
FIntVector CopySize)
{
UWorld* World = WorldContextObject->GetWorld();
ERHIFeatureLevel::Type FeatureLevel = World->Scene->GetFeatureLevel();
if (FeatureLevel < ERHIFeatureLevel::SM5)
{
UE_LOG(LogTemp, Warning, TEXT("FeatureLevel < ERHIFeatureLevel::SM5"));
return;
}
if (nullptr == OutTexture)
{
UE_LOG(LogTemp, Warning, TEXT("InTexture Is NULL"));
return;
}
FTexture* SourceTexture = InTexture->Resource;
FTexture* TargetTexture = OutTexture->Resource;
ENQUEUE_RENDER_COMMAND(TestShaderCommand)(
[SourceTexture, TargetTexture, FeatureLevel, CopySize](FRHICommandListImmediate& RHICmdList)
{
FResolveParams ResolveParams;
ResolveParams.Rect = FResolveRect(0, 0, SourceTexture->GetSizeX(), SourceTexture->GetSizeY());
ResolveParams.DestRect = FResolveRect(0, 0, SourceTexture->GetSizeX(), SourceTexture->GetSizeY());
RHICmdList.Transition(FRHITransitionInfo(TargetTexture->TextureRHI, ERHIAccess::Unknown, ERHIAccess::CopyDest));
RHICmdList.Transition(FRHITransitionInfo(SourceTexture->TextureRHI, ERHIAccess::SRVMask, ERHIAccess::CopySrc));
RHICmdList.CopyToResolveTarget(SourceTexture->TextureRHI, TargetTexture->TextureRHI, ResolveParams);
RHICmdList.Transition(FRHITransitionInfo(TargetTexture->TextureRHI, ERHIAccess::CopyDest, ERHIAccess::SRVMask));
RHICmdList.Transition(FRHITransitionInfo(SourceTexture->TextureRHI, ERHIAccess::CopySrc, ERHIAccess::SRVMask));
});
}Even the function of parameters is very similar , But strictly speaking CopyToResolveTarget Use Range ratio CopyTexture To be wide , For example, ordinary texture (UTexture2D, UTexture2DArray, UTextureRenderTarget2D) Use CopyTexture There is no problem , however SceneDepthTexture such Texture Use CopyTexture Direct brutal copy effect is problematic .
have a look CopyToResolveTarget stay DX11 The implementation of the


You can see CopyToResolveTarget Aimed at DepthStencil Class texture , Say it's customized FResolveDepthPS To carry out Copy Of , For ordinary textures , And CopyTexture equally . Overall CopyTexture Just say CopyToResolveTarget A subset of functions .
Case code download
https://download.csdn.net/download/qq_29523119/86242859
Reference material
边栏推荐
- 【翻译】Chaos Mesh移至CNCF孵化器
- Uniapp switches the tab bar to display different pages, remembers the page location and pulls up to get new data
- 【技术科普】联盟链Layer2-论一种新的可能性
- 升级poi-tl版本1.12.0与旧版poi(4.1.2)、easyexcel之间的依赖冲突解决
- C language program environment
- 小程序毕设作品之微信校园二手书交易小程序毕业设计成品(5)任务书
- Delete the duplicate items in the array (keep the last duplicate elements and ensure the original order of the array)
- Vector3.Lerp
- 妙用cURL
- [daily question] 757. Set the intersection size to at least 2
猜你喜欢

小程序毕设作品之微信校园二手书交易小程序毕业设计成品(1)开发概要

直播预告 | openGauss的自治运维平台DBMind实践分享

Research on security situation awareness method of Internet of things based on evidence theory

测试用例设计方法合集

Is cross modal semantic alignment optimal under comparative learning--- Adaptive sparse attention alignment mechanism IEEE trans MultiMedia

Codeforces Round #808 (Div. 2) A - D

NFT Insider #67:巴塞罗那足球俱乐部推出首个NFT作品,迪拜推出国家元宇宙战略

Wechat campus second-hand book trading applet graduation design finished product (7) Interim inspection report

Codeforces Round #807 (Div. 2) A - D

Delete the duplicate items in the array (keep the last duplicate elements and ensure the original order of the array)
随机推荐
直播预告 | openGauss的自治运维平台DBMind实践分享
Codeforces Round #809 (Div. 2) A - D1
Trees and binary trees
小程序毕设作品之微信校园二手书交易小程序毕业设计成品(5)任务书
Ambire 钱包开启 Twitter Spaces 系列
Classes and objects (1)
Delete the duplicate items in the array (keep the last duplicate elements and ensure the original order of the array)
Draw a wave ball with the curve of flutter and Bessel
uniapp切换tab栏显示不同页面并记住页面位置和上拉获取新数据
Codeforces Round #807 (Div. 2) A - D
Overview of the development of pseudo defense in cyberspace: from pseudo concept to "pseudo +" ecology
阿里云安全中心之漏洞修复最佳实践
RS485 communication OSI model network layer
2022就业季惊喜来袭!正版Adobe软件,终于能正经白嫖一把了
类和对象(1)
能量原理与变分法笔记11:形函数(一种降维思想)
Countermeasure and defense method based on softmax activation transformation
Educational Codeforces Round 132 A - D
小程序毕设作品之微信酒店预订小程序毕业设计(6)开题答辩PPT
ETL工具(数据同步)