Creating a mesh in code, only a few triangles visible

(Peter Verbrugge) #1

I’m currently writing an asset loader responsible for loading an heightmap and producing a mesh. Unfortunately i’m encountering problems generating the actual mesh.

I’m iterating over the pixels from 0, 0 to 63, 63 first over the rows then the columns, i was searching for a way to match this to the generation of triangles. I found the solution in the form of a MeshBuilder set to generating using a TriangleStrip. It generates triangles byte iterating over a list of positions [a, b, c, d, e] and then creating the triangles [a, b, c], [b, c, d] and [c, d, e].

By iterating over the pixels in a (0, 0), (1, 0), (2, 0) fashion and continuously appending the pixel coordinate and the pixel below it i’m creating a sort of sawtooth of triangles. (0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1). This in combination with the TriangleStrip should provide me with a nice, filled, rectangle.

But, it doesn’t. Half of the triangles aren’t even visible, when i view the mesh from the bottom different triangles are visible. Could anyone tell me whether my idea is flawed and/or point me in the right direction?

    fn import_simple(&self, bytes: Vec<u8>) -> Result<MeshData, Error> {
    let height_map = load_from_memory(&bytes)?.to_luma();
    let mut pos = Vec::new();
    let mut norm = Vec::new();
    let mut tex = Vec::new();
    for (pixel_x, pixel_y, pixel_luma) in height_map.enumerate_pixels() {
        let point = Vector3::new(pixel_x as f32, pixel_y as f32, 0.0); //pixel_luma.0.first()? as f32);

        pos.push(Position([point.x, point.y, point.z]));
        norm.push(Normal([0.0, 0.0, 1.0]));
        tex.push(TexCoord([0.0, 0.0]));

        pos.push(Position([point.x, point.y + 1.0, point.z]));
        norm.push(Normal([0.0, 0.0, 1.0]));
        tex.push(TexCoord([0.0, 0.0]));
    }
    Ok(MeshBuilder::new()
        .with_prim_type(Primitive::TriangleStrip)
        .with_vertices(pos)
        .with_vertices(norm)
        .with_vertices(tex)
        .into())
}

And perphaps it’s necessary, this is the bundle for my rendering configuration:

.with_bundle(
        RenderingBundle::<DefaultBackend>::new()
            .with_plugin(
                RenderToWindow::from_config_path(display_config_path)?
                    .with_clear([0.34, 0.36, 0.52, 1.0]),
            )
            .with_plugin(RenderShaded3D::default())
            .with_plugin(RenderSkybox::with_colors(
                Srgb::new(0.82, 0.51, 0.50),
                Srgb::new(0.18, 0.11, 0.85),
            )),
    )
#2

I am guessing it’s due to back face culling. Front face is determined by vertex order and by default it is counter-clockwise (I stand corrected for this). Try swapping the order of vertices that are not visible from the front.

(Abovegame) #3

Well TriangleStrip ignores the face winding order, i think it uses Clockwise and then CounterClockwise for the same quad.

(Chris Howard) #4

I just had a similar issue. Try swapping one of the normals to 0.0, 0.0, -1.0

(Peter Verbrugge) #5

Thanks for pointing me in the right direction.
Unfortunately i was still unable to get this to work with TriangleStrip. It indeed draws every triangle in a different direction.
Therefore i went back and successfully implemented it with a TriangleList, changing the normals there did help me out.