I'm drawing a lot of boxes (~3k) in a Unity scene that are all instances of a prefab (simple cube).
However, each cube has a custom height and color. I believe that by changing the color, Unity creates a new instance of the material (I had a very high number of SetPass calls). This decreases my performance a lot.
When using sharedMaterial the performance (and the SetPass calls) is much better but all cubes have the same color.
Is it possible to group all cubes with the same color together for them to share one material but still use only one prefab?
Related
I am creating a scene with several thousand cubes, each of which can be translated, scaled and rotated.
Initially, I tried creating a cube geometry, applying the transformations, creating a mesh with my material and adding it to the scene. That worked but was very slow because of all the draw calls.
So now, for all the cubes, I create a THREE.BoxGeometry(1,1,1), and merge it with a single THREE.Geometry() each time before finally creating a material and a single mesh and adding it to my scene.
The performance is drastically improved but I don't know how to apply a translation (XYZ), scale (XYZ) and rotation (quaternion) to each box before merging it. Can someone point me at the right syntax?
Secondly, if I merge my geometry like this, is there still a way to pick out a single box with a raycaster? Typically I've used the object name on the mesh but that's not relevant anymore.
Thank you.
I am working on a project which needs rendering of thousands of unique meshes of building models. My objects need to be selectable and they will have their data (other than geometry) attached to them.
Since number of objects/meshes has a big impact on the rendering performance, I merge my objects into a few huge meshes and create "pseudo meshes" which just hold information about the indexes of the mesh's triangles and the other data attached. I am able to render each mesh with their own color and user is able to pick them separately.
However transparency and render order is making things hard for me. I managed to render my scene with transparent and non-transparent objects by merging them to separate meshes.
My problem is not being able to highlight the picked objects effectively. I want the highlighting to be a non-transparent color. If a transparent object is picked I change the associated triangles' color attribute to match my highlight color with opacity of 1.0. But this does not work as I intend to because, since the merged mesh's material is transparent, the render order for it won't change although I set the opacity of its' triangles as 1.0. Result is poorly ordered objects on the screen.
I know I could use MultiMaterial but then number of drawcalls -may or may not- increase enormously if the user selects high number of objects. So I am looking for a better solution that will keep the same performance whatever happens.
Do you have any suggestions on how to solve this problem?
Is there a way to universally multiply physics2D calculations on the canvas?
I'm trying to make a set of canvas UI elements with 2D physic properties. The objects contain images and text, but need to respond to gravity, impacts, and overlapping collision boxes with other GUI elements.
I've added 2D RigidBody and boxCollider components to my objects. However, they move very slowly. If given a gravity, they fall slowly. If overlapped, they push each other apart slowly.
I've figured out that this is due to the canvas having a very large scale. My objects are effectively 'very big and very far away'.
I can't modify the canvas scale. It needs to be huge or I get render artifacts.
I can't just modify gravity because it doesn't provide a universal fix. Things fall faster, but they don't push apart or spring right.
I can't modify the timestep because it affects the whole world, not just the canvas.
My canvas objects have widths akin to 80, where unity physics expects widths akin to 1. How can I get them to behave like they have a width of 1?
Is there some universal scaling factor for canvas based physics, or am I simply mis-using the canvas for something it is not intended for?
if you are still having this problem, the answer to fixing the movement rates of your scaled-up objects is to scale up your movement forces as well as your gravity. If you can't get certain elements to work right, use a forcepush that you can set to any strength.
I'm using Unity 4.6 to develop a 2D game. I want to know if having a lot of GameObjects in the scene (out of the camera's sight) has a considerable influence on performance.
For example, is it efficient to make an scrollable list of names (like 1000 of them)? (each one is a GameObject and has a text, a button etc.)
I mask them in a specified area (for example 10 of them are visible at the same time).
Thanks in advance!
Depends on whether or not the objects have visible components. If they do, the engine will draw them even if they are 'off-camera'. A game object by itself has a pretty light load - a tile based game could have thousands in memory. You'll want to toggle the visibility of sprites if you plan on drawing a large number to the scene off-camera. This is where a SpriteManager comes in. It'll check to see if the sprite is in the camera's rectangle and disabled sprites that aren't. There is a semi-offical exmaple here that is good if a little complicated:
http://wiki.unity3d.com/index.php?title=SpriteManager
In a three.js project (viewable here) I have 500 cubes, all of the same size and all statically positioned. On each of these cubes, five of the faces always remain the same color; however, the color of the sixth face can be dynamically updated, and this modification occurs across many of the cubes in a single frame and also occurs across most frames.
I've been able to implement this scene several different ways, but I have not been completely satisfied with the performance of anything I've tried. I know I must not have hit upon the right technique yet or maybe I'm not implementing one quite right. From a performance standpoint, what is the best way to change the color of these cube faces while maintaining independence across each of the cubes?
Here is what I have tried so far:
Create 500 individual CubeGeometry and Mesh instances. Change the color of a geometry face as described in the answer here: Change the colors of a cube's faces. So far this method has performed the best for me, but 500 identical geometries seems less than ideal, especially because I'm not able to achieve a regular 60fps with a good GPU. Rendering takes about 11-20ms here.
Create one CubeGeometry and use it across 500 Mesh instances. Create an array of MeshBasicMaterials to create a MeshFaceMaterial for each Mesh. Five of the MeshBasicMaterial instances are the same, representing the five statically colored sides of each cube. Create a unique MeshBasicMaterial to add to the MeshFaceMaterial for each Mesh. Update the color of this unique material with thisMesh.material.materials[3].uniforms.diffuse.value.copy(newColor). This method renders quite slower than the first method, 90-110ms, which seems surprising to me. Maybe it's because 500 cubes with 6 materials each = 3000 materials to process???
Any advice you can offer would be much appreciated!
I discovered that three.js performs a WebGL draw for each mesh in your scene, and this is what was really hurting my performance. I looked into yaku's suggestion of using BufferGeometry, which I'm sure would be a great route, but using BufferGeometry appears to be relatively difficult unless you have a good amount of experience with WebGL/OpenGL.
However, I came across an alternative solution that was incredibly effective. I still created individual meshes for each of my 500 cubes, but then I used GeometryUtils.merge() to merge each of those meshes into a generic geometry to represent the entire group of cubes. I then used that group geometry to create a group mesh. An explanation of GeometryUtils.merge() is here.
What's especially nice about this tactic is that you still have access to all the faces that were part of the underlying geometries/meshes that you merge. In my project, this allowed me to still have full control over the face colors that I wanted control over:
// For 500 merged cubes, there will be 3000 faces in the geometry.
// This code will get the fourth face (index 3) of any cube.
_mergedCubesMesh.geometry.faces[(cubeIdx * 6) + 3].color