- Home /
Texture tiling based on Object size/scale
I want to create a ground plane that can be scaled to any size and maintain the same texture size on the surface without having to change the material tiling every time.
To give an example. Make a plane 1000x1000x1000. Add a grid 100x100 pixel texture and change the tiling to 1000 on both x and y. Now when you scale the plane the texture changes size relative to everything else.
How do I mitigate this effect?
Update:
I wrote an article, Texture Tiling based on object Size/Scale in Unity, that goes over two methods to get this feature.
any success with that? im trying to get the same thing done....
@pcace Just finished up an article, `Texture Tiling based on object Size/Scale in Unity`, that goes through both methods DaveA suggested in his answer.
I think the solution posted by @$$anonymous$$L$$anonymous$$ is very promising. I've been looking around for an answer to this question for some time today, and the script he publishes in his article works great for tiling planes. The only issue I ran into was something about materials leaking out onto the scene, which I found a small bit of workaround code to resolve. I want to do the same type of tiling technique for cubes and other 3d objects -- this seems like it gets very close. Any guidance to modify his script in order to perform tiling on cubes would be great.
Can I ask, what was the change you needed to implement in order to prevent the leaking materials error? I understand that using .material makes a copy, where as .sharedmaterial does not--but the latter returns us back to the original problem...
Sure... and to be quite honest I'm not totally sure how all the texture/material stuff works in unity yet, however I did find a solution that seems to get me most of the way there so far, scaling both planes and cubes.
I'm using @$$anonymous$$L$$anonymous$$'s script exactly with a few modifications to the UpdateTiling() method. It's been a while since I worked on this so it might take me some time to remember exactly what my modifications do, lol, but here they are...
[Context$$anonymous$$enu("UpdateTiling")]
void UpdateTiling()
{
// A Unity plane is 10 units x 10 units
float planeSizeX = 10f;
float planeSizeZ = 10f;
// Figure out texture-to-mesh width based on user set texture-to-mesh height
float textureTo$$anonymous$$eshX = ((float)this.texture.width / this.texture.height) * this.textureTo$$anonymous$$eshZ;
var meshRenderer = gameObject.GetComponent<$$anonymous$$eshRenderer>();
var scale = new Vector2(
planeSizeX * gameObject.transform.lossyScale.x / textureTo$$anonymous$$eshX,
planeSizeZ * gameObject.transform.lossyScale.z / textureTo$$anonymous$$eshZ);
$$anonymous$$aterial scaled$$anonymous$$aterial = GetScaled$$anonymous$$aterial(
meshRenderer,
new[] {"_Bump$$anonymous$$ap", "_Illum"},
scale);
meshRenderer.shared$$anonymous$$aterial = scaled$$anonymous$$aterial;
}
$$anonymous$$aterial GetScaled$$anonymous$$aterial(
$$anonymous$$eshRenderer meshRenderer,
string[] texturePropertyNames,
Vector2 scale)
{
var material = new $$anonymous$$aterial(meshRenderer.shared$$anonymous$$aterial);
material.mainTextureScale = scale;
var shaderPropertyCount = ShaderUtil.GetPropertyCount(material.shader);
for (int i = 0; i < shaderPropertyCount; i++)
{
var propertyName = ShaderUtil.GetPropertyName(material.shader, i);
if (texturePropertyNames.Contains(propertyName))
material.SetTextureScale(propertyName, scale);
}
return material;
}
So it looks like I'm getting the $$anonymous$$eshRenderer of the game object and creating a new scaled material, then setting that material to the renderer's shared$$anonymous$$aterial property. I'm not sure of the performance issues, if any, with this code, but any thoughts would be welcomed.
Answer by DaveA · Aug 17, 2013 at 05:39 PM
Basically you look for changes in scale and adjust the tiling accordingly. If you want this in the editor, make the script 'execute in editor'. Note that affecting the tiling is per-material so if that same material is used elsewhere, it will mess with them. The other option is to play with UV's but I wouldn't.
It would be nice if it could be used on many different planes. A script that listens to scale and adjusts tiling would not be suitable as you said. This seems like a necessary feature in order to keep textures from stretching and blurring. Is there somewhere where I can define the texture size and just tile that size across whatever?
Answer by Simonius Skjorn · Aug 12, 2014 at 10:26 PM
You could use this: https://www.assetstore.unity3d.com/en/#!/content/20333
And change the plane's size instead of scale. Except you don't want to do it at run time very often, because it regenerates the mesh. It's an out-of-the-box implementation of the second method you describe. It has an advantage of not taxing your material count.
Answer by legoblaster1234 · Jul 03, 2018 at 06:46 AM
Is there a way to get method 1 in your article to work in all 3 directions and not just on the top surface? I want to make a rescalable wall.
Your answer
Follow this Question
Related Questions
Assigning UV Map to model at runtime 0 Answers
Dynamic Texture Tiling 1 Answer
Visible seams on borders when tiling texture 1 Answer
Unity 3.5 can't display negative tiling in UV? 1 Answer
Changing scale of WebCamTexture 1 Answer