gizmo-renderer 0.1.3

A custom ECS and physics engine aimed for realistic simulations.
Documentation
struct LightData {
    position:  vec4<f32>,  // xyz=pos, w=intensity
    color:     vec4<f32>,  // rgb=color, a=radius
    direction: vec4<f32>,  // xyz=dir (spot/directional), w=inner_cutoff_cos
    params:    vec4<f32>,  // x=outer_cutoff_cos, y=light_type (0=point,1=spot,2=dir)
};

struct SceneUniforms {
    view_proj: mat4x4<f32>,
    camera_pos: vec4<f32>,
    sun_direction: vec4<f32>,
    sun_color: vec4<f32>,
    lights: array<LightData, 10>,
    light_view_proj: array<mat4x4<f32>, 4>,
    cascade_splits: vec4<f32>,
    camera_forward: vec4<f32>,
    cascade_params: vec4<f32>,
    num_lights: u32,
    _pad_scene: vec3<u32>,
};

@group(0) @binding(0)
var<uniform> scene: SceneUniforms;

@group(1) @binding(0)
var t_diffuse: texture_2d<f32>;
@group(1) @binding(1)
var s_diffuse: sampler;

// Shadow bg
@group(2) @binding(0) var t_shadow: texture_depth_2d_array;
@group(2) @binding(1) var s_shadow: sampler_comparison;

struct SkeletonData {
    joints: array<mat4x4<f32>, 128>,
};
@group(3) @binding(0)
var<uniform> skeleton: SkeletonData;

struct InstanceData {
    model_matrix_0: vec4<f32>,
    model_matrix_1: vec4<f32>,
    model_matrix_2: vec4<f32>,
    model_matrix_3: vec4<f32>,
    albedo_color: vec4<f32>,
    pbr: vec4<f32>,
};

@group(4) @binding(0)
var<storage, read> instances: array<InstanceData>;

struct VertexInput {
    @location(0) position: vec3<f32>,
    @location(1) color: vec3<f32>,
    @location(2) normal: vec3<f32>,
    @location(3) tex_coords: vec2<f32>,
    @location(4) joint_indices: vec4<u32>,
    @location(5) joint_weights: vec4<f32>,
};

struct VertexOutput {
    @builtin(position) clip_position: vec4<f32>,
    @location(0) world_pos: vec3<f32>,
    @location(1) inst_albedo: vec4<f32>, // Renk çarpanı
};

@vertex
fn vs_main(@builtin(instance_index) instance_idx: u32, input: VertexInput) -> VertexOutput {
    var out: VertexOutput;
    
    let inst = instances[instance_idx];
    let model = mat4x4<f32>(
        inst.model_matrix_0,
        inst.model_matrix_1,
        inst.model_matrix_2,
        inst.model_matrix_3,
    );

    let world_pos = model * vec4<f32>(input.position, 1.0);
    
    // Skybox'ı kameranın etrafında sabit tutmak ve derinliğini en arkaya atmak için:
    // Fakat gizmo engine main loop'ta zaten kameraya takılır.
    out.clip_position = scene.view_proj * world_pos;
    // Derinlik testini kesin geçmesi için NDC z = 0.99999 yapıyoruz
    out.clip_position.z = out.clip_position.w * 0.99999;
    
    out.world_pos = world_pos.xyz;
    out.inst_albedo = inst.albedo_color;
    
    return out;
}

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    // 1. Ray Yönünü (Bakış Açısı) Hesapla
    let view_dir = normalize(in.world_pos - scene.camera_pos.xyz);
    
    // 2. Çok Şık Atmosferik Gradyan (Zenith ve Horizon)
    // Gökyüzü rengini güneşin rengiyle harmanla (Gün doğumu, öğle, gece efektleri için)
    let zenith_color = vec3<f32>(0.08, 0.25, 0.6) * scene.sun_color.rgb * scene.sun_color.w; // Koyu lacivert/mavi tepe noktası
    let horizon_color = vec3<f32>(0.5, 0.7, 0.9) * scene.sun_color.rgb * scene.sun_color.w; // Daha açık ufuk rengi
    let ground_color = vec3<f32>(0.2, 0.2, 0.2) * scene.sun_color.rgb * scene.sun_color.w; // Zemin rengi
    
    // Y eksenindeki durum (yukarı/aşağı)
    let y = view_dir.y; // -1 (Aşağı) ile 1 (Yukarı)
    
    var sky_color = vec3<f32>(0.0);
    
    if (y >= 0.0) {
        // Gökyüzü: Horizon'dan Zenith'e geçiş
        // pow kullanıp ufuk beyazlığını daraltıyoruz.
        let blend = pow(y, 0.5); 
        sky_color = mix(horizon_color, zenith_color, blend);
    } else {
        // Zemin: Horizon'dan Ground'a geçiş
        let blend = pow(max(-y, 0.0), 0.5);
        sky_color = mix(horizon_color, ground_color, blend);
    }
    
    // 3. Güneş Efekti (Sun Halo)
    // Güneş yönü pozitif ışık kaynağına doğru olan yöndür (Veya tersidir).
    // Güneş konumu: Işık yönünün tersi (ışık aşağı iniyorsa güneş yukarıdadır)
    let sun_pos_dir = normalize(-scene.sun_direction.xyz);
    let sun_dot = max(dot(view_dir, sun_pos_dir), 0.0);
    
    // Büyük ve yumuşak bir ışık halesi (Rayleigh Scattering simülasyonu)
    let sun_halo = pow(sun_dot, 6.0) * 0.4;
    
    // Küçük ve sivri bir güneş diski (Mie Scattering)
    let sun_disk = pow(sun_dot, 500.0) * 2.5;
    
    let sun_glow_color = scene.sun_color.rgb * (sun_halo + sun_disk);
    
    sky_color += sun_glow_color;
    
    // Tonlama sonrası return (HDR Render pass zaten ACES yapıyor)
    return vec4<f32>(sky_color, 1.0);
}