Baryon

Flexible prototyping engine.
slides: https://hackmd.io/@kvark/baryon

Dzmitry Malyshau


History

Three-rs:
three-rs aviator


Goals

  • easy to prototype (batteries included)
  • solid portable graphics stack (wgpu)
  • scalable to a lot of entities
  • very little magic in the API

mesh-material-pass


What vertex format should I pick?

What is exactly is a material?

How much opinion do I need to have?


nested core


ECS

How much would ECS help?

Bevy, Rend3, and Dotrix - already use it,

but very differently.


Dotrix:

let mesh_handle = assets.register::<Mesh>("sphere::mesh");
world.spawn(vec![
    (pbr::solid::Entity { // bag of components
        mesh: mesh_handle,
        texture: albedo,
        translate: Vec3::new(0., 0., 0.),
        ..Default::default()
    }).tuple(),
]);

Rend3:

let mesh = rend3::types::MeshBuilder::new(vertex_positions.to_vec(), rend3::types::Handedness::Left)
    .with_indices(index_data.to_vec())
    .build() // produces `rend3::types::Mesh`
    .unwrap()
let material = rend3_routine::pbr::PbrMaterial {
    albedo: rend3_routine::pbr::AlbedoComponent::Value(
        glam::Vec4::new(0.0, 0.5, 0.5, 1.0),
    ), ..
};
let object = rend3::types::Object {
    mesh_kind: rend3::types::ObjectMeshKind::Static(renderer.add_mesh(mesh)),
    material: renderer.add_material(material), // generic <M>
    transform: glam::Mat4::IDENTITY,
};
let object_handle = renderer.add_object(object);

Bevy:

let mesh = meshes.add(Mesh::from(shape::Cube { size: 1.0 })); // prelude
let material = materials.add(StandardMaterial { // prelude
    base_color: Color::PINK,
    ..Default::default()
});
commands.spawn_bundle(PbrBundle { // prelude
    mesh,
    material,
    transform: Transform::from_xyz((x as f32) * 2.0, (y as f32) * 2.0, 0.0),
    ..Default::default()
});

Disclaimer!

Baryon is really just a toy.

Not nearly as useful as all the engines here.

The core doesn't even know what a material is, or what is a vertex position!


Baryon (entity):

let prototype = // essentially, a bundle of vertex data components
    Geometry::cuboid(Streams::empty(), mint::Vector3 { x: 1.0, y: 1.0, z: 1.0 })
    .bake(&mut context);
let node = scene
    .add_node()
    .position(mint::Vector3 { x: 0.0, y: 0.0, z: 1.0 + SCALE_LEVEL })
    .scale(SCALE_LEVEL)
    .parent(parent_node)
    .build(); 
let entity = scene
    .add_entity(prototype)
    .parent(node)
    .component(level.color) // material?
    .build();

Baryon (update & render):

let mut pass = baryon::pass::Solid::new(
    &baryon::pass::SolidConfig {
        cull_back_faces: true,
    },
    &context,
);
...
scene[node].pre_rotate( // node indexed directly
    mint::Vector3 { x: 0.0, y: 0.0, z: 1.0 },
    delta * level.speed,
);
context.present(&mut pass, &scene, &camera);

baryon components


Baryon (pass):

for (_, (entity, color)) in scene
    .world
    .query::<(&bc::Entity, &bc::Color)>()
    .with::<bc::Vertex<crate::Position>>()
    .iter()
{
    let space = &nodes[entity.node];
    let mesh = context.get_mesh(entity.mesh);
    ... // bind vertices, uniforms, etc
    pass.draw(0..mesh.vertex_count, 0..1);
}

Demo

cubeception


Questions

This is probably impractical, but fun!


Select a repo