Colored Microvoxels & Material Profiles
intermediate featureVoxel Play 4 extends the microvoxel system with custom color palettes and material profiles, enabling detailed decorations with per-cell coloring and dual-material surfaces like grass-over-dirt terrain.
Color Palettes
Each microvoxel shape can have a palette of up to 255 colors. Individual cells reference a palette slot, allowing detailed coloring within a single voxel.
- palette: a
Color32[]array storing the available colors - colorIndices: a
byte[]with 4096 entries (16x16x16), one per cell. Value0= use parent material color. Values1..N= usepalette[N-1]
Requires VP_USE_TINTING enabled in the VoxelPlayEnvironment settings to render palette colors at runtime.
Layout Modes
The MicroVoxelLayout enum controls how primary and secondary materials are distributed across the microvoxel cells:
| Layout | Behavior | Use case |
|---|---|---|
| Default | All cells use the primary material | Standard decorations, furniture, details |
| Slabs | Horizontal split at secondaryTypeHeight. Cells below use primary, cells above use secondary material. | Grass-over-dirt, snow-over-rock terrain surfaces |
| TopCap | Side faces of the bottom half use the top-half texture from the secondary material | Terrain surface caps where sides need to show the top texture |
The secondaryTypeHeight field (0-16) controls where the split occurs in Slabs mode. Default is 8 (midpoint).
Material Profiles
A VoxelMaterialProfile is a ScriptableObject that stores texture and PBR properties for a voxel surface. Each profile has per-face textures (top, side, right, forward, left, bottom) with optional normal, displacement and PBR maps.
Setting Up Dual Materials
- Create a VoxelMaterialProfile asset (Create > Voxel Play > Voxel Material Profile)
- Assign the secondary textures (e.g. grass textures for the top layer)
- On the VoxelDefinition, assign the profile to the Secondary Material Profile field
- Set the microvoxels layout to Slabs and adjust
secondaryTypeHeight
At runtime, the engine creates an internal shadow VoxelDefinition from the profile and uses it for the secondary material zones.
Per-Quad Material Routing
When using palettes, individual cells can override which material is used regardless of the layout mode. This is encoded in the alpha channel of the palette color (bits 7-6):
| Mode | Alpha bits | Behavior |
|---|---|---|
| INHERIT | 00 | Use the layout rule (Slabs/TopCap height threshold) |
| PRIMARY | 01 | Force primary material regardless of position |
| SECONDARY | 10 | Force secondary material regardless of position |
This enables fine-grained control: a single microvoxel shape can have some cells using grass textures and others using stone, independent of their vertical position.
Creating Microvoxels in the Editor
Select a VoxelDefinition asset and expand the Microvoxels section in the inspector. Available tools:
- Clear: Remove all microvoxel data
- Bottom Slab / Top Slab: Fill half the voxel
- Custom Height: Fill a specific number of layers (0-15)
The inspector shows a 3D preview of the shape (click to rotate) and a layer diagram.
Alternatively, create a standalone MicroVoxelsDefinition asset and reference it from multiple VoxelDefinitions to share shapes.
PBR Surface Maps
VoxelDefinitions support full PBR maps per face. For each face direction (top, side, right, forward, bottom) you can assign:
- Metallic, Smoothness and Occlusion maps (e.g.
textureTopMetallic,textureSideSmoothness,textureBottomOcclusion) - Emission maps for self-illuminated surfaces (
textureTopEmission, ...)
These separate maps are combined into a single packed surface map for rendering. Use the editor's surface-map packing utility, or pack at runtime with TextureTools.PackSurfaceMap() (see the scripting reference).
Building MicroVoxels from Code
Procedural generators can author MicroVoxels directly: create the object, set occupancy with SetOccupied(x, y, z) (index layout x + z*16 + y*256), and pass it to VoxelPlace(..., microVoxels: mv). Two rules keep this safe:
- Sharing is managed by the system. The engine clones shared instances before mutating them (copy-on-write), and an instance stored in a second cell is promoted to
isShared = trueautomatically - so multi-cell shapes are safe by default. The flag stays public as an override: set it totrueyourself when a single-cell instance must behave as immutable (e.g. a template you keep a reference to), and only force it back tofalseif you deliberately want in-place mutation of a multi-cell shape. - For colored microvoxels, assign the palette before anything captures it. A cell is colored by setting
mv.palette(aColor32[]) plusmv.colorIndices(one byte per microvoxel: 0 = no override, k = palette[k-1]). If you build shapes in static initializers, declare the palette field above the builders - C# initializes statics in declaration order and a palette declared below is still null inside them.
Colored microvoxels require Enable Tinting on the environment; the tint multiplies over the definition's texture. Since worlds can mix authored and code-built content, the engine logs a warning at initialization when colored microvoxel definitions exist but tinting is off. Fully occupied cells normally take a fast path that renders them as plain voxels; cells carrying a palette are excluded from it so their colors always render.
See Also
- Microvoxels (VP3 docs) - Base microvoxel system reference
- OBJ Export - Export microvoxel models with textures to external tools
Suggest an improvement
Help us improve this documentation page.