Combining Multiple Textures Onto a Single Object

Okay, so I’ve been racking my brain trying to figure out how to do this. Basically I have an Earth model (it’s just a sphere with specified UVs), and I have 32 8K textures that go across the surface. You may be wondering why not just use one texture; well I’m trying to get the most texel density, so that when you zoom in really close to it, it isn’t pixelated. What I currently have is a sphere with 32 separate material ID’s, with each map being it’s own texture. This is a lot of draw calls, I know, but this isn’t meant to be used in a game, and it’s the only object really in the scene. So off the bat, performance is not an issue. This technique works great for an Opaque material, however where it fails is with translucent materials. Currently UE4 has a limitation on the “Dynamic Shadow Distance” for both movable and stationary lights on Cascaded Shadow Maps . My earth is gigantic in the scene, and because of this my camera distance well exceeds the cap of 20,000 units, thus my translucent clouds that surround the earth are not receiving the appropriate shadows. To get around this I created a hemisphere mask around the cloud texture; this works well if it is a single texture, but fails when I try to break it up into 32 separate textures (obviously).
A forum post about the Cascaded Shadow Map issue can be found here, yet to be solved:

So here’s the issue/the idea. If I’m able to combine the 32 Textures into 1 material, the hemisphere mask will work, but pulling this off has been quite the challenge. The base idea behind this
video works well, BUT it only works for 2 materials! and because the material editor doesn’t have any other conditional nodes such as: ‘else’ or ‘and’, I can only ever compare two numbers.


I tried to write a custom HLSL node, but soon realized I have no clue what I’m doing and there is so little understandable documentation on HLSL.

SO! What I want is to take the UV coords, and compare the U to a range of 8, and the V to a range of 4, and then apply a specific material depending on the UV values.
EX: If U=1 and V=1 apply texture A1-1, if U=2 and V=1 apply texture A1-2, if U=1 and V=2 apply texture A1-3, if U=2 and V=2 apply texture A1-4. It’s really extremely basic logic, but again the material editor only has if statements.

I’ve tried running it through multiple if statements but it always overwrites the first texture input. I’ve also tried using lerps, and it actually does start to put them in the right place, but if i ever change the alpha to 0 or 1 in order to get a solid image, it breaks.

Anyone know a solution to this? I know blueprints have much more logic to them, but I wouldn’t really know where to start in connecting it to a material.

Here is what I’m going for, this is the current model. Looks great from far away, but if you get close you would find the clouds and the lights to be pixelated.

Unfortunately, You cannot have more than 16 texture samplers in one material.
Edit: Actually, I was wonrg. you can have more than 16 if you set the sampler source mdoe to “wrap”.

i put together a material using lerps. Its like an art peice made of string :stuck_out_tongue:


All those functions on the left enumerate from 1 to 32, and they each creat an alpha whish masks a single segment/square of the UV grid.

this is the material function


All 32 texture maps, in one material.
3.jpg
Dont worry, I wont make you copy it out. The UE4 material assets are atatched. Place them directly in your content folder.

The way I have set it up, the textures maps enumerate in rows from left to right, and top to bottom. The same way a page of english writing does.

2 Likes

Holy…Mother… WOW! I thought this post disappeared into nothingness, but you found it! I will Test that out right now! Thank you in advance if it works!!!

Okay so first. THANK YOU!!! You’re amazing! Truly! I appreciate the work you put into this.
Good news first! I was able to get your material to be 4 by 2 for a total of 8 textures in one (perviously on my own I was only able to get 4) so you have already DOUBLED my texture resolution! The bad news: If I try to use 32, UE4 crashes after a moment LOL, I guess it can’t handle all the high resolution maps I’m plugging in, BUT this is okay because of the good news! 8 maps should be enough resolution for a really nice quality up close. I might even go for 16 and see if it can handle it!

Once again, THANK YOU!!! :smiley:

Is there anything I can do on the forums to make sure you get the appreciation you deserve?

Awnswering questions is a good way to strengthen your skills and learn things you never would have discovered otherwise, thats why I do it.
And a thankyou like that is always nice aswell :slight_smile:
I may have a solution to your problem. I assume ue4 crashes with 32 textures because your GPU does not have enough memory to handle so many high resolution textures.
Large Open world games have the exact same problem. To overcome this, UE4 uses “Level streaming” - it is used in the kite demo.
For your planet earth, you would need to split the planet mesh into separate meshes. Maybe 16 or so. Each of these sections would be it’s own level.This means only one high resolution section of the model would ever loaded at one time. I have never properly looked into the level streaming system so I cant provide exact instructions, you would need to research it yourself.

Your planet earth looks really nice by the way - it would so cool to have an interactive planet earth like that, made in UE4.

Thanks! I’ve sort of gathered all the best things from around the internet and put them into this earth lol including Ryan Buck’s volumetric ray marcher for the atmosphere.
GPU has 11GB of memory lol I think the problem was that I was messing with it without increasing my texture streaming pool size first. I’m going for 16 currently, if it still looks bad when I zoom in after quadrupling the resolution then I’ll shoot for 32.

The “Level Streaming” idea sounds interesting, however my earth has to remain in one piece due to seam visibility between meshes. My first plan was to split the earth into 32 pieces, and I did, but found the seams to be unavoidable with separate pieces, so I just gave one mesh 32 separate material ID’s. Thanks for the thought though!

And thanks again for solving my main issue! :slight_smile:

@somawheels I got another question for you. When I apply the material to the earth, the seams are still visible. (see the images)

I know this has something to do with the interpolation between the two textures. I’ve been trying to use Ryan Brucks’ “Tiling within subUV” method but am a bit lost on where to put the encoding and decoding steps.

Would that method work here with multiple textures? or are seams just something I’ll need to deal with? Thanks in advance!

Regarding split mesh seams: these can usually be avoided by adding some overlap between the separate meshes.
Regarding level streaming: You could have one low resolution earth which is full and not split into peices; this would always be loaded. Peices of high resolution earth can streamed in as required, over the top of the low resolution earth, and there should not be any seams because there is a low resolution earth mesh right below it.

Regarding texture seams: I think you have two problems going on at once here. One might be due to texture filtering or UV precision - the actual texture pixels dont match up on the closeup.
To fix this, try setting the meshes and material to use “full precision UVs” and also try changing the texture filtering to “nearest” in texture settings.

The other issue (due to MipMaps “Tiling within subUV”) is interesting but i wont look into it right now, sorry. Maybe when i have some spare time. Good luck!

You would have to edit the material function subUV and add in Seamless UVs(V2) in it. The image that followed in the link showed the steps. Have fun.

Thanks for the help, unfortunately changing the mesh to use 'full precision UVs" and texture filter to “nearest” didn’t solve the problem. In regard to the pixels being off, I was using the wrong normal map for the top right clouds in the image. I also switched from 16 maps to 8 which got rid of two seams on the top and bottom, so it’s not perfect, but better.

If you have any other suggestions, I’ll be here lol

Thanks again!

I actually might have figured out the issue. In Photoshop the pixels around the edge of each image are slightly transparent, very odd, but could be due to image downsizing for UE4. I’ll update with results of fixing that.

Update: that wasn’t the problem unfortunately, seams still remain.

Hey have you found a solution for the seams issue? I’m having the same problem.

@somawheels Do you still have these Material Assets by any chance? I don’t see them attached to the post anymore. Thanks!

Hi, Im sorry to say I dont. I would not recommend the method anyway though, it has mip issues.

Texture arrays might be a better way to combine textures in a material. They dont have the mip issues, and would be simpler to setup.

Thanks for the reply!

Hi, so I’ve got a 32k texture that I want on my landscape, but obviously there’s a 16,384 size limit on textures in UE. If I cut my image up into a grid of say 4X4 of 8129 resolution images (or 2x2 of 16k), how would I then texture my landscape so that they all line up? I’m not sure at all how to set up the material, they would also need the landscapelayercoord node to upscale them to fit the 4033 resolution landscape.

Interesting.

You have to define what you want out of it.

If you just want to tile 4 textures into the landscape you just use the UV split by .5 similar to how it’s shown above.
You manually manage what texture to use and how by feeding different UV input into each of the textures…

Managed to figure it out! Used an if statement to basically get 0,0 and 0-1 along the R channel (with texture/landscapelayer coord and a R mask) and then did the same for 1-0 and 1-1. And then combined them with a third IF along the green channel (if Mask g<1 then 0,0 +0,1) and if (mask g>1 then 1-0 + 1,1)