BlazorThree 0.1.1-preview

This is a prerelease version of BlazorThree.
dotnet add package BlazorThree --version 0.1.1-preview
                    
NuGet\Install-Package BlazorThree -Version 0.1.1-preview
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BlazorThree" Version="0.1.1-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BlazorThree" Version="0.1.1-preview" />
                    
Directory.Packages.props
<PackageReference Include="BlazorThree" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BlazorThree --version 0.1.1-preview
                    
#r "nuget: BlazorThree, 0.1.1-preview"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BlazorThree@0.1.1-preview
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BlazorThree&version=0.1.1-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=BlazorThree&version=0.1.1-preview&prerelease
                    
Install as a Cake Tool

BlazorThree

NuGet version NuGet downloads GitHub stars GitHub issues

BlazorThree is a .NET 10 Razor Class Library for building Three.js scenes with declarative Blazor components. You compose a scene graph in Razor, and the library keeps a browser-side Three.js runtime synchronized for rendering, animation, model playback, and scene interaction.

Live demo: https://nicolaparo.github.io/BlazorThree-demo

BlazorThree demo 1 BlazorThree demo 2

Why BlazorThree

BlazorThree exists for developers that want scene composition and scene state management to live entirely in Blazor components.

Compared to other libraries, BlazorThree centers the component model as the primary authoring experience:

  • Scene graph structure is expressed directly in Razor (Scene, Group, Mesh, Model, and children)
  • Scene changes come from normal Blazor state updates instead of manually orchestrating an imperative scene lifecycle
  • Behaviors like transforms, transitions, materials, outlines, and interaction handlers remain colocated with each node in component markup

The goal is predictable, maintainable 3D UI composition for Blazor-first applications.

Demo app quickstart

If you want to see the current published demo first, open:

If you want to try the demo app from this repository instead of consuming the NuGet package directly:

  1. Clone the repository.

  2. Change into the demo folder:

    cd demo
    
  3. Run the Blazor Server demo project:

    dotnet run --project BlazorThree.Demo.BlazorServer/BlazorThree.Demo.BlazorServer.csproj
    
  4. Open the local URL printed by dotnet run in your browser.

Preview status

BlazorThree is still a preview feature. The API surface, runtime behavior, packaging details, and documentation may change before a stable release.

What the library provides

  • Declarative scene composition with Scene, Camera, Light, Group, Mesh, and Model
  • Nested transform hierarchies with shared position, rotation, and scale primitives
  • Per-node property transitions for state changes
  • Model loading for .glb, .gltf, .fbx, and .dae
  • Model clip discovery, playback, looping, scrubbing, and blend control
  • Per-bone pose overrides through BonePose or BonePoses
  • Mesh outlines for highlighting and stylized rendering
  • Pointer picking callbacks on meshes, models, and groups
  • A broad built-in geometry and material component set

Install

Preview note: this package is still in preview and should be treated as pre-release software.

Add the package reference to your app:

<PackageReference Include="BlazorThree" Version="0.1.0-preview" />

Import the namespaces where you author scenes, typically in _Imports.razor:

@using System.Numerics
@using BlazorThree
@using BlazorThree.Engine
@using BlazorThree.Geometries
@using BlazorThree.Materials

No service registration is required. Scene loads the JavaScript bridge automatically from _content/BlazorThree/blazorthree.bundle.js.

Runtime dependency strategy

BlazorThree ships a bundled browser runtime that includes the pinned Three.js dependency and required loaders. This keeps production deployments deterministic and avoids runtime CDN dependencies.

When changing runtime JavaScript or upgrading Three.js, rebuild the bundled artifact:

npm install
npm run build:runtime

This writes src/BlazorThree/wwwroot/blazorthree.bundle.js, which is the only runtime entry loaded by Scene.

Quick start

<Scene Width="100%" Height="520px" ClearColor="#101925">
   <Camera Fov="65" Position="@(new(0f, 1.4f, 7f))">
      <OrbitControls Enabled="true" EnableDamping="true" DampingFactor="0.09" />
   </Camera>
   <Light Type="LightDefinitions.Directional" Intensity="1.6" Position="@(new(6f, 8f, 3f))" />

   <Group Position="@(stageActive ? new(0f, 0.9f, 0f) : Vector3.Zero)"
          Rotation="@(stageActive ? new(0f, 1.8f, 0f) : Vector3.Zero)"
          Scale="@(stageActive ? new(-1f, -1f, -1f) : Vector3.One)">
      <Transition Properties="@([nameof(Group.Position), nameof(Group.Rotation), nameof(Group.Scale)])"
                  DurationMs="1200"
                  Easing="@Easings.EaseInOutQuad" />

      <Mesh Position="@(new(-1.7f, 0.1f, 0f))">
         <BoxGeometry Width="1" Height="1" Depth="1" />
         <MeshStandardMaterial Color="#f5f500" Metalness="0.05" Roughness="0.55" />
      </Mesh>

      <Mesh Position="@(new Vector3(1.7f, 0.1f, 0f))">
         <SphereGeometry Radius="0.9" WidthSegments="48" HeightSegments="24" />
         <MeshStandardMaterial Color="#ffffff"
                               TextureUrl="https://threejs.org/examples/textures/uv_grid_opengl.jpg"
                               Metalness="0.05"
                               Roughness="0.55" />
      </Mesh>
   </Group>

   <Mesh Position="@(new Vector3(0f, -1.5f, 0f))">
      <BoxGeometry Width="6" Height="0.18" Depth="3" />
      <MeshStandardMaterial Color="#6ca0ff" Metalness="0.15" Roughness="0.9" />
   </Mesh>
</Scene>

@code {
   private bool stageActive;
}

Changing a node property such as Position, Rotation, or Scale at runtime animates that property when a matching child Transition is present.

Scene building blocks

Scene and camera

  • Scene hosts the renderer, controls canvas size and clear color, and owns scene-level callbacks
  • Camera configures a perspective camera with field of view, position, and rotation
  • Light publishes one active light using LightDefinitions.Directional, LightDefinitions.Point, or LightDefinitions.Ambient
  • OrbitControls enables browser-side orbit interaction with optional damping and must be nested under Camera

Hierarchy and transforms

  • Group creates a transformable parent for nested groups, meshes, and models
  • Mesh combines a geometry component, a material component, and an optional Outline
  • Model loads an external asset and behaves like any other transformable scene node
  • All object nodes share Id, Position, Rotation, Scale, and pointer callbacks
<Group Position="new Vector3(0f, 1f, 0f)" Rotation="new Vector3(0f, 0.5f, 0f)">
   <Mesh Position="new Vector3(-1f, 0f, 0f)">
      <BoxGeometry Width="1" Height="1" Depth="1" />
      <MeshStandardMaterial Color="#15b8a6" />
   </Mesh>

   <Group Position="new Vector3(2f, 0f, 0f)">
      <Mesh>
         <SphereGeometry Radius="0.5" />
         <MeshStandardMaterial Color="#ffb020" />
      </Mesh>
   </Group>
</Group>

Animation

Transitions

Place Transition inside Mesh, Group, or Model to animate specific transform properties for that node.

  • Property can target one property: Position, Rotation, or Scale
  • Properties can target multiple properties with one transition definition
  • DurationMs controls animation length
  • Easing accepts the values from Easings
<Group Position="@groupPosition" Rotation="@groupRotation">
   <Transition Properties="@(new[] { "Position", "Rotation" })" DurationMs="800" Easing="@Easings.EaseInOutQuad" />

   <Mesh>
      <BoxGeometry Width="1" Height="1" Depth="1" />
      <MeshStandardMaterial Color="#15b8a6" />
   </Mesh>
</Group>

Keyframe animations

Use Animation with nested Keyframe entries when you want CSS-like keyframe animation behavior managed internally by the runtime.

  • DurationMs sets animation duration in milliseconds
  • Active starts or pauses playback
  • Loop repeats playback
  • Easing sets the default easing between keyframes
  • OnStart, OnUpdate, and OnEnd expose playback lifecycle events

Keyframe supports any animatable property path available in the current scope, including transforms and nested paths such as Material.Color, Material.Opacity, Geometry.Width, and Outline.Opacity.

<Mesh>
   <Animation DurationMs="2000" Loop="true" Active="true" Easing="@Easings.EaseInOutQuad" OnUpdate="OnAnimationUpdate">
      <Keyframe Offset="0" Property="Position" Value="@(new Vector3(0f, 0f, 0f))" />
      <Keyframe Offset="0" Property="Rotation" Value="@(new Vector3(0f, 0f, 0f))" />
      <Keyframe Offset="50" Property="Position" Value="@(new Vector3(0f, 1.2f, 0f))" />
      <Keyframe Offset="100" Property="Rotation" Value="@(new Vector3(0f, 1.57f, 0f))" />
      <Keyframe Offset="0" Property="Material.Color" Value="#3b82f6" />
      <Keyframe Offset="100" Property="Material.Color" Value="#ef4444" />
      <Keyframe Offset="0" Property="Outline.Opacity" Value="0.2" />
      <Keyframe Offset="100" Property="Outline.Opacity" Value="0.95" />
   </Animation>

   <BoxGeometry Width="1" Height="1" Depth="1" />
   <MeshStandardMaterial Color="#3b82f6" />
   <Outline Color="#ffffff" Opacity="0.2" />
</Mesh>

Models, clips, and bones

Model supports runtime-loaded assets and animation playback controls:

  • SourceUrl points to a model under your app's static files
  • AnimationClipName selects the active clip
  • IsAnimationPlaying, AnimationLoop, AnimationSpeed, AnimationTimeMs, and AnimationBlendMs control playback
  • AvailableClipsChanged reports clip names discovered by the loader
  • BonePose child components and BonePoses let you override skeleton transforms declaratively
<Model
   SourceUrl="/models/Fox.glb"
   AnimationClipName="Run"
   AnimationLoop="true"
   AnimationSpeed="1.2"
   AvailableClipsChanged="OnClipsChanged">
   <BonePose BoneName="Head" Rotation="new Vector3(0f, 0.3f, 0f)" />
</Model>

Interaction and highlighting

Mesh, Model, and Group can all react to pointer events with Click, MouseEnter, and MouseLeave. Group handlers bubble from picked descendants, which is useful for selecting whole subtrees.

<Group Click="OnGroupClick">
   <Mesh MouseEnter="OnMeshEnter" MouseLeave="OnMeshLeave">
      <SphereGeometry Radius="1" />
      <MeshStandardMaterial Color="#ffffff" />
      <Outline Color="#00ffcc" Opacity="0.9" />
   </Mesh>
</Group>

Outline draws an edge-based silhouette from the mesh geometry for hover states, selection affordances, or stylized rendering.

Built-in geometries

BlazorThree currently ships geometry components for:

  • BoxGeometry
  • CapsuleGeometry
  • CircleGeometry
  • ConeGeometry
  • CylinderGeometry
  • DodecahedronGeometry
  • EdgesGeometry
  • ExtrudeGeometry
  • IcosahedronGeometry
  • LatheGeometry
  • OctahedronGeometry
  • PlaneGeometry
  • PolyhedronGeometry
  • RingGeometry
  • ShapeGeometry
  • SphereGeometry
  • TetrahedronGeometry
  • TorusGeometry
  • TorusKnotGeometry
  • TubeGeometry
  • WireframeGeometry

These cover common primitives, line-like derivatives, and procedural profile-based shapes.

Built-in materials

BlazorThree currently ships material components for:

  • MeshBasicMaterial
  • MeshLambertMaterial
  • MeshMatcapMaterial
  • MeshNormalMaterial
  • MeshPhongMaterial
  • MeshPhysicalMaterial
  • MeshStandardMaterial
  • MeshToonMaterial

The material components expose the parameters you would expect for their Three.js counterparts, including colors, texture URLs, wireframe options, lighting properties, and physically based rendering controls.

Build and run locally

Build the solution:

dotnet build BlazorThree.slnx

Run the Blazor Server demo app:

dotnet run --project demo/BlazorThree.Demo.BlazorServer/BlazorThree.Demo.BlazorServer.csproj

Run the Blazor WebAssembly demo app:

dotnet run --project demo/BlazorThree.Demo.BlazorWebAssembly/BlazorThree.Demo.BlazorWebAssembly.csproj

Then open the local URL printed by ASP.NET Core.

Demo project

The repository contains:

  • src/BlazorThree: the reusable component library
  • demo/BlazorThree.Demo.Shared: shared demo components, pages, layout, and static assets
  • demo/BlazorThree.Demo.BlazorServer: Blazor Server host for the shared demo
  • demo/BlazorThree.Demo.BlazorWebAssembly: Blazor WebAssembly host for the shared demo

The demo reflects the current preview feature set and is not a statement of stable API guarantees.

Roadmap

The current roadmap lives in docs/roadmap.md. If you want to contribute, start there and look for small issues around docs, demos, CI, rendering behavior, and interaction edge cases.

Three.js reference

If you need the underlying rendering concepts, start with the Three.js scene primer:

https://www.threejs.pro/docs/#manual/en/introduction/Creating-a-scene

Support and contribute

If it helped you, here are simple ways to support it:

If you want to contribute:

  • Read CONTRIBUTING.md
  • Open an issue for bugs, feature ideas, or questions
  • Start with docs/roadmap.md for current contribution priorities
  • Fork the repository and open a pull request
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.1-preview 85 7/18/2026
0.1.0-preview 69 7/14/2026