- Home /
Dynamically tiling texture on a cube of changing scale.
Hi,
I'm attempting to build a wall via scripting using a primitive cube that could be of any size. That part is no problem, it's just tiling the texture that's causing a headache.
As a standard cube the tiling is fine, however as soon as the sides are no longer even the texture stretches on one or more sides.
I've hard-coded the majority of the dimensions into the example function below to show the kind of thing I'm attempting.
void BuildWall(Texture texture, float wallLength) {
GameObject westWall = GameObject.CreatePrimitive(PrimitiveType.Cube);
westWall.name = "Outer Wall West";
westWall.transform.parent = room.transform;
westWall.transform.position = new Vector3(-49.0f, 2.5f, 0.0f);
westWall.transform.localScale = new Vector3(2.0f, 5.0f, wallLength - 4.0f);
westWall.renderer.material.mainTexture = texture;
westWall.renderer.material.mainTextureScale = new Vector2(0.2f, 4.6f);
}
Is this possible? Or is a UV map required as soon as a cube's faces are not of equal size?
Thanks in advance to anyone that can help!
Answer by Wolfram · Feb 04, 2013 at 03:18 AM
Take a look at this professional drawing of a textured cube.
You can stretch the cube along two axes, without distorting the textures on their faces non-uniformly - but not all three axes:
Stretch along X: the stripes on the 4 side faces will remain the same as the cube is stretched along the stripe's direction. the other 2 sides remain unchanged.
Stretch along Y: the stripes on the 4 side faces will appear thicker as the cube is stretched against the stripe's direction. the other 2 sides remain unchanged.
Stretch along Z: whoa. two sides will be stretched along the stripe's direction, and two sides perpendicular to that! You cannot compensate this with texture scale either, as two faces would again stretch/replicate with the stripe's direction, and the other two against it (or in other words, two faces need x scaling, while the other two faces need y scaling. at the same time the two remaining faces must not be scaled.
(EDITED, as the first version was wrong:) Note as long as you scale only one axis (just don't scale the Unity Primitive Cube along Z (might be a different axis for modeled cubes, but there will always be one that doesn't work)), you should be fine for the 4 stretched faces, but you cannot map all 6 faces without distortion. As soon as you start to scale two or more axes, you can't even compensate to make 4 faces look correct.
For example, a cuboid 1x2x4 would need the texture mapped 2x4 times on the X faces, 1x4 times on the Y faces, and 1x2 times on the Z faces. Not possible without a matching UV map.
What you can do, however, is creating your cube mesh (and hence its UV map) dynamically, in which case you can just compute the UVs of all faces/vertices depending on the cuboid's scaling. Then you can use the texture scaling to uniformly increase/decrease the replication factor on all sides, without distortion.
Thanks Wolfram. (Your professional drawing of a cube rocks!)
So I suppose to have a wall that could change length on the fly (thinking of a basic level editor), the only ways to do it would be:
use multiple cubes like bricks to build the wall and add or remove bricks as needed. Each brick texture would need to be scaled to look like it fits in... or somehow spread a material over multiple bricks. (I'll have to go and do some research here).
$$anonymous$$atch a differently scaled texture to each side of the cube after each scale transform (I'm only guessing that's possible).
If there are any more simplistic ways known to overcome this hurdle, please share! :)
Thanks again!
Ah missed your extra comment before. Cheers! I'll have a look into doing that now ;)
Both should be possible. $$anonymous$$ethod #2 sounds like a possible alternative to updating the mesh+UVs on-the-fly. You would need 3 different materials, mapped in a modeling tool on the 3 pairs of opposite sides. Then you can use a script to independently adjust the texture scaling of these three textures. However, I think this would require 3 drawcalls per cube ins$$anonymous$$d of one, as the graphics card now has to handle 3 distinct materials.
I know I'm late to the party, but this thread got me started on a solution to a similar scaling/wrapping problem. I created a script that automatically causes the texture to repeat ins$$anonymous$$d of wrap by updating the UV's. thought I would add it here to help any others that find themselves in the same boat.
Thanks for script. It was exactly what I was looking for my breaking wall scenario where the bigger block are splitting into smaller and I need to retain visualized bricks textures size.
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Real Sized Texture Tiling 2 Answers
Texture is Tied to Two Cubes 1 Answer
How to add my texture to a cube? 2 Answers
Auto tiling texture 2 Answers