Search Unity

  1. Click here to see what's on sale for the "Best of Super Sale" on the Asset Store
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    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


    Mar 16, 2015
    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.

    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):
    2.             Entities.WithNone<LitMeshRenderData>().ForEach((Entity e, ref SimpleMeshBGFX mesh) =>
    3.             {
    4.                 DestroyMesh(ref mesh);
    5.                 EntityManager.RemoveComponent<SimpleMeshBGFX>(e);
    6.             });

    original, non functioning code.
    Code (CSharp):
    1.                       // test anim
    2.                         if (EntityManager.HasComponent<MeshRenderer>(targetEntity))
    3.                         {
    4.                             var mr = EntityManager.GetComponentData<MeshRenderer>(targetEntity);
    6.                             var lmr = EntityManager.GetComponentData<LitMeshReference>(targetEntity);
    7.                             var lmrd = EntityManager.GetComponentData<LitMeshRenderData>(lmr.mesh);
    9.                             AnimateMesh(ref lmrd.Mesh.Value);
    10.                             EntityManager.SetComponentData<LitMeshRenderData>(lmr.mesh, lmrd);
    12.                         }
    13.                     }    
    14.                 }
    17.             });
    18.         }
    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.         }
    Last edited: Jan 7, 2020
  2. sebastianm_unity


    Unity Technologies

    May 3, 2018
    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


    Mar 16, 2015
    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


    Jan 9, 2013
    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


    Unity Technologies

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