Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do I change mesh vertices for a mesh rendered with the Tiny Renderer at runtime?

Discussion in 'Project Tiny' started by EdRowlett-Barbu, Jan 7, 2020.

  1. EdRowlett-Barbu

    EdRowlett-Barbu

    Joined:
    Mar 16, 2015
    Posts:
    88
    So I'm trying to change a mesh at runtime, namely just vertex positions. Below is an code excerpt from a ComponentSystem, running on the main thread. Trying to change a default unity cube that's been converted through unity subscene conversion. The cube is targetEntity in the code below.
    I was expecting the cube vertices to go up and down, but that doesn't happen, the cube remains unchanged. What am I missing?
    I have a feeling maybe the updated mesh isn't being re-uploaded to the GPU? How would I do that? I didn't find a way to mark it dirty.

    EDIT: I think I found the issue, but I still need a solution, I don't know how to proceed.
    RendererBGFX.cs line 708 inside UploadMeshes().
    So the mesh data from LitMeshRendererData gets turned into a SimpleMeshBGFX and uploaded onto gpu. It remains cached inside SimpleMeshBGFX which gets added to the mesh entity. Any subsequent changes to LitMeshRendererData won't trigger a reupload of the mesh. A simple solution would be to remove SimpleMeshBGFX component from the mesh entity, after changing the LitMeshRendererData, but there's no way to do that since SimpleMeshBGFX is an internal data type.

    What should I do?


    Edit2: I might have found a way. Instead of trying to remove SimpleMeshBGFX, I remove the entire mesh entity. Then I create a new mesh entity from scratch, with new BlobAssetReference<LitMeshData>() on it, inside the LitMeshRendererData component.

    I had to change SimpleMeshBGFX from IComponentData to ISystemStateComponentData, I think that's how it should have been in the first place, so the render system can free the graphics memory when the entity containing the SImpleMeshBGFX gets removed.
    Then I added the code below in RendererBGFX's OnUpdate(), to cleanup the mesh memory. It's not entirely correct, as it will remove any SimpleMeshBGFX, but I don't use those, I only use LitMeshRenderData. This seems to work for now, doesn't seem to leak any memory I think.
    Here's the resulting Tiny browser build, with physics, transform animations, and now a good basis for skinned mesh rendering, now that i can manipulate the mesh data.
    http://ec2-13-48-172-110.eu-north-1...95/wwwroot/DotsRTBuildSettings/ChaosTech.html

    I'm happy to see Tiny is pretty close to being usable for production, if working around its current limitations. Since I'm not clear yet on when a UI solution will be available for Tiny, I think I'll just go ahead and roll my own, and with that, seems like most of the basic functionality is there for making games with it.

    Hope this helps other people.

    Code (CSharp):
    1.  
    2.             Entities.WithNone<LitMeshRenderData>().ForEach((Entity e, ref SimpleMeshBGFX mesh) =>
    3.             {
    4.                 DestroyMesh(ref mesh);
    5.                 EntityManager.RemoveComponent<SimpleMeshBGFX>(e);
    6.             });
    7.  

    original, non functioning code.
    Code (CSharp):
    1.                       // test anim
    2.                         if (EntityManager.HasComponent<MeshRenderer>(targetEntity))
    3.                         {
    4.                             var mr = EntityManager.GetComponentData<MeshRenderer>(targetEntity);
    5.              
    6.                             var lmr = EntityManager.GetComponentData<LitMeshReference>(targetEntity);
    7.                             var lmrd = EntityManager.GetComponentData<LitMeshRenderData>(lmr.mesh);
    8.              
    9.                             AnimateMesh(ref lmrd.Mesh.Value);
    10.                             EntityManager.SetComponentData<LitMeshRenderData>(lmr.mesh, lmrd);
    11.              
    12.                         }
    13.                     }    
    14.                 }
    15.  
    16.  
    17.             });
    18.         }
    19.  
    20.         void AnimateMesh(ref LitMeshData meshData)
    21.         {
    22.             ref var verts = ref meshData.Vertices;
    23.             for (int i = 0; i < verts.Length; ++i)
    24.             {
    25.                 ref var v = ref verts[i];
    26.                 var pos = v.Position;
    27.                 pos.y += (float)math.sin(Time.ElapsedTime - pos.z);
    28.                 v.Position = pos;
    29.                 verts[i] = v;
    30.             }
    31.         }
    32.  
     
    Last edited: Jan 7, 2020
  2. sebastianm_unity

    sebastianm_unity

    Unity Technologies

    Joined:
    May 3, 2018
    Posts:
    21
    I am currently working on an API and example for runtime procedural geometry. It should be available with the next release (or one past that).
    Currently there is simply no nice way to do this - but it has been a number 1 feature request so far, and we are on it!
     
    T-Zee, RemIsWho, Thaina and 2 others like this.
  3. EdRowlett-Barbu

    EdRowlett-Barbu

    Joined:
    Mar 16, 2015
    Posts:
    88
    Thanks, that's great news. In the meantime, is my approach ok, or do you think it will cause issues that I haven't noticed yet?
     
  4. Sarkahn

    Sarkahn

    Joined:
    Jan 9, 2013
    Posts:
    440
    Just wanted to say I would love to switch to Tiny with my current project but I really need an api for dynamic runtime meshes. Any news on this front?
     
  5. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    230
    Yep! It's coming in 0.23.
     
    T-Zee and Sarkahn like this.