-
Notifications
You must be signed in to change notification settings - Fork 50
Rendering 3D Models
Ultraviolet 2020.10 adds built-in support for loading, rendering, and animating 3D models. Currently, Ultraviolet supports .stl
, .gltf
, and .glb
files, though support for additional files can be provided by extending the content pipeline with custom code.
A static (i.e., non-animated) model is represented by the Model
class and can be loaded through ContentManager
as with any other kind of asset.
var myModel = content.Load<Model>("path/to/modelfile");
A model is a hierarchical type consisting of one more more ModelScene
objects, each of which represents a tree of ModelNode
objects. A node can optionally contain renderable geometry, though some nodes only contain transform data, and others are merely organizational. Nodes which contain geometry will have an associated ModelMesh
instance, which is accessible through its Mesh
property.
Scenes are drawn using the ModelSceneRenderer
class or another class which derives from ModelSceneRendererBase<T1, T2>
. The Draw()
method will render the scene's geometry using the specified camera parameters, as in the example below.
var camera = PerspectiveCamera.Create();
camera.Position = new Vector3(0, 1, 500);
camera.Target = new Vector3(0, 100, 0);
camera.Update();
var renderer = new ModelSceneRenderer();
var worldMatrix = Matrix.Identity;
renderer.Draw(myModel.Scenes.DefaultScene, camera, ref worldMatrix);
Note that Model
and ModelSceneRenderer
do not support animations.
To animate 3D models, you will need to use the SkinnedModel
class. As with Model
, you can load instances of this class using the content system.
var myModel = content.Load<SkinnedModel>("path/to/modelfile");
A SkinnedModel
is a kind of template; it contains the model's geometry and the definitions of all of its animations, but it does not track animation state and therefore cannot be animated itself. To play animations, you need to create instances of the template using the SkinnedModelInstance
class.
var instance = new SkinnedModelInstance(myModel);
Each SkinnedModelInstance
represents a distinct animation state for the model. If your game has 100 characters in it, and each of those characters is separately animated from all of the others, then you will need 100 SkinnedModelInstance
objects, one for each character. Each instance will have its own copy of the data used to animate the model's bones, but they'll all refer back to the original SkinnedModel
instance for the basic geometry data.
You can play an animation by calling the PlayAnimation()
method on SkinnedAnimationInstance
. You can specify an animation either by its name (if it has one) or its logical index. Each SkinnedModelInstance
contains 1 or more animation tracks, each of which can play a single animation; tracks are allocated to animations automatically by the PlayAnimation()
method. If you attempt to play more animations on one instance than there are tracks, the least-recently-played animation will be stopped and its track will be reused for the new animation.
To render a skinned model instance, use the SkinnedModelSceneRenderer
class. This class works analogously to the ModelSceneRenderer
class used above, but supports skinned animation using SkinnedModelInstance
and SkinnedEffect
.
As it always has, Ultraviolet represents a shader program with the Effect
class. The built-in BasicEffect
can be used to render static 3D models using a standard lighting setup of three directional lights, and the built-in SkinnedEffect
can be used to support basic skinned animation. You can also load custom shaders into your own Effect
instances; see Creating Effects for more details.
The geometry of a ModelNode
is associated with a Material
object. A material specifies the set of parameters which are passed to the Effect
used to render that geometry. For example, a material might specify the diffuse color and texture of the mesh.
The Material
class is an abstract base class. Derived classes are associated with a specific kind of Effect
and expose properties corresponding to that effect's expected parameters. For example, the BasicMaterial
class is designed to be used with BasicEffect
, and SkinnedMaterial
is designed to be used with SkinnedEffect
. Changing a mesh's Material
will therefore change the Effect
which is used to render that mesh.
- Contributing
- Dependencies
- Basic Concepts
- First Look- Platform
- First Look- Graphics
- First Look- Audio
- First Look- Input
- First Look- Content
- First Look- UI
- sRGB Color
- Customizing SpriteBatch
- Creating Fonts
- Creating Effects
- Creating Glyph Shaders
- FreeType2 Fonts
- Rendering 3D Models