zeux / meshoptimizer

Mesh optimization library that makes meshes smaller and faster to render
MIT License
5.67k stars 481 forks source link

Corrupted textures after meshopt_optimizeOverdraw #624

Closed emeiri closed 1 year ago

emeiri commented 1 year ago

Hi,

I'm on the following commit:

commit f23b67d0965bcf52d00efb8d91e576666cf387bb (HEAD -> master, origin/master, origin/HEAD) Author: Arseny Kapoulkine arseny.kapoulkine@gmail.com Date: Sun Oct 15 09:03:44 2023 -0700

I load the model using Assimp and then optimize it with meshoptimizer. I've implemented the basic remapping as well as meshopt_optimizeVertexCache and everything is working correctly. However, after I execute meshopt_optimizeOverdraw the textures are completely corrupted.

The model I'm using is: https://casual-effects.com/g3d/data10/common/model/crytek_sponza/sponza.zip

Here's the relevant code:

// Vector3f is the same as glm::vec3 and Vector2f is the same as glm::vec2 struct Vertex { Vector3f Position;
Vector2f TexCoords; Vector3f Normal; };

// populated by Assimp vector m_Vertices; vector m_Indices;

// populated by meshoptimizer vector m_optVertices; vector m_optIndices;

std::vector remap(NumIndices); size_t OptVertexCount = meshopt_generateVertexRemap(remap.data(), m_Indices.data(), m_Indices.size(), m_Vertices.data(), m_Indices.size(), sizeof(Vertex)); m_optIndices.resize(m_Indices.size()); m_optVertices.resize(OptVertexCount);

// works OK: meshopt_remapIndexBuffer(m_optIndices.data(), m_Indices.data(), m_Indices.size(), remap.data()); meshopt_remapVertexBuffer(m_optVertices.data(), m_Vertices.data(), m_Vertices.size(), sizeof(Vertex), remap.data());

// works OK: meshopt_optimizeVertexCache(m_optIndices.data(), m_optIndices.data(), m_Indices.size(), OptVertexCount);

// this is where the problem starts: meshopt_optimizeOverdraw(m_optIndices.data(), m_optIndices.data(), m_Indices.size(), &(m_optVertices[0].Position.x), OptVertexCount, sizeof(Vertex), 1.05f);

I guess I'm missing something but I don't know what.

Thank you.

zeux commented 1 year ago

What does "corrupted textures" mean exactly?

emeiri commented 1 year ago

Without overdraw: good

With overdraw: bad

emeiri commented 1 year ago

After thinking a bit more I think I understand the problem. Assimp loads the model into multiple aiMesh structures. Each aiMesh has its own vertex/index vector. I concatenate all the vertices/indices together into a single vertex/index OpenGL buffer but I still render them piece by piece because I have to switch textures between the meshes. The optimization occurs on the complete buffer so naturally it messes up the order between the meshes. I guess I need to optimize each mesh separately.

zeux commented 1 year ago

Yeah, that's correct - you need to optimize each mesh separately. If you want to still merge the buffers, you can merge them but you need sure that you run both meshopt_optimizeVertexCache and meshopt_optimizeOverdraw on each individual mesh subset (index range). Other functions don't disturb the order; I suspect you just happened to not notice issues with meshopt_optimizeVertexCache.

emeiri commented 1 year ago

Thanks a lot for your prompt response. I've optimized each mesh separately and now the overdraw works correctly. Cheers!