AgentSkillsCN

voxel-burst-noise-sampler

噪声生成器(Perlin、Simplex、Cellular/Worley、FBM)完全兼容Burst Compiler,可用于程序化地形生成。当用户需要创建地形、生成地貌、洞穴生成、矿石分布,或任何程序化内容时,可使用此功能。

SKILL.md
--- frontmatter
name: voxel-burst-noise-sampler
description: Bộ sinh Noise (Perlin, Simplex, Cellular/Worley, FBM) tương thích hoàn toàn với Burst Compiler cho procedural terrain generation. Dùng khi user yêu cầu tạo terrain, sinh địa hình, cave generation, ore distribution, hoặc bất kỳ procedural content nào.

Voxel Burst Noise Sampler

Critical Instructions

  • 100% Burst Compatible: KHÔNG dùng UnityEngine.Mathf.PerlinNoise — nó không Burst-safe. Dùng Unity.Mathematics.noise.
  • Deterministic: Cùng seed + coordinate → cùng kết quả. Không dùng Random không seed.
  • Job Ready: Mọi hàm noise phải gọi được trong IJobParallelFor.Execute() mà không vi phạm safety.
  • Project Convention: Đặt file vào Assets/Scripts/Core/Jobs/ hoặc Assets/Scripts/Environment/.

Core Principles

  • Unity.Mathematics: Dùng noise.cnoise() (classic Perlin), noise.snoise() (simplex), noise.cellular() cho noise cơ bản.
  • FBM Layering: Xếp chồng nhiều octave noise để tạo chi tiết tự nhiên.
  • 3D Noise: Thế giới voxel yêu cầu 3D noise (không chỉ 2D heightmap) cho cave, overhang.
  • Scale & Offset: Luôn parameterize frequency, amplitude, persistence, lacunarity, seed offset.

Noise Types Reference

1. Perlin Noise (Classic)

Smooth, gradient-based. Dùng cho terrain hills, gentle elevation.

csharp
using Unity.Burst;
using Unity.Mathematics;

/// <summary>
/// Burst-safe Perlin noise wrapper.
/// </summary>
[BurstCompile]
public static class BurstNoise
{
    /// <summary>
    /// 2D Perlin noise, range approximately [-1, 1].
    /// </summary>
    [BurstCompile]
    public static float Perlin2D(float2 coord, float frequency, float2 offset)
    {
        return noise.cnoise((coord + offset) * frequency);
    }

    /// <summary>
    /// 3D Perlin noise cho cave/overhang generation.
    /// </summary>
    [BurstCompile]
    public static float Perlin3D(float3 coord, float frequency, float3 offset)
    {
        return noise.cnoise((coord + offset) * frequency);
    }
}

2. Simplex Noise

Ít artifact hơn Perlin ở chiều cao. Tốt cho organic features.

csharp
/// <summary>
/// 3D Simplex noise, range approximately [-1, 1].
/// </summary>
[BurstCompile]
public static float Simplex3D(float3 coord, float frequency, float3 offset)
{
    return noise.snoise((coord + offset) * frequency);
}

3. Cellular / Worley Noise

Tạo pattern dạng tế bào. Dùng cho ore veins, crystal formations, biome boundaries.

csharp
/// <summary>
/// Cellular noise. Returns (F1, F2) distances.
/// F1 = khoảng cách tới điểm gần nhất. F2 - F1 = cell edge.
/// </summary>
[BurstCompile]
public static float2 Cellular2D(float2 coord, float frequency, float2 offset)
{
    return noise.cellular((coord + offset) * frequency).xy;
}

4. Fractal Brownian Motion (FBM)

Xếp chồng nhiều octave noise → chi tiết đa tỷ lệ.

csharp
/// <summary>
/// FBM: Xếp chồng octaves với persistence giảm dần.
/// Tạo terrain tự nhiên có cả đồi lớn lẫn chi tiết nhỏ.
/// </summary>
[BurstCompile]
public static float FBM3D(float3 coord, FBMParams param)
{
    float value = 0f;
    float amplitude = 1f;
    float frequency = param.BaseFrequency;
    float maxValue = 0f;

    for (int i = 0; i < param.Octaves; i++)
    {
        value += noise.cnoise((coord + param.Offset) * frequency) * amplitude;
        maxValue += amplitude;

        amplitude *= param.Persistence;   // typically 0.5
        frequency *= param.Lacunarity;    // typically 2.0
    }

    return value / maxValue; // Normalize to [-1, 1]
}

/// <summary>
/// Parameters cho FBM noise generation. Burst-safe struct.
/// </summary>
public struct FBMParams
{
    public float BaseFrequency;  // 0.01 - 0.1 cho terrain
    public float Persistence;    // 0.4 - 0.6 (amplitude decay per octave)
    public float Lacunarity;     // 1.8 - 2.2 (frequency multiply per octave)
    public int Octaves;          // 4 - 8
    public float3 Offset;       // Seed-based offset

    public static FBMParams Default => new FBMParams
    {
        BaseFrequency = 0.02f,
        Persistence = 0.5f,
        Lacunarity = 2.0f,
        Octaves = 6,
        Offset = float3.zero
    };
}

Project-Specific Patterns (VisualWorld)

Terrain Density Function

csharp
/// <summary>
/// Hàm mật độ 3D: density > 0 = solid, density <= 0 = air.
/// Kết hợp heightmap (2D FBM) + cave carving (3D noise).
/// </summary>
[BurstCompile]
public struct TerrainDensityJob : IJobParallelFor
{
    [WriteOnly] public NativeArray<VoxelData> Voxels;
    public int3 ChunkSize;         // (32, 32, 32)
    public int3 ChunkWorldOffset;  // Chunk position in world coords
    public float VoxelSize;        // 0.02m (2cm)

    // Noise params
    public FBMParams TerrainFBM;   // Macro terrain shape
    public FBMParams CaveFBM;      // Cave carving
    public FBMParams OreFBM;       // Ore distribution
    public float SeaLevel;         // Y level for water
    public float CaveThreshold;    // Density cutoff for caves

    public void Execute(int index)
    {
        // Flat index → 3D local coord
        int lx = index % ChunkSize.x;
        int ly = (index / ChunkSize.x) % ChunkSize.y;
        int lz = index / (ChunkSize.x * ChunkSize.y);

        // World position
        float3 worldPos = (new int3(lx, ly, lz) + ChunkWorldOffset) * VoxelSize;

        // --- 1. Base terrain height (2D FBM) ---
        float terrainHeight = BurstNoise.FBM3D(
            new float3(worldPos.x, 0, worldPos.z),
            TerrainFBM
        ) * 64f + 32f; // Map to world height

        // --- 2. Density = height - y ---
        float density = terrainHeight - worldPos.y;

        // --- 3. Cave carving (3D noise) ---
        float caveNoise = BurstNoise.FBM3D(worldPos, CaveFBM);
        if (caveNoise > CaveThreshold)
            density = -1f; // Carve cave

        // --- 4. Determine material ---
        var voxel = new VoxelData();
        if (density > 0)
        {
            voxel.State = 1; // Solid
            voxel.MaterialID = DetermineMaterial(worldPos, density);
        }
        else if (worldPos.y < SeaLevel)
        {
            voxel.State = 2; // Liquid (water)
            voxel.MaterialID = 10; // Water ID
        }
        else
        {
            voxel.State = 0; // Air
        }

        Voxels[index] = voxel;
    }

    private byte DetermineMaterial(float3 pos, float density)
    {
        // Surface layer (density < 2) → Grass/Dirt
        if (density < 2f) return 1; // Grass
        if (density < 5f) return 2; // Dirt

        // Ore distribution (cellular noise)
        float oreNoise = BurstNoise.FBM3D(pos, OreFBM);
        if (oreNoise > 0.7f) return 20; // Iron Ore
        if (oreNoise > 0.85f) return 21; // Gold Ore

        return 3; // Stone (default deep material)
    }
}

Biome Blending

csharp
/// <summary>
/// Xác định biome tại vị trí (x,z) bằng Cellular noise.
/// Trả về biome weights cho blending giữa các biome lân cận.
/// </summary>
[BurstCompile]
public static int GetBiome(float2 worldXZ, float frequency, float2 offset)
{
    float2 cell = BurstNoise.Cellular2D(worldXZ, frequency, offset);
    float biomeValue = cell.x * 4f; // Map F1 tới biome index
    return (int)math.clamp(biomeValue, 0, 3);
    // 0=Plains, 1=Forest, 2=Desert, 3=Mountains
}

Common Presets

Use CaseNoise TypeFrequencyOctavesPersistence
Macro terrainFBM (Perlin)0.005 - 0.026-80.5
Hills/valleysFBM (Perlin)0.02 - 0.054-60.45
Cave tunnelsFBM 3D (Simplex)0.03 - 0.083-40.5
Ore veinsCellular + Perlin0.1 - 0.32-30.6
Surface detailFBM (Perlin)0.1 - 0.52-30.3
Biome zonesCellular 2D0.001 - 0.0051
RiversRidged FBM0.005 - 0.0140.5

Seed Management

csharp
/// <summary>
/// Tạo deterministic offset từ world seed.
/// Mỗi noise layer có offset riêng để tránh correlation.
/// </summary>
[BurstCompile]
public static float3 SeedToOffset(uint worldSeed, int layerIndex)
{
    // Hash-based: mỗi layer có hash riêng từ seed
    uint h = math.hash(new uint2(worldSeed, (uint)layerIndex));
    return new float3(
        (h & 0xFFFF) / 65535f * 10000f,
        ((h >> 8) & 0xFFFF) / 65535f * 10000f,
        ((h >> 16) & 0xFFFF) / 65535f * 10000f
    );
}

Validation Checklist

  • Không dùng UnityEngine.Mathf.PerlinNoise hay UnityEngine.Random
  • Tất cả hàm noise biên dịch được với Burst
  • FBM normalize output về range [-1, 1] hoặc [0, 1] tùy use case
  • Seed deterministic: cùng input → cùng output
  • Frequency phù hợp voxel size (2cm) — không quá cao gây aliasing
  • Không allocate trong Execute (mọi buffer được allocate trước)
  • Terrain density function tạo kết quả hợp lý (có đất, có trời, có cave)