I’ve updated the old PR with Texture Array Support to 4.22, here is a new PR: https://github.com/EpicGames/UnrealEngine/pull/5767
If you need Texture Array Support with 4.22 or above, you can easily merge this into your engine source now.
I’ve updated the old PR with Texture Array Support to 4.22, here is a new PR: https://github.com/EpicGames/UnrealEngine/pull/5767
If you need Texture Array Support with 4.22 or above, you can easily merge this into your engine source now.
Great work. We need to set up a pinned thread to list all pull requests like this, so people could more easily find cool “mods” for their engines.
It’s insane that such basic is still not in UE4 after so many years (first PR was in 2015). I saw that Epic close all PR about texture arrays because they are already working on “improving Textures in the Engine” but it’s been a year ago and never had any updates. Do we need to wait 10 years to get what is in almost all engine since 4 or 5 years?
All engines? Unity and which other ones? Because CryEngine definitely doesn’t, since I worked on doing exactly that for a client that uses CE. And you can use the PR yourself, GitHub does the merging, no programming skills necessary.
Hey all - it looks like a fix for this went in and will be available in 4.24.
Can you clarify what you mean by this? Is the PR being merged for 4.24?
There is indeed a Texture 2D Array support in 4.24 although it’s broken in the 4.25 preview again.
I’ve created a test landscape with 10 layers and 2 texture samplers per layer (Color+Normal).
Without using texture arrays I’m getting 0.5ms in the BasePass. (Total scene 2.67ms)
**With **texture arrays I’m getting 4.18ms in the BasePass. (Total scene 6.19ms)
That’s a huge loss in performance. Does anyone know if I missed something important here? Or is it indeed not as simple as replacing the samplers?
[USER=“24522”]John Alcatraz[/USER] Is your implementation for 4.22 different than the “official” one in 4.24?
Not being an expert here but any help would be great! Thank you.
Of course not. You achieve nothing by replacing fetches from textures for fetches from arrays.
Arrays seem to be fine in 4.25p0.
Thanks for the clarification. Looks like I’m gonna stick with RVT then which works very well for large landscapes in 4.25.
There is a compile error in preview 7 for me. Not sure about earlier previews.
To benefit from arrays for landscape, you’d need to shift towards a different landscape texturing approach. Whole point of arrays is to decouple number of texture fetches from number of layers. RVT and arrays are not mutually exclusive either. RVT can be productively used with array-based landscape texturing system.
It is slightly different, but overall similar. Have you reported the TA in 4.25 to Epic yet? If not, please do so, would be good if they could manage to fix it before 4.25 comes out: Unreal Engine Community
I was impressed by this video here https://www.youtube.com/watch?v=fuvDy4lvGOM&vl=en
Enough to just swap the samplers in the hope to gain something.
Thanks for your information. From your words it sounds like it’s not easy and might require redoing the whole landscape again or even engine changes?
I’ve read through your earlier posts, trying to understand on how to take on this. But as I said, not being an expert here. Maybe someone ever finds the time to go more in practical detail.
Ah I see, thank you. I wonder why they never announced this in 4.24.
Yes I did, a new report has already been created: Unreal Engine Issues and Bug Tracker (UE-92616)
This tool can work with vertex color?
For example, there are 16 colors. These colors are fully consistent with the index in UE4 array. The FBX source mesh contains vertex color. When exporting a mesh to UE4, the model is painted over with the necessary textures from the array.
Looks like there’s texture 2d array support in 4.25 on the c++ side. Able to manually create texture arrays in C++ with a modified create transient function but the becomes that the shader/material side doesnt work correctly as it’s labeling the texture 2d array as a texture2d and not a texture2darray.
Here’s my C++ code on how im doing it:
UTexture2DArray* TextureGenerator::CreateTexture2DArray(TArray<UTexture2D*> data, int width, int height, int depth, EPixelFormat format){
UTexture2DArray* textureArray = TextureGenerator::CreateTransientArray(width, height, depth, format);
if (!textureArray) return nullptr;
#if WITH_EDITORONLY_DATA
textureArray->MipGenSettings = TMGS_NoMipmaps;
#endif
textureArray->NeverStream = true;
textureArray->SRGB = 0;
#if WITH_EDITORONLY_DATA
textureArray->SourceTextures = data;
#else
//copy the textures?
FTexture2DMipMap& Mip = textureArray->PlatformData->Mips[0];
void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE);
/*TArray<void*> inData;
for (int i=0; i<data.Num();i++){
inData.Add(data->PlatformData->Mips[0]);
}*/
FMemory::Memcpy(Data, data.GetData(), width * height * depth * GPixelFormats[format].BlockBytes);
//FMemory::Memcpy(Data, inData.GetData(), width * height * depth * GPixelFormats[format].BlockBytes);
Mip.BulkData.Unlock();
#endif
textureArray->UpdateResource();
return textureArray;
}
UTexture2DArray* TextureGenerator::UpdateTexture2DArray(TArray<UTexture2D*> data, int width, int height, int depth, EPixelFormat format, UTexture2DArray* textureArray){
if (textureArray == nullptr)
return CreateTexture2DArray(data, width, height, depth, format);
#if WITH_EDITORONLY_DATA
textureArray->SourceTextures = data;
#else
//copy the textures?
FTexture2DMipMap& Mip = textureArray->PlatformData->Mips[0];
void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE);
/*TArray<void*> inData;
for (int i=0; i<data.Num();i++){
inData.Add(data->PlatformData->Mips[0]);
}*/
FMemory::Memcpy(Data, data.GetData(), width * height * depth * GPixelFormats[format].BlockBytes);
//FMemory::Memcpy(Data, inData.GetData(), width * height * depth * GPixelFormats[format].BlockBytes);
Mip.BulkData.Unlock();
#endif
textureArray->UpdateResource();
return textureArray;
}
UTexture2DArray* TextureGenerator::CreateTransientArray(int32 InSizeX, int32 InSizeY, int32 InSizeZ, EPixelFormat InFormat, const FName InName)
{
UTexture2DArray* NewTexture = NULL;
if (InSizeX > 0 && InSizeY > 0 && InSizeZ > 0 &&
(InSizeX % GPixelFormats[InFormat].BlockSizeX) == 0 &&
(InSizeY % GPixelFormats[InFormat].BlockSizeY) == 0 &&
(InSizeZ % GPixelFormats[InFormat].BlockSizeZ) == 0)
{
NewTexture = NewObject<UTexture2DArray>(
GetTransientPackage(),
InName,
RF_Transient
);
NewTexture->PlatformData = new FTexturePlatformData();
NewTexture->PlatformData->SizeX = InSizeX;
NewTexture->PlatformData->SizeY = InSizeY;
NewTexture->PlatformData->SetNumSlices(InSizeZ);
NewTexture->PlatformData->PixelFormat = InFormat;
// Allocate first mipmap.
int32 NumBlocksX = InSizeX / GPixelFormats[InFormat].BlockSizeX;
int32 NumBlocksY = InSizeY / GPixelFormats[InFormat].BlockSizeY;
int32 NumBlocksZ = InSizeZ / GPixelFormats[InFormat].BlockSizeZ;
FTexture2DMipMap* Mip = new FTexture2DMipMap();
NewTexture->PlatformData->Mips.Add(Mip);
Mip->SizeX = InSizeX;
Mip->SizeY = InSizeY;
Mip->SizeZ = InSizeZ;
Mip->BulkData.Lock(LOCK_READ_WRITE);
Mip->BulkData.Realloc(NumBlocksX * NumBlocksY * NumBlocksZ * GPixelFormats[InFormat].BlockBytes);
Mip->BulkData.Unlock();
}
else
{
UE_LOG(LogTexture, Warning, TEXT("Invalid parameters specified for UTexture2D::CreateTransient()"));
}
return NewTexture;
}
You will need to add “RenderCore” to your build.cs as the GPixelFormats are in there to use.
Under the editor, using the “SourceTextures” variable that is in the UTexture2DArray class will enable easy creation of the texture array, but out of the editor, i dont really know if what im doing is correct or not.
Like i said above, the only that there is currently is that there doesnt seem to be shader/material support with TextureObject(Parameter) or TextureSampler(Parameter) since in HLSL the variables are created using Texture2D and not Texture2DArray.
r.AllowTexture2DArrayCreation
This is it.
THIS IS THE GOD ■■■■ COMMAND!
For freak sakes…
Set this to 1 and you’ll be able to create Texture2DArrays in the content browser.
I used the command alatnet mentioned and got this working on PC, but building for Oculus Quest gives me errors.
Depending on the compression setting I use, it’s either an errorabout PixelBufferObjects:
or an errorabout the compression method not being supported
Using the “Alpha” compression setting avoids errors, but isn’t useful.
Anyone know a way I could get this working for Quest? I’m hoping there’s an option somewhere to use PixelBufferOBjects but I’m not really familiar with it. Unity documentation mentions Texture2DArray requiring OpenGL ES 3.0 and Quest is 3.2, which makes me think it’s possible.
Came back to bump this with some additional info.
Here’s how you can set it to always have the console command enabled: .unrealengine.com/en-US/ProductionPipelines/DevelopmentSetup/Tools/ConsoleManager/index.html