Shader Architecture

advanced scripting

Voxel Play 3 · Scripting / API

Overview

Voxel Play uses standard Unity geometry (meshes) and custom shaders to deliver performant rendering for massive amounts of voxels in a scene.

A voxel definition specifies the render type which points to a specific shader. Custom (prefab) voxels use the material attached to the prefab so it can use any shader. The rest of render types use one of the included shaders with Voxel Play.

The most common shader, used for terrain rendering, is "Opaque 3 Textures (with ambient occlusion)" found in Voxel Play/Resources/VoxelPlay/Shaders folder. All voxel shaders include sub-shaders for built-in and URP pipelines.

Vertex Shader

The vertex shader data includes:

  • Vertex position (in object space)
  • UV coordinates
  • Normal (in world space as voxels are AABB aligned)
  • Color (only if Tinting option is enabled)

UV Coordinates Structure

The UV coordinates are packed into a float4 (x, y, z, w):

  • x & y: Texture coordinates in non-normalized range. Use frac(uv.xy) for 0..1 range.
  • z: Texture index plus flags. First 14 bits reserved for texture index (supports 16,384 textures per array). Upper bits encode animation data or tree wind speed.
  • w: Smooth lighting data with bits 1-4 encoding Sun lighting and bits 12-15 encoding Torch lighting.

Fragment Shader

Fragment shaders implement numerous features. Lighting can be computed at vertex stage or in fragment shader when VOXELPLAY_PIXEL_LIGHTS keyword is enabled, providing per-pixel normal and world position data.

Lighting

Vertex Lighting Components

  • Sun light contribution acts as a multiplier to normal-light dot product
  • Torch light contribution represents light intensity reaching that vertex

Point Lights

Voxel Play provides data for 32 nearest point lights via constant buffer:

CBUFFER_START(VoxelPlayLightBuffers)
float4 _VPPointLightPosition[32];
float4 _VPPointLightColor[32];
int _VPPointLightCount;
CBUFFER_END

Where _VPPointLightPosition.xyz contains world-space coordinates with w storing range multiplied by global light scattering parameter, and _VPPointLightColor.rgb contains color multiplied by intensity values.

Authoring Custom Shaders

Creating custom shaders requires understanding the custom UV format for texture coordinates, index, and smooth lighting. You must use bit shifting and bitwise operations to extract meaningful data from packed float values.

Was this page helpful?