OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / distribute / hypertps-win64 / shaders / density_fill.glsl

145 lines · glsl ref:
#version 450

// Density field compute shader for Dual Contouring terrain.
// Template shader: the SDF body is injected at the GENERATOR_SDF_BODY marker
// by DCWorker at shader composition time.
//
// Each invocation computes one voxel corner density (and optionally normal).

layout(local_size_x = 8, local_size_y = 8, local_size_z = 8) in;

// ---- Outputs ----
layout(set = 0, binding = 0, std430) buffer DensityBuf  { float densities[]; };
layout(set = 0, binding = 1, std430) buffer NormalXBuf   { float normal_x[];  };
layout(set = 0, binding = 2, std430) buffer NormalYBuf   { float normal_y[];  };
layout(set = 0, binding = 3, std430) buffer NormalZBuf   { float normal_z[];  };

// ---- Parameters (std140) ----
layout(set = 0, binding = 4, std140) uniform Params {
    // Grid params (offset 0)
    int   grid_stride;           // 0
    float voxel_scale;           // 4
    float origin_x;              // 8
    float origin_y;              // 12
    float origin_z;              // 16

    // DensityConfig fields (offset 20)
    float primary_frequency;     // 20
    float primary_strength;      // 24
    float tunnel_frequency;      // 28
    float tunnel_strength;       // 32
    float tunnel_radius;         // 36
    float ridge_frequency;       // 40
    float ridge_strength;        // 44
    float warp_frequency;        // 48
    float warp_strength;         // 52
    float detail_frequency;      // 56
    float detail_strength;       // 60
    float ground_bias;           // 64
    float solid_floor_depth;     // 68
    float sky_height;            // 72
    float flat_center_radius;    // 76
    float floor_strength;        // 80
    float floor_height_min;      // 84
    float floor_height_max;      // 88
    float room_height;           // 92
    float terrain_size;          // 96

    // Pre-computed octave counts (offset 100)
    int primary_octaves;         // 100
    int tunnel_octaves;          // 104
    int ridge_octaves;           // 108
    int warp_octaves;            // 112
    int detail_octaves;          // 116

    // Flags (offset 120)
    int compute_normals;         // 120
    int seed;                    // 124
    int voronoi_cell_count;      // 128
    int use_noise;               // 132
    // Spherical mode
    int spherical;               // 136 — 1 = planet mode
    float planet_radius;         // 140
    float planet_center_x;       // 144
    float planet_center_y;       // 148
    float planet_center_z;       // 152
    float island_radius;         // 156
};

// ---- Voronoi cells: count followed by (x, z, floor_height) triples ----
layout(set = 0, binding = 5, std430) buffer VoronoiBuf {
    int   voronoi_count;
    float voronoi_data[];  // [x0, z0, h0, x1, z1, h1, ...]
};

// ---- Permutation tables: 6 x 512 ints ----
// Order: primary, tunnel_a, tunnel_b, ridge, warp, detail
layout(set = 0, binding = 6, std430) buffer PermBuf {
    int perm_tables[];  // 3072 entries total
};

// ---- CSG primitives ----
struct CSGPrimitive {
    uint  prim_type;     // 0=sphere, 1=box
    uint  op;            // 0=union, 1=subtract, 2=intersect
    uint  group;
    uint  flags;         // bit 0 = is_first_in_group
    float pos_x, pos_y, pos_z;
    float _pad0;
    float size_x, size_y, size_z;  // half_extents for box, radius in size_x for sphere
    float _pad1;
};

layout(set = 0, binding = 7, std430) readonly buffer CSGBuf {
    uint csg_count;
    uint _csg_pad[3];
    CSGPrimitive csg_primitives[];
};

// =====================================================================
// SDF body — injected by DCWorker from generator GLSL
// Must define: float evaluate_density(float x, float y, float z)
// =====================================================================
// GENERATOR_SDF_BODY

// =====================================================================
// Main
// =====================================================================

void main() {
    uvec3 gid = gl_GlobalInvocationID;
    int stride = grid_stride;

    if (int(gid.x) >= stride || int(gid.y) >= stride || int(gid.z) >= stride)
        return;

    int idx = int(gid.z) * stride * stride + int(gid.y) * stride + int(gid.x);

    float wx = origin_x + float(gid.x) * voxel_scale;
    float wy = origin_y + float(gid.y) * voxel_scale;
    float wz = origin_z + float(gid.z) * voxel_scale;

    float d = evaluate_density(wx, wy, wz);
    densities[idx] = d;

    // Optionally compute normals via tetrahedron gradient (same as DensityGrid::gradient)
    if (compute_normals != 0) {
        float h = voxel_scale * 2.0;
        float d0 = evaluate_density(wx + h, wy - h, wz - h);
        float d1 = evaluate_density(wx - h, wy - h, wz + h);
        float d2 = evaluate_density(wx - h, wy + h, wz - h);
        float d3 = evaluate_density(wx + h, wy + h, wz + h);
        // Negate for outward-facing normals (density positive = solid)
        float nx = -(d0 - d1 - d2 + d3);
        float ny = -(-d0 - d1 + d2 + d3);
        float nz = -(-d0 + d1 - d2 + d3);
        float len = sqrt(nx * nx + ny * ny + nz * nz);
        if (len > 1e-10) {
            nx /= len; ny /= len; nz /= len;
        }
        normal_x[idx] = nx;
        normal_y[idx] = ny;
        normal_z[idx] = nz;
    }
}