Crate three

source ·
Expand description

Three.js inspired 3D engine.

Getting Started

Creating a window

Every three application begins with a Window. We create it as follows.

let title = "Getting started with three-rs";
let mut window = three::Window::new(title);

The four key structs

Every Window comes equipped with four structures, namely Factory, Renderer, Input, and Scene.

  • The Factory instantiates game objects such as Mesh and Camera.
  • The Input handles window events at a high-level.
  • The Scene is the root node of the component-graph system.
  • The Renderer renders the Scene from the view of a Camera object.

Creating a basic mesh

Renderable 3D objects are represented by the Mesh struct. A mesh is a combination of Geometry, describing the shape of the object, paired with a Material, describing the appearance of the object.

let geometry = three::Geometry::with_vertices(vec![
    [-0.5, -0.5, -0.5].into(),
    [ 0.5, -0.5, -0.5].into(),
    [ 0.0,  0.5, -0.5].into(),
]);
let material = three::material::Basic {
    color: 0xFFFF00,
    .. Default::default()
};
let mut mesh = window.factory.mesh(geometry, material);

Managing the scene

In order to be rendered by the Renderer, meshes must be placed in the Scene within the viewable region. Any marked with the Object trait may be placed into the scene heirarchy, including user-defined structs.

window.scene.add(&mesh);

We can set the initial scene background using the Scene::background field. The default background is solid black. Let’s set the background to a sky blue color instead.

window.scene.background = three::Background::Color(0xC6F0FF);

Creating the game loop

All is left to do to render our triangle is to create a camera and to write the main game loop.

let center = [0.0, 0.0];
let yextent = 1.0;
let zrange = -1.0 .. 1.0;
let camera = window.factory.orthographic_camera(center, yextent, zrange);
while window.update() {
    window.render(&camera);
}

Putting it all together

You should have the following code which renders a single yellow triangle upon a sky blue background.

extern crate three;

use three::Object;

fn main() {
    let title = "Getting started with three-rs";
    let mut window = three::Window::new(title);

    let vertices = vec![
        [-0.5, -0.5, -0.5].into(),
        [ 0.5, -0.5, -0.5].into(),
        [ 0.0,  0.5, -0.5].into(),
    ];
    let geometry = three::Geometry::with_vertices(vertices);
    let material = three::material::Basic {
        color: 0xFFFF00,
        .. Default::default()
    };
    let mesh = window.factory.mesh(geometry, material);
    window.scene.add(&mesh);

    let center = [0.0, 0.0];
    let yextent = 1.0;
    let zrange = -1.0 .. 1.0;
    let camera = window.factory.orthographic_camera(center, yextent, zrange);

    while window.update() {
        window.render(&camera);
    }
}

Highlighted features

Scene management

We use froggy to manage the scene heirarchy. three takes a slightly different approach to regular scene graphs whereby child objects keep their parents alive, opposed to parents keeping their children alive.

At the heart of the scene heirarchy is the object::Base type, which is a member of all three objects that are placeable in the scene.

All three objects are marked by the Object trait which provides the library with the object::Base type. Users may implement this trait in order to add their own structs into the scene heirarchy. Three-rs provides a helper macro three_object which provides a convenient way to implement Object for your types:

#[macro_use]
extern crate three;

use three::Object;

struct MyObject {
    group: three::Group,
}

three_object!(MyObject::group);

fn main() {
    // Initialization code omitted.
    let my_object = MyObject { group: window.factory.group() };
    window.scene.add(&my_object);
}

Multiple graphics pipelines

Graphics pipeline management is handled implicitly by three. The pipeline used to render a Mesh is chosen by its Material properties and the available vertex attributes from its Geometry.

The range of graphics pipelines available range from simple sprite rendering to physically based rendering.

3D format loading

glTF 2.0

three comes equipped with support for rendering and animating glTF scenes.

See Factory::load_gltf to get started.

Wavefront OBJ

For less complex meshes, three supports loading models in OBJ format.

See Factory::load_obj for more information.

Procedurally generated geometry

The Geometry struct leverages the genmesh crate to provide procedurally generated primtives such as cuboids, spheres, and cylinders. See the documentation on the Geometry struct for more information.

Modules

Animation system.
Primitives for audio playback.
Cameras are used to view scenes from any point in the world.
sRGB colors.
High-level input handling.
Contains re-exports for custom pipeline state.
Contains different types of light sources.
Material parameters for mesh rendering.
Items in the scene heirarchy.
The renderer.
Scene and SyncGuard structures.
Mesh skinning.
Utilites for creating reusable templates for scene objects.
Primitives for creating and controlling Window.

Macros

Implements the following traits:

Structs

Cubemap is six textures useful for Cubemapping.
Represents paths to cube map texture, useful for loading CubeMap.
A dynamic version of a mesh allows changing the geometry on CPU side in order to animate the mesh.
Factory is used to instantiate game objects.
Smart pointer containing a font to draw text.
A collection of vertices, their normals, and faces that defines the shape of a polyhedral object.
Groups are used to combine several other objects or groups to work with them as with a single entity.
Controls user and system input from keyboard, mouse and system clock.
Properties for vertex skinning.
General information about an object in a scene.
Renders Scene by Camera.
The sampling properties for a Texture.
The root node of a tree of game objects that may be rendered by a Camera.
A geometry shape.
Two-dimensional bitmap that is integrated into a larger scene.
UI (on-screen) text. To use, create the new one using Factory::ui_text and add it to the scene using Scene::add.
An image applied (mapped) to the surface of a shape or polygon.
Timer can be used to find the time difference between the moment of timer creation and the moment of calling elapsed.
Position, rotation, and scale of the scene node.
Window is the core entity of every three-rs application.

Enums

Describes the horizontal alignment preference for positioning & bounds. See gfx_glyph::HorizontalAlign for more.
Background type.
Keyboard or mouse button.
How to filter the texture when sampling. They correspond to increasing levels of quality, but also cost. Mipmap, trilinear and anisotropic filtering require mipmapping, but the other filtering methods do not.
Symbolic name for a keyboard key.
Describes text alignment & wrapping. See gfx_glyph::Layout.
Local space, defined relative to the parent node.
Specifies the appearance of a Mesh.
Describes a button of a mouse controller.
World space, defined relative to the scene root.
Specifies how texture coordinates outside the range [0, 1] are handled.

Constants

Axis for up and down arrow keys.
Axis for left and right arrow keys.
Escape keyboard button.
Space keyboard button.
Left mouse button.
Right mouse button.

Traits

Marks data structures that are able to added to the scene graph.

Type Definitions

sRGB color represented by a 4-byte hexadecimal number.