OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / distribute / hypertps-win64 / shaders / generators / grid_sdf.glsl

59 lines · glsl ref:
// =====================================================================
// Grid SDF body — trilinear interpolation from the density grid.
//
// Provides: float evaluate_density(float x, float y, float z)
//
// Used by the hybrid GPU path: CPU fills the density grid, this SDF
// reads from it for edge_intersect (binary search) and surface_normals
// (central differences). Less accurate than full SDF evaluation but
// works with any DCGenerator that has no GPU shader.
//
// Requires (declared by template):
//   - density[] (DensityBuf at binding 0)
//   - Params UBO fields: grid_stride, voxel_scale, origin_x/y/z
// =====================================================================

float clampf(float v, float lo, float hi) {
    return clamp(v, lo, hi);
}

float evaluate_density(float x, float y, float z) {
    // Convert world position to grid coordinates
    float gx = (x - origin_x) / voxel_scale;
    float gy = (y - origin_y) / voxel_scale;
    float gz = (z - origin_z) / voxel_scale;

    int s = grid_stride;

    // Integer grid coordinates (clamped to valid range)
    int ix = clamp(int(floor(gx)), 0, s - 2);
    int iy = clamp(int(floor(gy)), 0, s - 2);
    int iz = clamp(int(floor(gz)), 0, s - 2);

    // Fractional parts
    float fx = clampf(gx - float(ix), 0.0, 1.0);
    float fy = clampf(gy - float(iy), 0.0, 1.0);
    float fz = clampf(gz - float(iz), 0.0, 1.0);

    // Base index
    int idx = iz * s * s + iy * s + ix;

    // 8-corner trilinear interpolation
    float d000 = density[idx];
    float d100 = density[idx + 1];
    float d010 = density[idx + s];
    float d110 = density[idx + s + 1];
    float d001 = density[idx + s * s];
    float d101 = density[idx + s * s + 1];
    float d011 = density[idx + s * s + s];
    float d111 = density[idx + s * s + s + 1];

    float d00 = mix(d000, d100, fx);
    float d10 = mix(d010, d110, fx);
    float d01 = mix(d001, d101, fx);
    float d11 = mix(d011, d111, fx);
    float d0 = mix(d00, d10, fy);
    float d1 = mix(d01, d11, fy);
    return mix(d0, d1, fz);
}