Skip to content
Edit on GitHub

Model deterministic voxel cloud formations and floating-origin drift

verifiedAgainst b1311b5 · verifiedOn 2026-09-10.

In Voxamine, clouds are not flat scrolling billboard textures or heavy volumetric shaders that blur the voxel world’s crisp aesthetic. Clouds are discrete voxel formations living high overhead at true world $Y=255$ (MASTERPLAN.md §13.1): compact, irregular clusters of block cells with physical thickness, drifting along the prevailing barometric wind vector, and dynamically reacting to atmospheric pressure by darkening into storm grey and dimming the surface landscape beneath them.

You will implement the pure shape generator in VoxelCloudShape.cs, manage a drifting bank of cloud instances aligned with AtmosphericPressureField.PrevailingWind, maintain strict floating-origin stability across world rebases via ChunkStreamingRuntime.RenderOriginOffset, and coordinate storm lighting modulation in VoxelCloudRuntime.cs.

// Generate a deterministic two-tier voxel cloud cluster:
IReadOnlyList<Vector3Int> voxels = VoxelCloudShape.Generate(seed: 42);
// Produces 8..180 compact voxel coordinates across layers y=0 and y=1!
// Central anchor (0, 0, 0) is mathematically guaranteed even for extreme seeds.

The cloud presentation layer connects pure world generation noise, atmospheric barometry, streaming floating-origin offsets, and HDRP scene lights:

  • Atmospheric Physics (AtmosphericPressureField) defines the global prevailing wind direction along which barometric systems and clouds travel.
  • Pure Shape Generator (VoxelCloudShape) evaluates elliptical integer distance fields and rotational bit-hashes to emit deterministic block clusters.
  • Presentation Coordinator (VoxelCloudRuntime) spawns 10 cloud formations across a $260\text{ m}$ radius, drifts them smoothly, recycles them across boundary thresholds, and modulates directional sun and moon lighting.
  • Streaming Pipeline (ChunkStreamingRuntime) provides the floating-origin RenderOriginOffset so clouds never snap or jitter when the player crosses floating-origin chunk boundaries.
flowchart TD
  subgraph WIND["Barometric Atmosphere"]
    PRESSURE["AtmosphericPressureField.PrevailingWind\n(Vector2(0.85, 0.53) direction)"]
  end

  subgraph SHAPE["VoxelSandbox.World.Environment"]
    GEN["VoxelCloudShape.Generate(seed)\n(Elliptical distance field + 2-layer hash)"]
    ANCHOR["Guaranteed Anchor (0, 0, 0)\n(Always non-empty)"]
  end

  subgraph RUNTIME["VoxelCloudRuntime (MonoBehaviour)"]
    CLOUDS["10 Cloud Instances (World Y = 255)\nRadius = 260m, Recycle = 330m"]
    DRIFT["Drift Velocity: 2.5 m/s (calm) -> 9.0 m/s (gale)"]
    COLOR["Color Modulation: Fair (0.96) -> Storm (0.50)"]
  end

  subgraph STREAMING["Floating-Origin Invariant"]
    OFFSET["ChunkStreamingRuntime.RenderOriginOffset\n(Subtract offset every frame: zero jitter)"]
  end

  subgraph LIGHTING["Scene Illumination"]
    SUN["Sun Light Component (dimmed under storm fronts)"]
    MOON["Moon Light Component (soft fill lighting)"]
  end

  PRESSURE --> DRIFT
  GEN --> ANCHOR
  ANCHOR --> CLOUDS
  DRIFT --> CLOUDS
  OFFSET --> CLOUDS
  CLOUDS --> COLOR
  COLOR --> SUN
  COLOR --> MOON

Read Docs/MASTERPLAN.md §13.1 (“Clouds and atmosphere”) and the ChunkStreaming.md Codebase orientation page, then review:

Review the cloud design parameters:

Parameter Value Rationale
Cloud Base Elevation $Y = 255$ Placed at world height limit above all mountains and structures; never clips terrain.
Block Dimensions $4\text{ m} \times 2\text{ m} \times 4\text{ m}$ Blocks are $4\text{ m}$ wide horizontally but only $2\text{ m}$ thick vertically, producing stylized architectural slabs.
Cluster Formation $y \in {0, 1}$ (two layers) The bottom layer forms the continuous belly; the top layer adds stepped volume.
Drift Velocity $2.5\text{ m/s}$ (calm) to $9.0\text{ m/s}$ (gale) Speeds scale smoothly with storm intensity along the prevailing wind vector.
Field Radius / Recycle $260\text{ m} / 330\text{ m}$ Clouds wrap around relative to the camera position, keeping sky coverage dense without boundless instances.

1. Elliptical Distance Fields and Hash Variations

Section titled “1. Elliptical Distance Fields and Hash Variations”

In VoxelCloudShape.Generate, generate irregular elliptical clusters using integer bit-rotation hashes:

public static IReadOnlyList<Vector3Int> Generate(int seed)
{
int halfLength = 3 + PositiveModulo(seed, 4);
int halfWidth = 2 + PositiveModulo(seed ^ 0x4F1BBCDC, 3);
var voxels = new List<Vector3Int>((halfLength * 2 + 1) * (halfWidth * 2 + 1));
for (int z = -halfWidth; z <= halfWidth; z++)
{
for (int x = -halfLength; x <= halfLength; x++)
{
float normalizedDistance = (x * x) / (float)(halfLength * halfLength)
+ (z * z) / (float)(halfWidth * halfWidth);
// Outer irregular boundary:
if (normalizedDistance > 1.05f + HashToSignedUnit(x, 0, z, seed) * 0.22f)
{
continue;
}
// Bottom base layer:
voxels.Add(new Vector3Int(x, 0, z));
// Stepped upper layer:
if (normalizedDistance < 0.72f + HashToSignedUnit(x, 1, z, seed) * 0.18f)
{
voxels.Add(new Vector3Int(x, 1, z));
}
}
}
// Mathematical guarantee: central anchor is never omitted!
if (voxels.Count == 0)
{
voxels.Add(Vector3Int.zero);
}
return voxels;
}

This ensures every generated cloud is guaranteed to have at least one block, eliminating invisible or zero-vertex cloud objects.

A common trap in large-world engines is that high-altitude objects jitter or stretch when the player walks far from world $(0, 0, 0)$. In VoxelCloudRuntime.cs, cloud positions are tracked in true double-precision world coordinates and reprojected into Unity scene space every frame using the chunk streaming render origin:

// Reproject true world position into camera-relative scene position:
Vector3 renderOffset = world != null ? world.RenderOriginOffset : Vector3.zero;
Vector3 scenePosition = cloud.WorldPosition - renderOffset;
cloud.Transform.position = scenePosition;

When a floating-origin rebase occurs, world.RenderOriginOffset jumps instantaneously by whole chunk widths. Because the cloud position is computed relative to that offset, the visual position in camera space is perfectly invariant—zero jitter, zero popping.

3. Prevailing Wind Drift and Dynamic Recycling

Section titled “3. Prevailing Wind Drift and Dynamic Recycling”

Clouds drift continuously along the barometric prevailing wind vector:

Vector2 windDirection = AtmosphericPressureField.PrevailingWind.normalized;
float speed = Mathf.Lerp(CalmDriftSpeed, GaleDriftSpeed, stormIntensity);
cloud.WorldPosition += new Vector3(windDirection.x, 0f, windDirection.y) * (speed * Time.deltaTime);
// Check boundary wrap-around relative to camera:
Vector3 cameraPosition = activeCamera.transform.position + renderOffset;
float distance = Vector2.Distance(
new Vector2(cloud.WorldPosition.x, cloud.WorldPosition.z),
new Vector2(cameraPosition.x, cameraPosition.z));
if (distance > CloudRecycleDistance)
{
// Recycle behind the camera along the wind vector:
cloud.WorldPosition = RespawnUpwind(cameraPosition, windDirection);
}

In VoxelCloudRuntime.UpdateLighting, cloud color and directional sun light dim dynamically as atmospheric pressure drops:

// Interpolate cloud albedo between crisp fair-weather white and deep storm grey:
Color cloudColor = Color.Lerp(FairWeatherCloudColor, StormCloudColor, stormIntensity);
cloudMaterial.color = cloudColor;
// Modulate directional sunlight intensity:
if (sun != null)
{
float lightMultiplier = Mathf.Lerp(1.0f, StormLightMinimum, stormIntensity);
sun.intensity = baseSunIntensity * lightMultiplier;
}

Run the dedicated voxel cloud shape tests:

Terminal window
/opt/unity/Editor/Unity -batchmode -nographics \
-projectPath /home/soulwax/workspace/engines/unity/minecraft/Minecraft-HD \
-runTests -testPlatform EditMode \
-testFilter VoxelSandbox.Tests.VoxelCloudShapeTests

Verify that all key assertions pass:

  • Generate_IsDeterministicForTheSameSeed: verifies byte-identical voxel outputs for repeated seeds.
  • Generate_ProducesACompactTwoLayerVoxelFormation: confirms voxel counts fall between $8$ and $180$ and $y \in {0, 1}$.
  • Generate_ChangesTheFormationForDifferentSeeds: proves seed diversity across different cloud instances.
  1. Enter Play Mode in Gameplay.unity.
  2. Locate [Voxel Sandbox] Voxel Clouds in the hierarchy.
  3. Observe the sky: 10 distinct cloud clusters drift smoothly overhead at $Y=255$.
  4. Fly with the character controller across several hundred meters:
    • Verify clouds do not jerk or jump when floating-origin rebases trigger.
    • Confirm clouds that drift past $330\text{ m}$ recycle seamlessly upwind.
  5. In the Inspector, adjust storm intensity from 0.0 to 1.0:
    • Watch clouds transition from crisp white to dark charcoal storm grey.
    • Watch ground sunlight dim smoothly to match the cloud cover.

To customize the cloud layer for high-latitude biomes or extraterrestrial worlds (e.g. High-Altitude Cirrus Streaks or Heavy Alien Smog):

  1. Adjust Cluster Ratios: In VoxelCloudShape.Generate, increase halfLength relative to halfWidth for stretched jet-stream clouds.
  2. Configure Base Elevation: Adjust CloudBaseWorldY in VoxelCloudRuntime for low-hanging fog valleys ($Y=64$) or stratosphere formations ($Y=384$).
  3. Customize Palette Tints: Adjust FairWeatherCloudColor and StormCloudColor for toxic yellow sulfur skies or Martian dust storms.
  4. Add EditMode Tests: Add test assertions in VoxelCloudShapeTests.cs.
Symptom Cause Fix
Clouds jitter or snap violently when moving across the world. Cloud positions were updated in scene space without subtracting RenderOriginOffset. Always evaluate scene position as WorldPosition - world.RenderOriginOffset on every frame.
Clouds clip into tall mountain peaks or skyscrapers. CloudBaseWorldY was authored below terrain generation height bounds. Place clouds strictly above maximum world height limit ($Y \ge 255$).
Cloud mesh has holes or fails to spawn on specific seeds. Hash function removed all voxel candidates. Enforce the fallback guarantee in VoxelCloudShape: if (voxels.Count == 0) voxels.Add(Vector3Int.zero);.
Clouds drift in a different direction from weather fronts and rain. Cloud velocity used an arbitrary vector instead of AtmosphericPressureField.PrevailingWind. Keep clouds aligned with global barometry via AtmosphericPressureField.PrevailingWind.normalized.
Cloud instances leak across scene transitions. Instances were parented to scene objects without DontDestroyOnLoad. The self-bootstrapping runtime uses DontDestroyOnLoad on its root GameObject and manages its own lifecycle.

User-contributed notes

Corrections, clarifications, and practical tips for this page. Anonymous is fine — a name is optional. Basic Markdown works: **bold**, *italic*, `code`, and links.

Notes policy

Notes are lightly filtered for spam and may be edited or removed. Keep them about this page — no support requests, no personal data, nothing you would not publish. Links are limited and marked nofollow.

  1. Loading notes…