Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Is there any way to override the bounds for a renderer because I have some vertex animation in shade

Discussion in 'General Graphics' started by watsonsong, Oct 31, 2018.

  1. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    I have some vertex animation in shader and I want to override the bounds of a renderer. I don't want to set the mesh's bounds because different renderer use the same mesh with different shader uniform property. So each renderer have different bounds.
    How can I override a new bounds to a renderer to avoid incorrect camera cull?
     
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
  3. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    But this option is used for occlusion culling I think, it not used for camera frustum culling.
    On the other hand, if I disable all culling for a renderer, should I add a new cull group to it to apply my own bounds?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,243
    You cannot disable culling on a renderer component. You can disable occlusion, but frustum culling is always enabled. You can get around that by drawing the object manually with DrawMeshNow, DrawMeshInstanced, or DrawProcedural, but these can be a pain for simple setups.

    The easiest solution, apart from modifying the mesh bounds directly, is to always make your shader only move or scale an object within the bounds of the original mesh. What I mean by that is you should scale up the renderer's game object, and scale it down in the shader. That way the renderer's bounds are larger, but the mesh appears unscaled.
     
    Alic likes this.
  5. Pangamini

    Pangamini

    Joined:
    Aug 8, 2012
    Posts:
    54
    I have found a placeholder solution that seems to work efficiently enough(so far).
    I created a CustomRenderer script that uses MeshRenderer and MeshFilter. On initialization, I create an empty mesh that only defines bounds, and assign that to the filter. I listen to OnBecameVisible() and OnBecameInvisible() to hook to Camera.onPreCull (I cannot use OnWillRenderObject() as it's too late for submit Graphics.DrawMesh at this stage).
    Then, on the preCull callback, I call Graphics.DrawMesh with all the data available from the MeshRenderer itself, including material, light probe transform, materialPropertyBlock, etc.
    The empty mesh doesn't have any submeshes and therefore produces zero drawcalls, it's merely used for the culling information.
    Now I have a writable bounds, since every CustomRenderer has its own empty mesh with custom bounds. The last thing to be solved is the fact that DrawMesh is still due for culling. Luckily, it seems that the bounds are stored at the time when DrawMesh is called, so what I can do is to change the actual rendered mesh bounds right before calling DrawMesh, and immediately change it back (possibly in a finally block, to be safe).
    It's far from ideal, as the frustum culling is now done twice (once per dummy mesh and once per DrawMesh). But it's the best solution I could come up with, it works correctly with shadowcaster culling and multiple cameras.
     
    watsonsong likes this.
  6. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    It's a good way, as it said theculling will do twice.
    I think if we use the Unity2021.2, the new Graphic.RenderMesh seems can specify a world bounds directly.
     
  7. ChillinTech

    ChillinTech

    Joined:
    Aug 12, 2018
    Posts:
    5
    I know that was posted a while ago but just for others, you can definitely modify the bounds of the renderer these days. I edit the bounds specifically because i change vertices in the shader and it messes with the frustum culling:
    Code (CSharp):
    1.     void Start() {
    2.         Mesh m = GetComponent<MeshFilter>().mesh;
    3.         m.bounds = new Bounds(Vector3.zero, Vector3.one * 10);
    4.     }
    I would keep a very close eye on performance though, depending on the application.
     
    CrazyCode_ and deus0 like this.
  8. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    This is modify the bounds of the Mesh, not the renderer.
    If there has two different renderer use the same mesh, but with different shader properties to do vertex animation. Modify the bounds of the mesh seems not work.
     
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,243
    The bounds of a Mesh Renderer component are calculated using the bounds of the mesh transformed into a world AABB. The only way to modify the bounds of the Mesh Renderer is by modifying the bounds of the mesh itself.

    If you have two Mesh Renderer components both using the same mesh and the vertex animation for one is offsetting it enough that it is disappearing, that just means you didn't increase the bounds enough. Or you're not actually using the mesh with the modified bounds.
     
  10. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    This is not the same problem. You mean use the max bounds the vertex animation might has. But I record the bounds sequence and want more correct bounds for each animation frame for better culling result.
     
  11. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,243
    Then you'll either have to use several unique meshes, or cull the game objects yourself manually using your more confined bounds data.
     
  12. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,240
    JCO123456 and olavrv like this.
  13. Neto_Kokku

    Neto_Kokku

    Joined:
    Feb 15, 2018
    Posts:
    1,751
    Be aware that by merely reading the .mesh property Unity will create a complete duplicate of the Mesh for that specific MeshFilter. If you are using additive scene loading, that Mesh will stick around in memory untill you either load a scene non-additively, call Resources.UnloadUnusedAssets(), or destroy the Mesh yourself. It's the same "trap" as accessing a renderer .material property.