rusting_engine 0.1.42

A high-performance Vulkano-based 3D engine with GPU physics.
Documentation
#version 450
layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;

const uint  HASH_SIZE    = 65521;
const uint  MAX_PER_CELL = 128;

struct InstanceData {
    mat4 model;     
    vec4 color;
    vec4 mat_props;
    vec4 velocity;  
    vec4 angular_velocity;  
    vec4 physic_props;      
};

layout(set = 0, binding = 0) readonly buffer ReadBuf  { InstanceData data[]; } read_buf;
layout(set = 0, binding = 2) buffer GridCounts        { uint data[]; } grid_counts;
layout(set = 0, binding = 3) buffer GridObjects       { uint data[]; } grid_objects;
layout(set = 0, binding = 4) readonly buffer BigIndices { uint data[]; } big_indices;

layout(push_constant) uniform PushConstants {
    float dt;           
    uint  total_objects;
    uint  offset;
    uint  count;
    uint  num_big_objects; 
    vec4  global_gravity; // w = CELL_SIZE
} pc;

uint hashCell(ivec3 c) {
    uvec3 u = uvec3(c);
    return (u.x * 2654435761u ^ u.y * 2246822519u ^ u.z * 3266489917u) % HASH_SIZE;
}

vec3 extractScale(mat4 m) {
    return vec3(length(m[0].xyz), length(m[1].xyz), length(m[2].xyz));
}

void main() {
    uint i = gl_GlobalInvocationID.x;
    if (i >= pc.total_objects) return;

    InstanceData me = read_buf.data[i];
    
    // Using x * 0.5 as radius
    float radius = extractScale(me.model).x * 0.5;
    
    // Ignore big objects (handled by BigIndices array)
    if (radius > 2.5) return;
    vec3 pos = me.model[3].xyz;
    
    float cell_size = pc.global_gravity.w;
    
    ivec3 cell = ivec3(floor(pos / cell_size));
    uint h = hashCell(cell);

    // Atomically increment the count for this hash cell
    uint idx = atomicAdd(grid_counts.data[h], 1);
    if (idx < MAX_PER_CELL) {
        grid_objects.data[h * MAX_PER_CELL + idx] = i;
    }
}