Hi I have a procedurally generated mesh. The mesh is very large, and its center is at a different location than the literal center. The problem is… When the mesh center is outside of the view, the entire mesh disappears. Having done some research into this, I found out that this is frustum culling… The solution supposedly is to do mesh.RecalculateBounds. My code is actually all ready doing that, and the mesh actually used to work! However I created some code to delete about 6 tris from the very large mesh of around 128 thousand tris. All of a sudden, I am getting frustum culling issues. I even tried UNDOING the code (only the part that SETS the tris, there is some code that GETS the tris after the bounds are recalculated) and I am still having issues. I’ve also turned on bounds calculation AFTER I delete the tris… No effect. However, according to Unity this is not even necessary as bounds are recalculated on triangle edit ANYHOW! It would seem that Unity is not properly calculating the bounds (I actually have had issues with normal calculation as well, but I got around that using a different calculation system). Is there a way to get Unity to, A: Forsake frustum culling for this object, or B: Correctly calculate the bounds? Stupid question, but, would manually calculating the bounds of my object to surround my object work?
It seems Unity have some problem about calculating mesh bounds - I’ve heard about this disappeared mesh issue before. Maybe a better approach could be set yourself the mesh bounds: you can save the min and max x, y and z coordinates when calculating the vertices, then set the bounds with collider.bounds.SetMinMax(min, max):
var max = Vector3.one * Mathf.NegativeInfinity; var min = Vector3.one * Mathf.Infinity; var vert: Vector3; for (...){ vert = ...// calculate each vertice as before... // then check min and max points if (vert.x < min.x) min.x = vert.x; if (vert.x > max.x) max.x = vert.x; if (vert.y < min.y) min.y = vert.y; if (vert.y > max.y) max.y = vert.y; if (vert.z < min.z) min.z = vert.z; if (vert.z > max.z) max.z = vert.z; } ...
When all vertices were calculated, set the bounds:
collider.bounds.SetMinMax(min, max);
NOTE: I suppose the calculated bounds will remain valid until you rotate the mesh - since the bounds are aligned to the axes, the bounds should be recalculated after each rotation.
EDITED: I found other questions about this same problem, and the @Lemon answer in this question seems a good way to “fool” the frustum culling and ensure that your mesh will always be considered visible. Basically, @Lemon forces the mesh’s bounds to be a big cube in front of the camera, and this trick seems to solve his problem. I posted a modified version of his script, where bounds are saved and modified in LateUpdate, and restored after culling and rendering in OnRenderObject :
Bounds svBounds; void LateUpdate(){ Transform camTransform = Camera.main.transform; float distToCenter = (Camera.main.farClipPlane - Camera.main.nearClipPlane) / 2.0f; Vector3 center = camTransform.position + camTransform.forward * distToCenter; float extremeBound = 500.0f; MeshFilter meshFilter = GetComponent(); svBounds = meshFilter.sharedMesh.bounds; meshFilter.sharedMesh.bounds = new Bounds (center, new Vector3.one * extremeBound); } void OnRenderObject(){ MeshFilter meshFilter = GetComponent(); meshFilter.sharedMesh.bounds = svBounds; }
Use RecalculateBounds() after you assign the mesh to a MeshFilter component. So for example in C#:
GetComponent().mesh = aMeshObject;
aMeshObject.RecalculateBounds();
This way it will recalculate renderer bounds.
Use RecalculateBounds() after you assign the mesh to a MeshFilter component. So for example in C#:
GetComponent().mesh = aMeshObject;
aMeshObject.RecalculateBounds();
This way it will recalculate renderer bounds.
Use RecalculateBounds() after you assign the mesh to a MeshFilter component. So for example in C#:
GetComponent().mesh = aMeshObject;
aMeshObject.RecalculateBounds();
This way it will recalculate renderer bounds.