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 highpockets · Sep 16, 2013 at 04:05 AM · textureprefabprefabsdrawcallsinstances

Is it possible to have a prefab of a cube, which has instances with different colours?

Hi, I'm trying to keep the number of draw calls down. I have a lot of cubes, which have all of the same textures, scripts, etc., the only thing that will be different is the colour (I'll have like 5 or 6 colours).

I have been reading a lot about max draw calls for mobile devices. From what I gather I believe that when a texture is applied to a game object prefab, all instances of the prefab on the screen will only use one draw call (per light?) for that texture, but when that texture is on a different material (because of the colour in my case), another draw call is required...

I'm new at this, so I may be wrong with what I said above, but if I'm right, is there a way to still only use the 1 draw call for that texture for every cube regardless of the colour change?

Please correct me if I was wrong with what I said about draw calls, I'm trying to wrap my head around this stuff, thanks for you help!!

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

2 Replies

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

Answer by whydoidoit · Sep 16, 2013 at 04:55 AM

You are roughly right, but it's materials rather than textures that count.

Setting the instance of a prefabs material to a different colour will break batching. Your choice is to have a custom shader that uses the vertex colours of the model to tint it - this does not break batching.

Every vertex of a model has the opportunity to have a colour associated with it, you set it using the colors[] on the mesh. If for instance you used this shader:

 Shader "whydoidoit/Vertex Color Tinted" {
     Properties {
       _MainTex ("Texture", 2D) = "white" {}
     }
     SubShader {
       Tags { "RenderType" = "Opaque" }
       CGPROGRAM
       #pragma surface surf Lambert
       struct Input {
           float2 uv_MainTex;
           float4 color;
       };
       sampler2D _MainTex;
       void surf (Input IN, inout SurfaceOutput o) {
           o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * IN.color;
       }
       ENDCG
     } 
     Fallback "Diffuse"
   }

The you could colour each cube separately and still batch by setting those vertex colours (probably all to the same value). The array is the same size as the vertices array:

     var mf = GetComponent<MeshFilter>();
     var colors = new Color[ mf.sharedMesh.vertexCount];
     for(var i = 0; i < colors.Length; i++)
          colors[i] = new Color(1,0,0,1);  //Your color here
     mf.mesh.colors = colors;
Comment
Add comment · Show 1 · 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 highpockets · Sep 16, 2013 at 05:32 AM 0
Share

Thanks, I'll take a look at your suggestion.

avatar image
2

Answer by supernat · Sep 16, 2013 at 04:57 AM

You are correct. If the material is the same on several objects in the scene, they are batched to produce 1 draw call. And mobile devices are sensitive to draw calls, if you want to support many of the cheaper devices. However, the number of texture swaps is very low, so that is a good thing.

I haven't tried this, but I think it would work. If you're going for something like random colors, the shader could instantiate a global index that is incremented for each pass, and that index could access a pre-built random array of colors and apply them to the vertices directly in the pipeline, which would allow you to use the same material for all cubes but have random colors on them. If you kept everything ordered, the app could also track the color of each cube independently, if they aren't created quickly one after the other.

If you created a mesh with 6 cubes where each vertex is a different color, you still run into the problem of writing to variables in the shader to do something like say rotate or move each cube individually. In that case, you may incur more cost than the draw calls. I would say do some tests on some low end and high end devices to get an idea of what your limits are with the 6 draw calls. My personal experience with Android devices is that you can stay pretty decent with 15'ish draw calls and still be viable for older devices. It's the transparent textures and fill rates on the older devices that really start to get you.

Comment
Add comment · Show 6 · 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 whydoidoit · Sep 16, 2013 at 05:17 AM 0
Share

If you created a mesh with 6 cubes where each vertex is a different color, you still run into the problem of writing to variables in the shader to do something like say rotate or move each cube individually. In that case, you may incur more cost than the draw calls. I would say do some tests on some low end and high end devices to get an idea of what your limits are with the 6 draw calls. $$anonymous$$y personal experience with Android devices is that you can stay pretty decent with 15'ish draw calls and still be viable for older devices. It's the transparent textures and fill rates on the older devices that really start to get you.

Not sure if you are referring to my answer - but there is no need to write anything in the shader to do that - dynamic batching will create a joined mesh out of the individual cubes, based on the normal restrictions of dynamic batching of course.

avatar image highpockets · Sep 16, 2013 at 05:34 AM 0
Share

Thanks for your input

avatar image supernat · Sep 17, 2013 at 03:41 AM 0
Share

@whydoidoit, No, I wasn't referring to your answer, I think we posted close together as I didn't see yours. Actually, your way is definitely better than a single mesh with 6 cubes, and I didn't even think about it. There still is some overhead to changing the vertex buffers as they have to be put into video memory, but probably not a concern since you would only do it upon instantiation of the cube and not every frame.

Actually, that brings up another point highpockets. You probably don't want to re-instantiate the cubes over and over. Try to use a memory pool (I like Pool $$anonymous$$anager, I think is the one I use from the Asset Store). Even instantiating small, simple objects on $$anonymous$$obile I've seen cause quite a few hiccups at runtime. Those all went away when I started using Pool $$anonymous$$anager.

avatar image highpockets · Sep 17, 2013 at 05:16 AM 0
Share

cool, I don't have to re-instantiate at the moment, but if I see the need for an object pool in the future, I will check it out...

On another note. Do you think that a texture atlas of my different colours for the cubes would be a good idea? That way, the material would never change. I have a greyscale texture bumped that supplies all of the definition for every cube and all I need to change is the colour. Would that work? or will it break batching?

avatar image whydoidoit · Sep 17, 2013 at 05:23 AM 0
Share

@supernat - cool, thx for clearing that up :)

@highpockets - your texture atlas would work - but you'd need to modify the uvs of the cubes to use a different part of it - so you might as well go with vertex colouring that takes vastly less space. It would be pretty easy to add that to a bumped shader too.

Show more comments

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

17 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 avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Script is reading from prefab instead of instance 1 Answer

Problems with Batching (diffuse shader) 1 Answer

How to load instances of a prefab to an array c# 2 Answers

Unity not Instantiating Prefabs Properly 0 Answers

Apply PNG as texture to 3d object 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