What is the best way to render triangles using three-d?

I'm working on a 3D editor in Rust using three-d. I have an input which is a Vector of triangles each with a pre-defined colour. I need to be able to render all these triangles into a model. Although my current approach works, it's really laggy:

pub fn build_model(&self, context: &Context) -> Vec<Gm<Mesh, ColorMaterial>> {
        let mut gm: Vec<Gm<Mesh, ColorMaterial>> = Vec::new();

        for tri in &self.tris {
            let mesh = Gm::new(
                Mesh::new(
                    &context,
                    &CpuMesh {
                        positions: Positions::F32(tri.vertices.clone()),
                        colors: Some(vec![
                            Color {
                                r: (tri.color[0] * 255.) as u8,
                                g: (tri.color[1] * 255.) as u8,
                                b: (tri.color[2] * 255.) as u8,
                                a: (tri.color[3] * 255.) as u8,
                            };
                            3
                        ]),
                        ..Default::default()
                    },
                ),
                ColorMaterial::default(),
            );

            gm.push(mesh);
        }
        gm
    }

I then proceed to use that Vector of Gms in my render loop:

frame_input.screen()
            .clear(ClearState::color_and_depth(0.8, 0.8, 0.8, 1.0, 1.0))
            .render(
                &camera, &gm, &[]
            );

I think a better way to do this would be to construct 1 model out of all these triangles rather than creating individual meshes for each triangle and rendering them individually. But I've tried to read the documentation and code examples and can't figure out how to do this.
Any help much appreciated!

I am not familiar with three_d but it should be just a matter of putting all of your vertices in one set of attribute (position, color) vectors:

pub fn build_model(&self, context: &Context) -> Gm<Mesh, ColorMaterial> {
    let mut positions = Vec::new();
    let mut colors = Vec::new();
    for tri in &self.tris {
        positions.extend(tri.vertices);
        colors.extend(
            [Color {
                r: (tri.color[0] * 255.) as u8,
                g: (tri.color[1] * 255.) as u8,
                b: (tri.color[2] * 255.) as u8,
                a: (tri.color[3] * 255.) as u8,
            }; 3],
        );
    }

    Gm::new(
        Mesh::new(
            &context,
            &CpuMesh {
                positions,
                colors,
                ..Default::default()
            },
        ),
        ColorMaterial::default(),
    )
}

The GPU will then take each successive 3 vertices in the vectors as a separate triangle.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.