dioxus-three 0.0.4

A Three.js 3D model viewer for Dioxus - supports Desktop, Web (WASM), and Mobile
Documentation

Dioxus Three

A Dioxus wrapper around Three.js for building cross-platform 3D applications in Rust.

⚠️ Pre-alpha: Active development. APIs will change.

Overview

Dioxus Three provides a Dioxus component that embeds a Three.js 3D viewer, allowing you to:

  • Load and display 3D models (GLB, GLTF, OBJ, FBX, STL, PLY, Collada, 3MF)
  • Render multiple models in a single scene
  • Apply custom vertex/fragment shaders
  • Control camera, lighting, and scene settings
  • Interact with the scene via pointer events and selection
  • Manipulate objects with transform gizmos (translate, rotate, scale)

Features

Feature Status Description
Model Loading ✅ Ready GLB, GLTF, OBJ, FBX, STL, PLY, Collada, 3MF
Multiple Models ✅ Ready Render multiple models in one scene
Camera Control ✅ Ready Orbit controls, custom positions
Shader Support ✅ Ready Custom vertex/fragment shaders
Desktop (WebView) ✅ Ready Tauri/WebView on macOS, Linux, Windows
Web (WASM) ✅ Ready WASM + Three.js canvas
Mobile (WebView) 🔄 Partial WebView-based, iOS/Android
Selection v0.0.3 Click to select objects, multi-select with Shift
Gizmos v0.0.3 Translate, Rotate, Scale handles
Pointer Events v0.0.3 on_pointer_down, on_pointer_move, on_pointer_up
Raycasting v0.0.3 Hit detection for clicks and hovers
Animation 🔄 Planned Keyframe and procedural animation
Physics 🔄 Planned Rapier.js integration
Post-Processing 🔄 Planned Bloom, SSAO, etc.

Installation

Add to your Cargo.toml:

[dependencies]
dioxus-three = "0.0.4"
dioxus = "0.6"

Or use the git version for the latest:

[dependencies]
dioxus-three = { git = "https://github.com/eftech93/dioxus-three" }

Quick Start

use dioxus::prelude::*;
use dioxus_three::{ThreeView, ModelFormat};

fn App() -> Element {
    rsx! {
        ThreeView {
            model_url: Some("model.glb".to_string()),
            format: ModelFormat::Glb,
            cam_x: 2.0,
            cam_y: 2.0,
            cam_z: 5.0,
        }
    }
}

Examples

Selection & Gizmos

use dioxus::prelude::*;
use dioxus_three::{ThreeView, ModelFormat, ModelConfig, Selection, Gizmo, GizmoMode, GizmoEvent, SelectionMode};

#[component]
fn App() -> Element {
    let mut selection = use_signal(|| Selection::empty());
    let mut gizmo = use_signal(|| None::<Gizmo>);

    rsx! {
        ThreeView {
            models: vec![
                ModelConfig::new("model.glb", ModelFormat::Glb)
            ],
            selection: Some(selection()),
            selection_mode: SelectionMode::Single,
            on_selection_change: move |sel| {
                selection.set(sel.clone());
                if let Some(id) = sel.primary() {
                    gizmo.set(Some(Gizmo::new(id).with_mode(GizmoMode::Translate)));
                } else {
                    gizmo.set(None);
                }
            },
            gizmo: gizmo(),
            on_gizmo_drag: move |event: GizmoEvent| {
                println!("Gizmo drag: {:?}", event.transform);
                if event.is_finished {
                    // Persist the transform to your app state
                }
            },
        }
    }
}

Custom Shader

ThreeView {
    model_url: Some("model.glb".to_string()),
    shader: ShaderPreset::Custom {
        vertex: include_str!("shaders/vertex.glsl"),
        fragment: include_str!("shaders/fragment.glsl"),
    },
}

Multiple Models

ThreeView {
    models: vec![
        ModelConfig::new("car.glb", ModelFormat::Glb)
            .with_position(-2.0, 0.0, 0.0)
            .with_color("#ff6b6b"),
        ModelConfig::new("wheel.glb", ModelFormat::Glb)
            .with_position(2.0, 0.0, 0.0)
            .with_color("#4ecdc4"),
    ],
}

Platform Notes

Desktop (macOS, Linux, Windows)

Uses a WebView iframe with Three.js loaded from CDN. Includes:

  • Full orbit camera controls
  • Official THREE.TransformControls for gizmos (translate, rotate, scale)
  • Pointer events via document::eval bridge
  • State updates via postMessage (no iframe reload on camera/selection/gizmo changes)
  • Selection outline with wireframe box + inner glow
  • Gizmo handles always render on top via depthTest: false

Web (WASM)

Renders Three.js directly to a <canvas> element:

  • Native canvas rendering
  • Custom-built gizmos using Three.js primitives (arrows, tori, boxes)
  • Manual raycasting and drag math
  • Bridge via wasm_bindgen closures (dioxusThreeRustBridge)
  • Same selection and gizmo features as Desktop
  • Gizmo handles always render on top via depthTest: false

Mobile

Uses WebView approach similar to Desktop. Gizmo features available but not yet fully tested.

Documentation

Contributing

Contributions are welcome! See CONTRIBUTING.md.

License

MIT License - see LICENSE file.