Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by pablo_s · Mar 30, 2013 at 11:05 PM · texture2druntimetilesdraw calls

Modifying mainTextureOffset increases draw calls

Hi All,

I'm working on a tile system for generating environments at runtime. The mechanism for generation is straight forward. I have a handful of tile prefabs (modeled in Blender) that are loaded, instantiated, and positioned in the scene. Each tile is 20x20 Unity units and I'm generating a 100x100 grid of them for testing. The tiles currently all share the same unlit mobile material containing a single 1024x1024 texture atlas. Each texture in the atlas is 256x256. By default the material's tiling is set to 0.25, 0.25 and the offset to 0, 0. Tile generation looks like:

 for(int i = 0; i < rows; i++)
 {
     for(int j = 0; j < cols; j++)
     {
         UnityEngine.Object resource = resources[UnityEngine.Random.Range(0, resources.Count)];
         GameObject tile = (GameObject) GameObject.Instantiate(resource);
         tile.transform.position = new Vector3(startX + i * tileSize, 0, startZ + j * tileSize);
     }
 }

The resources object contains the prefabs which were loaded with Resources.Load. Tile selection, as seen, is currently random. Nothing groundbreaking here and it works great. Looking at the stats there is only a single draw call and it absolutely flies when tested on an iPhone 4S. Now for the problem... If I modify each tile's mainTextureOffset the draw calls shoot through the roof (in the thousands) and performance suffers. The code looks like:

 // outside of the loop
 List<Vector2> offsets = new List<Vector2>
 {
     Vector2.zero,
     new Vector2(0.25f, 0f),
     new Vector2(0.5f, 0f),
     
     new Vector2(0.0f, 0.25f),
     new Vector2(0.25f, 0.25f),
     new Vector2(0.5f, 0.25f),
 
     ...
 };
 
 ...
 
 // inside the loop
 tile.renderer.material.mainTextureOffset = offsets[UnityEngine.Random.Range(0, offsets.Count)];

I would have thought that Unity would only need a single draw call or batch the calls since the material and texture remain the same but apparently that's not the case. Is there anyway I can set this up so the tiles continue to require only a single draw call? Combine the tiles into a single mesh possibly?

Many thanks

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by robertbu · Mar 30, 2013 at 11:09 PM

Modifying the texture offset results in each individual tile getting a new material instance and therefore it will no longer batch. Based on what I see here, what you want to do instead is manipulate the uv coordinates of each tile and use a texture atlas.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image pablo_s · Mar 31, 2013 at 12:04 AM 1
Share

Success! Thanks a ton, back to one draw call and it's haulin some major booty! Code could use a little clean up yet, but here's what I did to modify the uvs:

 List<float[]> uvOffsets = new List<float[]>
 {
     new float[]{ 0f,     0f },
     new float[]{ 0.25f, 0f },
     new float[]{ 0.5f,     0f },
     ...
 };
 
 ...
 
 // inside loop
 $$anonymous$$esh mesh = tile.GetComponent<$$anonymous$$eshFilter>().mesh;
 Vector2[] uvs = mesh.uv;
 float[] offset = uvOffsets[UnityEngine.Random.Range(0, uvOffsets.Count)];
 
 for(int k = 0; k < uvs.Length; k++)
 {
     Vector2 uv = uvs[k];
     uvs[k] = new Vector2(offset[0] + uv.x * 0.25f, offset[1] + uv.y * 0.25f);
 }
 
 mesh.uv = uvs;
avatar image Torbach · Jun 10, 2013 at 06:10 PM 0
Share

This seems to be a problem if any animation is applied to a material through an *.anim controller?

I use an empty+controller to pass motion to children for vFX, but doing so alters the material at run-time "[materials name] **(instance)"... destroys any optimization I was hoping to create,

is there any trick/solution I should be aware of to animate a material exclusively for 1 plane without instancing this?

Specifically I key alpha (additive +/-) to get vFX textures to dissolve. I can't quite do this on the vertex.alpha level because in practice they perform multiplicatively creating a 'fade' .i.e alpha gain rather than an alpha offset.

(also I am supposed to avoid use of emitters for mobile deployment)

[edit spelling/clarity]

avatar image robertbu · Jun 10, 2013 at 06:12 PM 0
Share

I don't have an answer for you. You may want to ask this as a new question rather than as an addition to an existing (marked answered) one.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Problem importing normal map texture at runtime 0 Answers

Change texture non-power of 2 setting at runtime? 1 Answer

Determine the texture format at runtime. 1 Answer

How do I fix repeating tiles ? 0 Answers

Projecting a texture onto a mesh (efficiently) at runtime 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges