Create & render Mesh using job System

Hello,
currently i am experimenting with the Mesh creation and rendering using Jobsystem.
i have created Mesh Procedurally by passing the ]Native Array data to The Job system and getting it back on the main thread.
I know that reference type data is not supported inside IJob Struct.
Once i get the Native Array data for the Mesh.Is there any way i can attach this Mesh to the entity created using Jobsystem. or render it with Jobsystem?

The whole point is i want to render the mesh using pure ecs /jobsystem for which i just have Nattive Array Data of mesh.

I will be crossing this bridge very soon so I’ve been collection other members example and post on the way. I have not read it yet but maybe this will help

https://github.com/keijiro/Voxelman

Let me know how it works out for you.

2 Likes

@francois85 Thanks for sharing the links. I went through the few of the links. and have been able to create mesh and Entity using Jobsystem. Passing Native Array Data to and fro ,from main thread and Worker Threads. now the only part pending is rendering the mesh in an efficient manner,perhaps on the main thread and Generating thousands of mesh instance at runtime.

OK started on this. Here is where im at. Did a super rough fist pass any critique would be appreciated. The code is ugly so please rip into any of it so I can refactor it as best as possible.

The good news is the data is correct and a mesh is building with live sub scenes and a bunch of embedded data on the entities for pathfinding and shader so pretty happy.

        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            EntityQuery qTriangleComponent = GetEntityQuery(ComponentType.ReadOnly<TriangleComponent>());
            if (qTriangleComponent.CalculateChunkCount() == 0)
            {
                //inputDeps.Complete();
                return inputDeps;
            }
              
                //
                // Get data
                var hexSphereBuildComponent = GetSingletonEntity<HexSphereBuildDataComponent>();
            hexSphereBuildDataSingleton = EntityManager.GetComponentData<HexSphereBuildDataComponent>(hexSphereBuildComponent);
            //int vertexBufferSize = hexSphereBuildDataSingleton.VertexCount * 3;
            int triangleBufferSize = hexSphereBuildDataSingleton.TriangleCount * 3;

            //
            // Schedule CreateMeshBuildBuffers
            var vertcesBuffer = new NativeArray<Vector3>(triangleBufferSize, Allocator.Persistent);
            var trianglesBuffer = new NativeArray<int>(triangleBufferSize, Allocator.Persistent);
            var normalsBuffer = new NativeArray<Vector3>(triangleBufferSize, Allocator.Persistent);
            var tangentsBuffer = new NativeArray<Vector4>(triangleBufferSize, Allocator.Persistent);
            var uvs01Buffer = new NativeArray<Vector2>(triangleBufferSize, Allocator.Persistent);
            var uvs02Buffer = new NativeArray<Vector2>(triangleBufferSize, Allocator.Persistent);
            var colorsBuffer = new NativeArray<int>(triangleBufferSize, Allocator.Persistent);

            inputDeps = new CreateMeshBuildBuffers()
            {
                VertcesBuffer = vertcesBuffer, //new NativeArray<Vector3>(triangleBufferSize, Allocator.TempJob),
                TrianglesBuffer = trianglesBuffer, // new NativeArray<int>(triangleBufferSize, Allocator.TempJob),
                NormalsBuffer = normalsBuffer, //new NativeArray<Vector3>(triangleBufferSize, Allocator.TempJob),
                TangentsBuffer = tangentsBuffer, //new NativeArray<Vector4>(triangleBufferSize, Allocator.TempJob),
                UVs01Buffer = uvs01Buffer, //new NativeArray<Vector2>(triangleBufferSize, Allocator.TempJob),
                UVs02Buffer = uvs02Buffer, //new NativeArray<Vector2>(triangleBufferSize, Allocator.TempJob),
                ColorsBuffer = colorsBuffer, //new NativeArray<int>(triangleBufferSize, Allocator.TempJob),
                DTileVertex = GetComponentDataFromEntity<TileVertexComponent>(true)
            }.ScheduleSingle(this, inputDeps);



            //
            // Complete
            inputDeps.Complete();

            hexMesh = GameObject.FindGameObjectWithTag("tagHexMeshGameObject").GetComponent<MeshFilter>().mesh;// GetComponent<MeshFilter>().sharedMesh;
            if (hexMesh == null)
                throw new System.ArgumentNullException("GameObject.FindGameObjectWithTag(tagHexMeshGameObject).GetComponent<MeshFilter>()");

            //TODO: If we go over 6 sub we need to use 32bin on mesh indexing
            hexMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            hexMesh.name = "HexShere";
            hexMesh.vertices = vertcesBuffer.ToArray();
            hexMesh.normals = normalsBuffer.ToArray();
            hexMesh.uv = uvs01Buffer.ToArray();
            hexMesh.tangents = tangentsBuffer.ToArray();
            hexMesh.triangles = trianglesBuffer.ToArray();
            //hexMesh.uv2 = uvs02Buffer.ToArray();
            //hexMesh.colors = colorsBuffer.ToArray();
            //hexSphereMesh = hexMesh;
         
            vertcesBuffer.Dispose();
            normalsBuffer.Dispose();
            uvs01Buffer.Dispose();
            tangentsBuffer.Dispose();
            trianglesBuffer.Dispose();
            uvs02Buffer.Dispose();
            colorsBuffer.Dispose();

            return inputDeps;
        }
1 Like

If you’re using 2019.3 you can use the new overloads and just pass the native array direct

public void SetVertices(NativeArray inVertices);

Otherwise if you want to avoid creating garbage you can just add it to a List and set it with that like I did on my old MeshSystem

7 Likes

ahh good to know, I w

Thank you i will check it out.