Shadows
This commit is contained in:
91
renderer/engine_buffers.jai
Normal file
91
renderer/engine_buffers.jai
Normal file
@@ -0,0 +1,91 @@
|
||||
calc_tight_light_projection :: (camera: Camera, light_direction: Vector3) -> Matrix4 {
|
||||
// View space camera frustum
|
||||
aspect_ratio := cast(float)renderer.render_target_height / cast(float)renderer.render_target_width;
|
||||
frustum := get_frustum(camera.fov, aspect_ratio, camera.z_near, camera.z_far);
|
||||
|
||||
// View frustum back to world space
|
||||
inv_camera_view := inverse(camera.view_matrix);
|
||||
view_frustum_in_world_space := transform(frustum, inv_camera_view);
|
||||
|
||||
// Transform world space camera frustum to light space (with origin in 0,0,0)
|
||||
light_view := look_at_lh(.{0,0,0}, light_direction, .{0,1,0});
|
||||
light_space_frustum := transform(view_frustum_in_world_space, light_view);
|
||||
|
||||
aabb := get_frustum_aabb(light_space_frustum);
|
||||
bottom_left := aabb.min;
|
||||
top_right := Vector3.{aabb.max.x, aabb.max.y, aabb.min.z};
|
||||
light_pos_world := (bottom_left + top_right) * 0.5;
|
||||
|
||||
inverse_light_view := inverse(light_view);
|
||||
light_pos_world = transform_position(light_pos_world, inverse_light_view);
|
||||
|
||||
light_view = look_at_lh(light_pos_world, light_pos_world + light_direction, .{0,1,0});
|
||||
light_space_frustum = transform(view_frustum_in_world_space, light_view);
|
||||
|
||||
final_aabb := get_frustum_aabb(light_space_frustum);
|
||||
// @Incomplete: Padding
|
||||
|
||||
light_projection := orthographic_lh_projection_matrix(final_aabb.min.x, final_aabb.max.x, final_aabb.min.y, final_aabb.max.y, final_aabb.min.z, final_aabb.max.z);
|
||||
|
||||
|
||||
return light_projection * light_view;
|
||||
}
|
||||
|
||||
update_light_buffer :: () {
|
||||
scene := current_scene;
|
||||
camera := scene.camera;
|
||||
|
||||
light_data : Directional_Light_Buffer_Data;
|
||||
light_data.direction = scene.directional_light.direction;
|
||||
light_data.color_and_intensity = scene.directional_light.color_and_intensity;
|
||||
|
||||
light_matrix := calc_tight_light_projection(camera, scene.directional_light.direction.xyz);
|
||||
light_data.light_matrix = light_matrix;
|
||||
|
||||
upload_data_to_buffer(renderer, directional_light_buffer, *light_data, size_of(Directional_Light_Buffer_Data));
|
||||
}
|
||||
|
||||
sync_engine_buffers :: () {
|
||||
update_light_buffer();
|
||||
|
||||
// Camera buffer
|
||||
camera := *current_scene.camera;
|
||||
|
||||
camera_data : Camera_Data;
|
||||
camera_data.projection_matrix = camera.projection_matrix;
|
||||
camera_data.view_matrix = camera.view_matrix;
|
||||
camera_data.position = to_v4(camera.position);
|
||||
upload_data_to_buffer(renderer, camera_buffer, *camera_data, size_of(Camera_Data));
|
||||
|
||||
shader_time : Shader_Time;
|
||||
shader_time.time = time;
|
||||
upload_data_to_buffer(renderer, time_buffer, *shader_time, size_of(Shader_Time));
|
||||
|
||||
// Sync entity transforms
|
||||
for current_scene.entities {
|
||||
if it.flags & .RENDERABLE {
|
||||
if it.renderable.type == {
|
||||
case .MODEL; {
|
||||
for n, i: it.renderable.model.nodes {
|
||||
if n.meshes.count > 0 {
|
||||
node_data := *it.renderable.nodes[i];
|
||||
upload_data_to_buffer(renderer, node_data.transform_buffer, *node_data.transform.world_matrix, size_of(Matrix4));
|
||||
|
||||
if node_data.num_bones > 0 {
|
||||
for handle, mesh_index: n.meshes {
|
||||
m := parray_get(*renderer.meshes, handle);
|
||||
bones : [MAX_BONES] Matrix4;
|
||||
for bone_index: 0..m.num_bones-1 {
|
||||
bone := *it.renderable.nodes[m.bone_indices[bone_index]];
|
||||
bones[bone_index] = bone.transform.world_matrix * m.bone_matrices[bone_index];
|
||||
}
|
||||
upload_data_to_buffer(renderer, node_data.bone_buffers[mesh_index], bones.data, size_of(Matrix4) * m.num_bones);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user