Header menu logo Mibo

Rendering3D Overview

The PipelineRenderer provides a complete 3D rendering pipeline with PBR materials, dynamic lighting, shadows, and post-processing effects. It handles the complex GPU state management so you can focus on what to render rather than how to render it.

What It Provides

These features are available if your project needs them. You are not required to use all of them.

Getting Started

A minimal setup using the fluent API:

open Mibo.Rendering.Graphics3D

let view (ctx: GameContext) (model: Model) (buffer: PipelineBuffer<RenderCommand>) =
    buffer
        .Camera(model.Camera)
        .Clear(Color.CornflowerBlue)
        .ClearDepth()
        .Lighting(model.Lighting)
        .DrawMany(model.Entities |> Seq.map (fun e ->
            draw {
                mesh e.Mesh
                at e.Position
                withAlbedo Color.White
                withMaterial e.Material
            }))
        .Submit()

let config =
  PipelineConfig.defaults
  |> PipelineConfig.withPostProcess {
      PostProcessConfig.defaults with
          ToneMapping = ToneMappingConfig.ACES
    }

Program.mkProgram init update
|> Program.withPipeline config view

The view function receives a PipelineBuffer<RenderCommand> (an alias for RenderBuffer<unit, RenderCommand>). Use the fluent API to chain commands, or use the Buffer module for a functional style:

let view ctx model buffer =
    buffer
    |> Buffer.camera model.Camera
    |> Buffer.clear Color.CornflowerBlue
    |> Buffer.clearDepth
    |> Buffer.lighting model.Lighting
    |> Buffer.drawMany (model.Entities |> Seq.map createDrawable)
    |> Buffer.submit

Creating Drawables

Use the draw computation expression to create drawables:

let drawable =
    draw {
        mesh playerMesh
        at 0.0f 2.0f 0.0f
        withAlbedo Color.Gold
        withMetallic 1.0f
        withRoughness 0.3f
        withEmissive Color.Orange 2.0f
    }

buffer.Draw(drawable)

Or use the fluent Draw method which accepts Drawable voption:

model.Entities
|> Seq.map (fun e ->
    draw { mesh e.Mesh; at e.Position; withMaterial e.Material })
|> buffer.DrawMany

When to Use It

Use the 3D pipeline when you want: - Realistic PBR materials and lighting - Dynamic shadows from multiple light sources - Post-processing effects - Automatic batching and culling for performance - Custom shader integration

For simpler 3D needs, you might prefer a custom IRenderer implementation that draws directly. For 2D games, use Batch2DRenderer instead.

Combining with Other Renderers

You can combine the 3D pipeline with other renderers:

Program.mkProgram init update
|> Program.withPipeline config3d view3d
|> Program.withRenderer (fun game -> Batch2DRenderer.create view game)

The pipeline runs in registration order. The 3D renderer typically clears the screen and renders the world. A 2D UI renderer can then draw on top.

Configuration

Configure the pipeline via PipelineConfig:

let config =
  PipelineConfig.defaults
  |> PipelineConfig.withShadows (ShadowConfig.defaults |> ShadowConfig.withBias 0.001f 0.005f)
  |> PipelineConfig.withPostProcess (
      PostProcessConfig.defaults
      |> PostProcessConfig.withBloom { Threshold = 0.9f; Intensity = 1.5f; Scatter = 0.7f }
      |> PostProcessConfig.withToneMapping ACES
  )
  |> PipelineConfig.withDefaultLighting {
      AmbientColor = Color(20, 20, 30)
      AmbientIntensity = 0.5f
      Lights = [| Light.Directional { ... } |]
  }
  |> PipelineConfig.withShader ShaderBase.PBRForward "Effects/PBR"
  |> PipelineConfig.withShader ShaderBase.ShadowCaster "Effects/ShadowCaster"

See Pipeline for the complete command reference.

See also: Camera, Lighting, Materials, Custom Shaders

val view: ctx: 'a -> model: 'b -> buffer: 'c -> 'd
val ctx: 'a
val model: 'b
val buffer: 'c
module Seq from Microsoft.FSharp.Collections
val map: mapping: ('T -> 'U) -> source: 'T seq -> 'U seq
val config: obj
val drawable: obj
val e: obj

Type something to start searching.