期待结果:
流程
1. 通过C++写入数据到纹理贴图
2. 在材质中通过采样能正确读取写入的数值
踩坑:
1. UE5之后,需要设置采样类型,才能达到上图效果,默认采样类型做了插值计算
FColor中写入 PF_B8G8R8A8
UTexture2D* ConvertFloatArr2Texture(TArray<FVector> inFArr) {if (inFArr.IsEmpty()) return nullptr;//FlushRenderingCommands();uint32 len = inFArr.Num();float templen = FMath::Sqrt(len);uint32 text_len = FMath::CeilToInt(templen);text_len = FMath::CeilToInt(log2(text_len));text_len = FMath::Pow(2, text_len);uint32 Totallen = FMath::Pow(text_len, 2);FColor* datas = new FColor[Totallen];for (uint32 i = 0; i < Totallen;++i) {if (i < len) {FColor Tempcolor;Tempcolor.B = inFArr[i].X;Tempcolor.G = inFArr[i].Y;Tempcolor.R = inFArr[i].Z;Tempcolor.A = 255;datas[i] = Tempcolor;}else {FColor Tempcolor(0,0,0,1);datas[i] = Tempcolor;}}UTexture2D* temp = UTexture2D::CreateTransient(text_len, text_len, PF_B8G8R8A8);temp->Filter = TF_Nearest;void* TextureData = temp->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);FPlatformMemory::Memcpy(TextureData, datas, Totallen * sizeof(uint8)*4);temp->GetPlatformData()->Mips[0].BulkData.Unlock();temp->UpdateResource();return temp;
}
FFloat16数据写入PF_FloatRGBA
void ConvertFloatArr2Texture(TArray<float> inFArr, int width, int height) {if (inFArr.IsEmpty()) return;FFloat16* datas = new FFloat16[height * width * 4];for (auto it = 0; it < 256; ++it) {FFloat16 ff(inFArr[it]);datas[it] = ff;}UTexture2D* temp = UTexture2D::CreateTransient(width, height, PF_FloatRGBA);temp->Filter = TF_Nearest;//temp->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;//temp->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;void* TextureData = temp->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);FMemory::Memmove(TextureData, datas, height * width * 4 * sizeof(FFloat16));temp->GetPlatformData()->Mips[0].BulkData.Unlock();// 更新纹理数据temp->UpdateResource();}
将FFloat32写入PF_R32G32B32F类型贴图
UTexture2D* ConvertFloatArr2Texture(TArray<FVector> inFArr) {if (inFArr.IsEmpty()) return nullptr;//FlushRenderingCommands();uint32 len = inFArr.Num();float templen = FMath::Sqrt(len);uint32 text_len = FMath::CeilToInt(templen);text_len = FMath::CeilToInt(log2(text_len));text_len = FMath::Pow(2, text_len);uint32 Totallen = FMath::Pow(text_len, 2);FFloat32* datas = new FFloat32[Totallen*4];for (uint32 i = 0; i < Totallen;++i) {if (i < len) {datas[i * 3 + 0] = inFArr[i].X;datas[i * 3 + 1] = inFArr[i].Y;datas[i * 3 + 2] = inFArr[i].Z;}else {datas[i * 4 + 0] = 0.0f;datas[i * 4 + 1] = 0.0f;datas[i * 4 + 2] =0.0f;}}UTexture2D* temp = UTexture2D::CreateTransient(text_len, text_len, PF_R32G32B32F);temp->Filter = TF_Nearest;void* TextureData = temp->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);FPlatformMemory::Memcpy(TextureData, datas, Totallen * sizeof(FFloat32)*3);temp->GetPlatformData()->Mips[0].BulkData.Unlock();temp->UpdateResource();return temp;
}
写入FLinearColor到PF_A32B32G32R32F格式的贴图
UTexture2D* ConvertFloatArr2Texture(TArray<FVector> inFArr) {if (inFArr.IsEmpty()) return nullptr;//FlushRenderingCommands();uint32 len = inFArr.Num();float templen = FMath::Sqrt(len);uint32 text_len = FMath::CeilToInt(templen);text_len = FMath::CeilToInt(log2(text_len));text_len = FMath::Pow(2, text_len);uint32 Totallen = FMath::Pow(text_len, 2);FLinearColor* datas = new FLinearColor[Totallen];for (uint32 i = 0; i < Totallen;++i) {if (i < len) {datas[i].R= inFArr[i].X;datas[i].G = inFArr[i].Y;datas[i].B = inFArr[i].Z;datas[i].A = 1.0;}else {datas[i].R = 0.0;datas[i].G = 0.0;datas[i].B = 0.0;datas[i].A = 1.0;}}UTexture2D* temp = UTexture2D::CreateTransient(text_len, text_len, PF_A32B32G32R32F);temp->Filter = TF_Nearest;void* TextureData = temp->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);FPlatformMemory::Memcpy(TextureData, datas, Totallen * sizeof(FLinearColor));temp->GetPlatformData()->Mips[0].BulkData.Unlock();temp->UpdateResource();return temp;
}
FFloat16数据写入灰度图PF_R16F
UTexture2D* ConvertFloatArr2Gray(TArray<FFloat16> inFArr, int32 width, int32 height) {if (inFArr.IsEmpty()) return nullptr;UTexture2D* temp = UTexture2D::CreateTransient(width, height, PF_R16F);temp->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;void* TextureData = temp->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);FMemory::Memzero(TextureData, width* height * sizeof(FFloat16));//temp->SRGB = false;//temp->CompressionSettings = TC_Displacementmap;FMemory::Memmove(TextureData, inFArr.GetData(), inFArr.Num() * sizeof(FFloat16));temp->GetPlatformData()->Mips[0].BulkData.Unlock();// 更新纹理数据temp->UpdateResource();UpdateKrigingTexture(temp);return temp;
}
纹理采样
方案一
for(int inw=0;inw<point_width;++inw)
{float2 Kriging_UV=float2(0,0);Kriging_UV[0]=float1(inw/point_width);for(int inh=0;inh<point_height;++inh){Kriging_UV[1]=float1(inh/point_height);//计算UV偏移float2 offset=float2(point_width,point_height);offset=1/offset;Kriging_UV=float2(offset*offsetCoord+Kriging_UV);//float4 point_T=Texture2DSample(in_Tex,Material.Texture2D_0Sampler, Kriging_UV);float3 point_T=in_Tex.Load(int3(Kriging_UV,0));}
}
方案二
float4 h=Texture2DSample(tex,texSampler,uv)
return h;
//另外采样方式
//float3 point_T=in_Tex.Load(int3(Kriging_UV,0));