gwihlidal / meshopt-rs

Rust ffi and idiomatic wrapper for zeux/meshoptimizer, a mesh optimization library that makes indexed meshes more GPU-friendly.
Apache License 2.0
163 stars 33 forks source link

Simplify does not affect the mesh (And simplify_sloppy do) #37

Closed axel-denis closed 8 months ago

axel-denis commented 8 months ago

Hi, I'm encountering some bug, here is some information :

Working code :

let mut lod: Vec<u32>;
    {
        let src = &mesh.indices;
        lod = meshopt::simplify_sloppy(
            src,
            vertex_adapter,
            ::std::cmp::min(src.len(), target_index_count),
            target_error,
            None,
        );
    }

    println!("finalizing lod {}...", display_id);
    meshopt::optimize_vertex_cache_in_place(&mut lod, vertex_adapter.vertex_count);
    meshopt::optimize_overdraw_in_place(&mut lod, &vertex_adapter, 1f32);

This snippet uses simplify_sloppy and works well. But for my project, I want to use the simplify function to keep mesh borders and texture, so here is the new code :

    let mut lod: Vec<u32>;
    {
        let src = &mesh.indices;
        lod = meshopt::simplify(
            src,
            vertex_adapter,
            ::std::cmp::min(src.len(), target_index_count),
            target_error,
            SimplifyOptions::LockBorder,
            None,
        );
    }

    println!("finalizing lod {}...", display_id);
    meshopt::optimize_vertex_cache_in_place(&mut lod, vertex_adapter.vertex_count);
    meshopt::optimize_overdraw_in_place(&mut lod, &vertex_adapter, 1f32);

Basically the same thing except I'm changing the function to simplify I'm adding a SimplifyOptions::LockBorder parameter

But with the same input settings, simplify_sloppy will create a nice lod, while simplify will almost not change the mesh. See :

simplify_sloppy : image

simplify : image

As you can see, simplify is barely affecting the mesh. I don't know if it's a bug or if I'm doing something wrong. I tried with a ton of parameters and can't make it work. Thank you for any help !

Uriopass commented 8 months ago

What is your target_error and target_index_count?

axel-denis commented 8 months ago

What is your target_error and target_index_count?

If I create 3 lods, I'll have :

Before staying on these values I tested others, without success

Uriopass commented 8 months ago

The first simplification algorithm, meshopt_simplify, follows the topology of the original mesh in an attempt to preserve attribute seams, borders and overall appearance. For meshes with inconsistent topology or many seams, such as faceted meshes, it can result in simplifier getting "stuck" and not being able to simplify the mesh fully. Therefore it's critical that identical vertices are "welded" together, that is, the input vertex buffer does not contain duplicates.

Could you share the model? Beware that if you shaded the faces as "flat" then blender will duplicate the vertices (not a bug).

axel-denis commented 8 months ago

Here is the file. I honestly don't remember if it was flat shaded :( But it does the same on models that where not made in Blender cube.zip

Uriopass commented 8 months ago

I confirm, the faces are flat-shaded, so the vertices are duplicated. This is exactly the "faceted mesh" the doc talks about. For the simplifier, there are just thousands of islands it can't do anything with.

Here's the smooth-shaded version if you want to try it out :) cube.zip

But it does the same on models that where not made in Blender

This is not a blender specific issue, flat shaded implies the exporter needs to duplicate the vertices to make sure the normals are correct.