Real‑Time Volumetric Cloud Rendering in Unity Using Raymarching

Real‑Time Volumetric Fog in Unity Using 3D Textures and Compute Shaders
August 24, 2026
Building a Custom Story Graph Editor in Unity (Visual Narrative System
Building a Custom Story Graph Editor in Unity (Visual Narrative System)
August 31, 2026
Real‑Time Volumetric Fog in Unity Using 3D Textures and Compute Shaders
August 24, 2026
Building a Custom Story Graph Editor in Unity (Visual Narrative System
Building a Custom Story Graph Editor in Unity (Visual Narrative System)
August 31, 2026

Real‑Time Volumetric Cloud Rendering in Unity Using Raymarching

Volumetric clouds are one of the most visually striking effects in modern games.
Unlike billboard or particle clouds, volumetric clouds are true 3D density fields that interact with light realistically.
The most common technique to render them in real time is raymarching inside a density volume using 3D noise textures.

In this guide you will learn how to implement real-time volumetric clouds in Unity using:


1. How Volumetric Clouds Work

Volumetric clouds are represented by a density field:

Density(x,y,z) → 0..1

During rendering, a ray is traced through the atmosphere and samples cloud density at many points.
Lighting is computed by approximating how sunlight scatters inside the cloud.

Rendering equation (simplified):

CloudColor += Density * Light * Transmittance
Transmittance *= exp(-Density * StepLength)

2. Cloud Volume Setup

We define a world-space box where clouds exist (a “cloud layer”).

  • Bottom height: 1200m
  • Top height: 2200m
  • Thickness: 1000m

C# setup for cloud region:

public class CloudVolume : MonoBehaviour
{
    public float bottomHeight = 1200f;
    public float topHeight = 2200f;

    public Material cloudMaterial;

    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        cloudMaterial.SetFloat("_BottomHeight", bottomHeight);
        cloudMaterial.SetFloat("_TopHeight", topHeight);

        Graphics.Blit(src, dest, cloudMaterial);
    }
}

3. Noise Generation (Core of Cloud Density)

Modern cloud systems use a combination:

  • Base Perlin Noise
  • Worley Noise (cell noise)
  • Erosion noise using multi-octave Worley

Cloud density usually follows:

density = BaseNoise - Erosion

Store this in 3D textures:

RenderTexture noise3D;

void Create3DNoise()
{
    noise3D = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGBFloat);
    noise3D.dimension = UnityEngine.Rendering.TextureDimension.Tex3D;
    noise3D.volumeDepth = 128;
    noise3D.enableRandomWrite = true;
    noise3D.Create();
}

4. Cloud Raymarching Shader

The fragment shader casts a ray through the cloud box and accumulates color.

// CloudRaymarch.shader (fragment excerpt)

float3 RayOrigin = _WorldSpaceCameraPos;
float3 RayDir = normalize(viewDir);

float stepSize = 100.0;
float maxDistance = 30000.0;

float3 pos = RayOrigin;
float transmittance = 1.0;
float3 result = 0;

for (int i = 0; i < 128; i++)
{
    float3 p = pos;

    if (!InsideCloudVolume(p)) break;

    float density = SampleCloudDensity(p);

    if (density > 0.01)
    {
        float light = ComputeSunLight(p);
        result += density * light * transmittance;
        transmittance *= exp(-density * stepSize * 0.02);
        if (transmittance < 0.01) break;
    }

    pos += RayDir * stepSize;
}

return float4(result, 1);

5. Cloud Density Function

This function blends Perlin, Worley, and erosion noise.

float SampleCloudDensity(float3 p)
{
    float3 uvw = p * 0.0005;

    float baseNoise = tex3D(_BaseNoise, uvw).r;
    float worley = tex3D(_Worley, uvw).r;
    float erosion = tex3D(_Erosion, uvw * 0.5).r;

    float density = baseNoise - erosion * 0.6;

    return saturate(density);
}

6. Lighting Inside the Clouds

Lighting is computed by tracing a few steps toward the sun direction:

float ComputeSunLight(float3 p)
{
    float3 L = normalize(_SunDirection);
    float light = 1.0;

    float step = 300.0;

    for (int i = 0; i < 6; i++)
    {
        p += L * step;
        float d = SampleCloudDensity(p);
        light *= exp(-d * 0.1);
    }

    return light;
}

This creates volumetric shadows inside the cloud.


7. Adding Wind and Cloud Movement

Clouds look dead if they don’t move. Apply wind by offsetting noise sampling:

float3 uvw = (p + float3(_Time * windSpeed, 0, 0)) * 0.0004;

Move erosion noise at a different speed for realism.


8. Performance Optimization

Volumetric clouds are expensive; optimize carefully:

  • Use half-resolution rendering
  • Limit ray steps (64–128)
  • Use jittered sampling + temporal accumulation
  • Lower cloud layer thickness
  • Early exit when transmittance is low

Most AAA games render clouds at quarter resolution + TAA upscale.


9. Temporal Reprojection (Dramatic Quality Boost)

Blend the current frame with last frame:

final = lerp(currentFrame, previousFrame, 0.92)

This stabilizes noise and allows fewer raymarch steps.


10. Cloud Types You Can Build

  • Cumulus (fluffy)
  • Stratus (flat sheet)
  • Cirrus (thin high-altitude)
  • Storm clouds
  • Volumetric God rays+

Cloud type depends on noise shaping + height curves.


11. Summary

By combining raymarching, procedural 3D noise, and volumetric lighting, Unity can render extremely realistic real-time clouds similar to AAA engines.

  • Noise = cloud structure
  • Raymarching = shape rendering
  • Lighting = realism
  • Temporal accumulation = performance

This system is highly customizable and can integrate with day/night cycles, weather systems, and atmospheric scattering.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *


Skip to toolbar