Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Loading GLTF files 📂

renderling's built-in model format is GLTF, a versatile and efficient format for transmitting 3D models. GLTF, which stands for GL Transmission Format, is designed to be a compact, interoperable format that can be used across various platforms and applications. It supports a wide range of features including geometry, materials, animations, and more, making it a popular choice for 3D graphics.

Using GLTF files

The previous section on staging resources covered the creation of various GPU resources such as Camera, Vertices, Material, Primitive, and Transform. When you load a GLTF file into renderling, it automatically stages a collection of these resources. This means that the GLTF file is parsed, and the corresponding GPU resources are created and returned to you, allowing you to integrate them into your application seamlessly.

Example

We'll start by creating our Context, Stage and Camera:

    use renderling::{
        camera::Camera,
        context::Context,
        glam::Vec4,
        glam::{Mat4, Vec3},
        stage::Stage,
    };

    let ctx = Context::headless(256, 256).await;
    let stage: Stage = ctx
        .new_stage()
        .with_background_color(Vec4::new(0.25, 0.25, 0.25, 1.0));

    let _camera: Camera = {
        let aspect = 1.0;
        let fovy = core::f32::consts::PI / 4.0;
        let znear = 0.1;
        let zfar = 10.0;
        let projection = Mat4::perspective_rh(fovy, aspect, znear, zfar);
        let eye = Vec3::new(0.5, 0.5, 0.8);
        let target = Vec3::new(0.0, 0.3, 0.0);
        let up = Vec3::Y;
        let view = Mat4::look_at_rh(eye, target, up);

        stage
            .new_camera()
            .with_projection_and_view(projection, view)
    };

Then we load our GLTF file through the Stage with Stage::load_gltf_document_from_path, and as long as there are no errors it returns a GltfDocument:

    use renderling::{gltf::GltfDocument, types::GpuOnlyArray};
    let model: GltfDocument<GpuOnlyArray> = stage
        .load_gltf_document_from_path(workspace_dir().join("gltf/marble_bust_1k.glb"))
        .unwrap()
        .into_gpu_only();
    println!("bounds: {:?}", model.bounding_volume());

On WASM we would use Stage::load_gltf_document_from_bytes as the filesystem is unavailable.

Notice how in the above example we call GltfDocument::into_gpu_only to unload the mesh geometry from the CPU.

Render

    let frame = ctx.get_next_frame().unwrap();
    stage.render(&frame.view());
    let img = frame.read_image().await.unwrap();
    img.save("gltf-example-shadow.png").unwrap();
    frame.present();

Result

a loaded GLTF file, a marble bust, in shadow

But wait! It's all in shadow.

This is because we haven't added any lighting.

We have two options here:

  1. Turn of lighting and show the scene "unlit", using Stage::set_has_lighting
  2. Add some lights

For now we'll go with option 1, as lighting happens in a later section:

    stage.set_has_lighting(false);

a loaded GLTF file, a marble bust, unlit