Idiot Question: Texture Scale?

Hey there! Brand spanking new to this whole UE4 thing, or, you know, development in general. Or 3D rendering. Or, yeah, much of anything that has anything to do with this world.

I have a texture. This texture is a square. It is designed to be a square; it is intended to be square in shape and scale.

I attach it to a plane. I stretch the plane into not-a-square. The plane now has dimensions like 2x4x1 or sommat.

The texture is now stretched to 2x4.

The texture is designed to be a square. It looks like hell stretched into a rectangle.

How, oh how, do I set the texture up to stay at one scale, such that, say, 2x2, on a 2x4 plane, creates two tiled instances of the texture?

To quote Galaxy Quest: “Explain as you would a child.” I am… already, GROSSLY overwhelmed. Just trying to do this one seemingly-simple task.

Use Triplanar Projection (or similar techniques) or create custom UVs.

I do not know what Triplanar Projection is. Or custom UVs. I am completely ignorant of… basically anything here. This is why I am asking, and why I said “Explain as you would a child.”

A 3D object is in 3D… but textures are 2D so when you assign a 2D texture to the 3D model, how does it know how to apply the 2D texture to the 3D model?

Well, similar to how geometry exists in 3D space (XYZ), the coordinates that map a texture to a model also exist in their own coordinate space, typically called “texture coordinates” or “UV coordinates” (and very rarely these days, “UVW coordinates”)

The process of creating UV coordinates is typically called “unwrapping”, in which you split up the model into a bunch of pieces and lay them out flat, and this is used to tell the model which parts of the texture go on which polygon. If you’ve ever seen a papercraft model, it’s pretty much exactly like that.

The important thing here in your case is that the texture coordinates don’t actually care about the size or shape of the polygons in 3D, they only care how they’re mapped in the UV space. So when your geometry gets stretched out the texture will simply stretch with it because as far as it is concerned, the UV coordinates haven’t changed at all even if the geometry has.

There really only two ways to address this, you could adjust the texture coordinates of your mesh in your 3D modeling package… But since texture coordinates are just numbers, you can also change them at runtime using some simply multiplication in the material.

If all you are doing is scaling an object, it is typically best to do this within the material in Unreal. Here’s how that would look:

In order to keep this from affecting ALL of your objects that use this material, you will want to create a material instanceto assign as needed to objects that get stretched out. The much more advanced way to do this would be to create a blueprint actor of your object and use the construction script to create the material instance for the mesh, and then use the objects relative scale in to determine the material parameters XY tiling, that way you don’t have to manually set it every time and you don’t fill your project up with material instances. But I’m already well beyond ELI5 territory here so I won’t go into that.

There are other options, you could use a triplanar projection (which is built into UE4 as a node called WorldAlignedTexture) as ZacD said above which essentially uses world coordinates as texture coordinates, but this typically only works with flat or natural surfaces (rock, dirt, etc.) and not patterned ones (like brick)

Okay, I understand that much. Thank you for taking the time to explain; I didn’t know that much, so it was helpful.

This is… a touch more confusing, largely because I’m using texture assets from Quixel, which seem to have hierarchy pre-made… The material already has a lot of parameters; alas, none of them are X Tiling or Y Tiling. (I do have a singular “Tiling” parameter.)

Yeah, that was going to be my next question, how to do this without affecting the overall use of the material. The “easiest” method I’d found to try to do this was to just create multiple planes for, for example, a floor: A floor that is 25 “tiles” wide, and 150 “tiles” long. This seemed… extreme. Unnecessary. Surely, there must have been an easier way! I’ll play around, see what I can figure out with this little tidbit more information. Thank you.

That’s a pretty unfortunate oversight on their end in my opinion.

You could just make a copy of their master material and then replace their UV/TextureCoord manipulation nodes with what I posted above and then use it as needed. I can’t 100% guarantee it won’t break anything though.

I should note, trying to manipulate texture coordinates like this only works if you are using tiling textures, megascans calls these “surfaces”]( as opposed to “3d assets”]( “Surface” materials can be tiled, but “3D Asset” textures cannot. This is because 3D assets are using bespoke textures that are intended to work only with that mesh and its texture coords, if you attempt to change them it will not look right. (normally a 3D asset CAN be constructed out of tiling materials, but to my knowledge none of the 3D assets on Megascans are built this way)

Unfortunately there really aren’t a lot of good ways to resolve this as a total beginner. My preferred approach is to use a construction script that creates its own material instance with material parameters specific to that object. This isn’t complex but it requires some understanding of how actor based blueprints work.

I would strongly suggest you work through the courses that Epic offers in the Unreal learning portal, they’re the most accurate source of information you’ll find (outside of the docs) on working with the engine and the courses are well structured for learning as a beginner.

You can separate the applied texture from the UV unwrapping coordinates of the mesh using the WorldAlignedTexture node in the material… This will allow you to scale the object mesh any way you like and the texture will stay the same scale…