Skip to content

keiya01/threerender

Repository files navigation

threerender

CAUTION: Currently, this is POC, and in development, so not production ready. If you interest this project, you can see examples dir

Overview

threerender is a simple 3D rendering engine. It will target providing feature of fundamental for 3D development.

It is similar to Three.js, but this will be more extensible and work on multiple platforms.

Usage

You can use this library as follow.

use std::rc::Rc;

use threerender::color::rgb::RGBA;
use threerender::math::{Quat, Transform, Vec3};
use threerender::mesh::{Sphere, Square};
use threerender::renderer::Renderer;
use threerender::traits::entity::EntityDescriptor;
use threerender::{CameraStyle, LightBaseStyle, LightStyle, RendererBuilder, HemisphereLightStyle};

fn main() {
    let (width, height) = (2000, 1500);
    let mut renderer_builder = RendererBuilder::new();
    renderer_builder.set_width(width);
    renderer_builder.set_height(height);
    renderer_builder.set_background(RGBA::new(0, 0, 0, 1));

    renderer_builder.set_camera(CameraStyle {
        width: width as f32,
        height: height as f32,
        ..Default::default()
    });

    renderer_builder.add_light(LightStyle::with_directional(
        "directional".to_owned(),
        LightBaseStyle::default(),
        None,
    ));
    renderer_builder.add_light(LightStyle::with_hemisphere(
        "hemisphere".to_owned(),
        HemisphereLightStyle::default(),
        Vec3::new(0., 50., 0.),
    ));

    let sphere = Rc::new(Sphere::new(50, 50, None));
    renderer_builder.push(EntityDescriptor {
        id: "sphere".to_owned(),
        mesh: Some(sphere),
        fill_color: RGBA::new(255, 255, 255, 255),
        transform: Transform::from_translation_rotation_scale(
            Vec3::ZERO,
            Quat::default(),
            Vec3::ONE,
        ),
        state: Default::default(),
        reflection: Default::default(),
        children: vec![],
        ..Default::default()
    });
    let square = Rc::new(Square::new(None));
    renderer_builder.push(EntityDescriptor {
        id: "square1".to_owned(),
        mesh: Some(square.clone()),
        fill_color: RGBA::new(0, 255, 0, 255),
        transform: Transform::from_translation_rotation_scale(
            Vec3::new(0., 0., -3.),
            Quat::default(),
            Vec3::ONE,
        ),
        state: Default::default(),
        reflection: Default::default(),
        children: vec![],
        ..Default::default()
    });
    renderer_builder.push(EntityDescriptor {
        id: "square2".to_owned(),
        mesh: Some(square),
        fill_color: RGBA::new(255, 0, 0, 255),
        transform: Transform::from_translation_rotation_scale(
            Vec3::new(-3., 0., -1.),
            Quat::default(),
            Vec3::ONE,
        ),
        state: Default::default(),
        reflection: Default::default(),
        children: vec![],
        ..Default::default()
    });

    let event_loop = winit::event_loop::EventLoop::new();
    let window = winit::window::Window::new(&event_loop).unwrap();
    window.set_inner_size(winit::dpi::PhysicalSize::new(
        renderer_builder.width(),
        renderer_builder.height(),
    ));

    let mut renderer = Renderer::new(&window, renderer_builder);
    event_loop.run(move |event, _target, control_flow| {
        match event {
            winit::event::Event::WindowEvent {
                event: winit::event::WindowEvent::Resized(size),
                ..
            } => {
                renderer.resize(size.width, size.height);
                // For macos
                window.request_redraw();
            }
            winit::event::Event::WindowEvent {
                event: winit::event::WindowEvent::CloseRequested,
                ..
            } => *control_flow = winit::event_loop::ControlFlow::Exit,
            winit::event::Event::RedrawRequested(_) => {
                renderer.render();
            }
            _ => {},
        }
    });
}

Examples

You can try this project by examples.

You can run these examples by below command.

cargo run -p examples_{PROJECT_NAME}

Road map

  • 3D entities
    • Square
      • 2D texture rendering
    • Sphere
      • 2D texture rendering
  • 2D entities
    • Lines
    • Plane
      • 2D texture rendering
    • Triangle
  • Camera
  • Light
    • Directional light
    • Spot light
    • Point light
    • Hemisphere light
  • Shadow
    • Directional shadow
    • Opacity
    • Soft shadow(PCSS)
    • Point light shadow
    • Spot light shadow
  • Multi light/shadow
  • Reflection rate for entity
  • 2D texture
  • Override shader
  • glTF support
    • Basic glTF support
    • Animation
    • PBR
  • Normal mapping
  • Model transparency
  • Extensible window system
  • Extendable shader by user
  • Custom render process by implementing trait
    • Shadow rendering
    • Ray tracing
  • Performance improvement
  • Font
  • Integration with 2D library like egui
  • Web support / Deno support(native binding)
  • Convenient Math API for 3D development

About

A simple 3D rendering engine

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published