gaiku icon indicating copy to clipboard operation
gaiku copied to clipboard

Improve Mesh/MeshBuilder, if possible

Open norman784 opened this issue 4 years ago • 8 comments

Right now we add a new pair of Position/Normal/UV, we check against all elements to see if they are duplicate or not, this leads to generate a lot of indices and vertices, if we export our mesh to .obj file we get:

o mesh_0
v 1.000000 1.000000 0.000000
v 0.000000 1.000000 0.000000
v 1.000000 1.000000 1.000000
v 0.000000 1.000000 1.000000
v 0.000000 0.000000 0.000000
v 1.000000 0.000000 0.000000
v 0.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v 0.000000 1.000000 1.000000
v 0.000000 1.000000 0.000000
v 0.000000 0.000000 1.000000
v 0.000000 0.000000 0.000000
v 1.000000 1.000000 0.000000
v 1.000000 1.000000 1.000000
v 1.000000 0.000000 0.000000
v 1.000000 0.000000 1.000000
v 1.000000 1.000000 1.000000
v 0.000000 1.000000 1.000000
v 1.000000 0.000000 1.000000
v 0.000000 0.000000 1.000000
v 0.000000 1.000000 0.000000
v 1.000000 1.000000 0.000000
v 0.000000 0.000000 0.000000
v 1.000000 0.000000 0.000000
vt 0.000000 0.937500
vt 0.062500 0.937500
vt 0.000000 1.000000
vt 0.062500 1.000000
vt 0.000000 0.937500
vt 0.062500 0.937500
vt 0.000000 1.000000
vt 0.062500 1.000000
vt 0.000000 0.937500
vt 0.062500 0.937500
vt 0.000000 1.000000
vt 0.062500 1.000000
vt 0.000000 0.937500
vt 0.062500 0.937500
vt 0.000000 1.000000
vt 0.062500 1.000000
vt 0.000000 0.937500
vt 0.062500 0.937500
vt 0.000000 1.000000
vt 0.062500 1.000000
vt 0.000000 0.937500
vt 0.062500 0.937500
vt 0.000000 1.000000
vt 0.062500 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
f 1/1/1 2/2/2 3/3/3
f 2/2/2 4/4/4 3/3/3
f 5/5/5 6/6/6 7/7/7
f 6/6/6 8/8/8 7/7/7
f 9/9/9 10/10/10 11/11/11
f 10/10/10 12/12/12 11/11/11
f 13/13/13 14/14/14 15/15/15
f 14/14/14 16/16/16 15/15/15
f 17/17/17 18/18/18 19/19/19
f 18/18/18 20/20/20 19/19/19
f 21/21/21 22/22/22 23/23/23
f 22/22/22 24/24/24 23/23/23

While blender generates

o Cube_Cube.001
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vt -0.002071 0.500793
vt 0.500071 0.500793
vt 0.500071 1.002934
vt -0.002071 1.002934
vt 0.001491 0.500907
vt 0.498970 0.500907
vt 0.498970 0.998387
vt 0.001491 0.998387
vt 0.000900 0.500561
vt 0.499561 0.500561
vt 0.499561 0.999222
vt 0.000900 0.999222
vt 0.000020 0.503617
vt 0.497980 0.503617
vt 0.497980 1.001577
vt 0.000020 1.001577
vt 0.001347 0.503713
vt 0.496164 0.503713
vt 0.496164 0.998531
vt 0.001347 0.998531
vt 0.004237 0.509806
vt 0.494253 0.509806
vt 0.494253 0.999821
vt 0.004237 0.999821
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
usemtl None
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/5/2 4/6/2 8/7/2 7/8/2
f 7/9/3 8/10/3 6/11/3 5/12/3
f 5/13/4 6/14/4 2/15/4 1/16/4
f 3/17/5 7/18/5 5/19/5 1/20/5
f 8/21/6 4/22/6 2/23/6 6/24/6

A quick look into Bevy source code seems to not supporting this feature, while in Amethyst I'm not sure, the documentation for the current version is broken in docs.rs and the source code is complicated.

norman784 avatar Jan 17 '21 15:01 norman784

Also not sure if this is related, but it generates artifacts in Blender. Steps to reproduce:

  • Run the voxel example in gaiku-3d
  • Open the small_tree.obj
  • Apply the texture to all meshes.
  • Set the Interpolation as Closest (Linear also has some artifacts, but that seems to be another issue).

image

** Notes

Right now the UVs starts top left, and the texture bottom left, so to fix that you should change the next line

https://github.com/norman784/gaiku/blob/b1d705ccb90ebc6eb5e0dc667939e7aa1cfab4f9/gaiku-common/src/texture.rs#L82

with

let y_o = ((1.0 - COL_SIZE - uv.1) * self.texture.height() as f32).floor() as u32; 

Maybe there's a better way, but for now seems to do the job.

norman784 avatar Jan 17 '21 15:01 norman784

With the linear interpolation the tree looks like this

image

norman784 avatar Jan 17 '21 15:01 norman784

While blender generates

I don't think blender will be directly comparable. Blender has the concept of shared vertices so one vertex can have multiple UV coorniates and normals at the same time while game engines dont do this, probably for render speed.

If you look at the blender export you will see that there are only 6 normals but 8 vertices. These are not vertex normals but face normals. Again something game engines dont use.

We duplicate vertices when the atlas index changes but if two indexes neighbour each other in the atlas and in 3d we could not duplicate the connecting uvs.

Blender is also using quads for the faces while we use triangles. Also somethig game engines dont typically do.

If we really wanted to replicate blender we could add the conpcept of shared vertices and quads then when baking to the appropriate format decide wether to split them or not. It's probably not worth the cognitive load though.

Edit: I see the faces at the end of the obj file format is a list of indices. Vertex/normal/UV indices. We could replicate this somewhat by storing UV and normal data as an index internally instead.

QuantumEntangledAndy avatar Jan 17 '21 23:01 QuantumEntangledAndy

Also not sure if this is related, but it generates artifacts in Blender.

This artifact is maybe to do with how just a few pixels are being stretched over a relatively large face. This might improve with larger texture sizes so that the size of the face in 3d roughly matches that in the 2d texture at desired viewing distance.

QuantumEntangledAndy avatar Jan 17 '21 23:01 QuantumEntangledAndy

Also not sure if this is related, but it generates artifacts in Blender.

This artifact is maybe to do with how just a few pixels are being stretched over a relatively large face. This might improve with larger texture sizes so that the size of the face in 3d roughly matches that in the 2d texture at desired viewing distance.

I've added a small padding and this issue seems to be solved check #31 more for details.

norman784 avatar Jan 17 '21 23:01 norman784

We could certainly improve the mesh with storage of normals. There are only 6 normals possible. So rather than store them all on each vertext we could just store an index to the normal in the vertex data. This would probably be best done with a normals octree so that we could reliably compare them (which would save createing that boudatmry for the normal inside the current normal comparison code).

QuantumEntangledAndy avatar Jan 17 '21 23:01 QuantumEntangledAndy

Could probably do something similar for UV too.

Could maybe also store face data as triple index too position/normal/UV but this would add more load to the baker

QuantumEntangledAndy avatar Jan 18 '21 00:01 QuantumEntangledAndy

I am thinking three octrees. Position normal uv. We represent a mesh as three tables position normal UV and a set of faces. Each face stores the index of position normal and UV.

When adding a face we look up the octrees seperatly. Which reduces the code for check duplicates considerably which is nice. This does mean however that we cannot add per vertex only per face. Edit: actually if the number of vertices in a face is flexible a single vertex could be added as a face of size one. A triangle a face of size three and a quad a face of size four. But again this would be more load on the baker to trianlize the quads.

QuantumEntangledAndy avatar Jan 18 '21 00:01 QuantumEntangledAndy