Get shadows for armatures working, testing shadow pillar

main
parent 782e263e54
commit 6d3594c6ad

BIN
art/art.blend (Stored with Git LFS)

Binary file not shown.

240
main.c

@ -2750,6 +2750,8 @@ typedef struct {
sg_pipeline pip;
sg_image color_img;
sg_image depth_img;
sg_pipeline armature_pip;
} Shadow_State;
Shadow_State init_shadow_state();
@ -3319,8 +3321,6 @@ void init(void)
.label = "armature",
});
state.clear_depth_buffer_pass_action = (sg_pass_action)
{
.colors[0] = { .action = SG_ACTION_LOAD },
@ -3992,7 +3992,6 @@ void dbgplanerect(AABB aabb)
void draw_armature(Mat4 view, Mat4 projection, Transform t, Armature *armature)
{
MD_ArenaTemp scratch = MD_GetScratch(0, 0);
sg_apply_pipeline(state.armature_pip);
Mat4 model = transform_to_matrix(t);
@ -4004,80 +4003,6 @@ void draw_armature(Mat4 view, Mat4 projection, Transform t, Armature *armature)
.bones_tex_size = V2((float)armature->bones_texture_width,(float)armature->bones_texture_height),
};
int bones_tex_size = 4 * armature->bones_texture_width * armature->bones_texture_height;
MD_u8 *bones_tex = MD_ArenaPush(scratch.arena, bones_tex_size);
for(MD_u64 i = 0; i < armature->bones_length; i++)
{
Bone *cur = &armature->bones[i];
// for debug drawing
Vec3 from = MulM4V3(cur->matrix_local, V3(0,0,0));
Vec3 x = MulM4V3(cur->matrix_local, V3(cur->length,0,0));
Vec3 y = MulM4V3(cur->matrix_local, V3(0,cur->length,0));
Vec3 z = MulM4V3(cur->matrix_local, V3(0,0,cur->length));
Mat4 final = M4D(1.0f);
final = MulM4(cur->inverse_model_space_pos, final);
for(Bone *cur_in_hierarchy = cur; cur_in_hierarchy; cur_in_hierarchy = cur_in_hierarchy->parent)
{
//final = MulM4(cur_in_hierarchy->anim_poses[0].parent_space_pose, final);
int bone_index = (int)(cur_in_hierarchy - armature->bones);
//final = MulM4(get_animated_bone_transform(&armature->animations[0].tracks[bone_index], cur_in_hierarchy, elapsed_time), final);
final = MulM4(transform_to_matrix(armature->anim_blended_poses[bone_index]), final);
}
from = MulM4V3(final, from);
x = MulM4V3(final, x);
y = MulM4V3(final, y);
z = MulM4V3(final, z);
Mat4 transform_matrix = transform_to_matrix(t);
from = MulM4V3(transform_matrix, from);
x = MulM4V3(transform_matrix, x);
y = MulM4V3(transform_matrix, y);
z = MulM4V3(transform_matrix, z);
dbgcol(LIGHTBLUE)
dbgsquare3d(y);
dbgcol(RED)
dbg3dline(from, x);
dbgcol(GREEN)
dbg3dline(from, y);
dbgcol(BLUE)
dbg3dline(from, z);
for(int col = 0; col < 4; col++)
{
Vec4 to_upload = final.Columns[col];
int bytes_per_pixel = 4;
int bytes_per_column_of_mat = bytes_per_pixel * 4;
int bytes_per_row = bytes_per_pixel * armature->bones_texture_width;
for(int elem = 0; elem < 4; elem++)
{
float after_decoding = decode_normalized_float32(encode_normalized_float32(to_upload.Elements[elem]));
assert(fabsf(after_decoding - to_upload.Elements[elem]) < 0.01f);
}
memcpy(&bones_tex[bytes_per_column_of_mat*col + bytes_per_row*i + bytes_per_pixel*0], encode_normalized_float32(to_upload.Elements[0]).rgba, bytes_per_pixel);
memcpy(&bones_tex[bytes_per_column_of_mat*col + bytes_per_row*i + bytes_per_pixel*1], encode_normalized_float32(to_upload.Elements[1]).rgba, bytes_per_pixel);
memcpy(&bones_tex[bytes_per_column_of_mat*col + bytes_per_row*i + bytes_per_pixel*2], encode_normalized_float32(to_upload.Elements[2]).rgba, bytes_per_pixel);
memcpy(&bones_tex[bytes_per_column_of_mat*col + bytes_per_row*i + bytes_per_pixel*3], encode_normalized_float32(to_upload.Elements[3]).rgba, bytes_per_pixel);
}
}
sg_update_image(armature->bones_texture, &(sg_image_data){
.subimage[0][0] = (sg_range){bones_tex, bones_tex_size},
});
ARR_ITER(sg_image, state.threedee_bind.vs_images)
{
*it = (sg_image){0};
}
ARR_ITER(sg_image, state.threedee_bind.fs_images)
{
*it = (sg_image){0};
}
state.threedee_bind.vertex_buffers[0] = armature->loaded_buffer;
state.threedee_bind.vs_images[SLOT_threedee_bones_tex] = armature->bones_texture;
state.threedee_bind.fs_images[SLOT_threedee_tex] = armature->image;
@ -4090,7 +4015,6 @@ void draw_armature(Mat4 view, Mat4 projection, Transform t, Armature *armature)
num_vertices += (int)armature->vertices_length;
sg_draw(0, (int)armature->vertices_length, 1);
MD_ReleaseScratch(scratch);
}
typedef struct
@ -5011,7 +4935,7 @@ Shadow_State init_shadow_state() {
});
shadows.pip = sg_make_pipeline(&(sg_pipeline_desc){
sg_pipeline_desc desc = (sg_pipeline_desc){
.layout = {
.attrs = {
[ATTR_threedee_vs_pos_in].format = SG_VERTEXFORMAT_FLOAT3,
@ -5029,8 +4953,21 @@ Shadow_State init_shadow_state() {
},
.colors[0].pixel_format = SG_PIXELFORMAT_RGBA8,
.label = "shadow-map-pipeline"
});
};
shadows.pip = sg_make_pipeline(&desc);
desc.label = "armature-shadow-map-pipeline";
desc.shader = sg_make_shader(threedee_armature_shadow_mapping_shader_desc(sg_query_backend()));
sg_vertex_attr_desc skeleton_vertex_attrs[] = {
[ATTR_threedee_vs_skeleton_pos_in].format = SG_VERTEXFORMAT_FLOAT3,
[ATTR_threedee_vs_skeleton_uv_in].format = SG_VERTEXFORMAT_FLOAT2,
[ATTR_threedee_vs_skeleton_indices_in].format = SG_VERTEXFORMAT_USHORT4N,
[ATTR_threedee_vs_skeleton_weights_in].format = SG_VERTEXFORMAT_FLOAT4,
};
assert(ARRLEN(skeleton_vertex_attrs) < ARRLEN(desc.layout.attrs));
memcpy(desc.layout.attrs, skeleton_vertex_attrs, sizeof(skeleton_vertex_attrs));
shadows.armature_pip = sg_make_pipeline(&desc);
return shadows;
}
@ -5338,6 +5275,82 @@ void frame(void)
// Draw all the 3D drawn things. Draw the shadows, then draw the things with the shadows.
// Process armatures and upload their skeleton textures
{
// Animate armatures, and upload their bone textures. Also debug draw their skeleton
{
SLICE_ITER(DrawnThing, drawn_this_frame)
{
if(it->armature)
{
MD_ArenaTemp scratch = MD_GetScratch(0, 0);
Armature *armature = it->armature;
int bones_tex_size = 4 * armature->bones_texture_width * armature->bones_texture_height;
MD_u8 *bones_tex = MD_ArenaPush(scratch.arena, bones_tex_size);
for(MD_u64 i = 0; i < armature->bones_length; i++)
{
Bone *cur = &armature->bones[i];
// for debug drawing
Vec3 from = MulM4V3(cur->matrix_local, V3(0,0,0));
Vec3 x = MulM4V3(cur->matrix_local, V3(cur->length,0,0));
Vec3 y = MulM4V3(cur->matrix_local, V3(0,cur->length,0));
Vec3 z = MulM4V3(cur->matrix_local, V3(0,0,cur->length));
Mat4 final = M4D(1.0f);
final = MulM4(cur->inverse_model_space_pos, final);
for(Bone *cur_in_hierarchy = cur; cur_in_hierarchy; cur_in_hierarchy = cur_in_hierarchy->parent)
{
int bone_index = (int)(cur_in_hierarchy - armature->bones);
final = MulM4(transform_to_matrix(armature->anim_blended_poses[bone_index]), final);
}
from = MulM4V3(final, from);
x = MulM4V3(final, x);
y = MulM4V3(final, y);
z = MulM4V3(final, z);
Mat4 transform_matrix = transform_to_matrix(it->t);
from = MulM4V3(transform_matrix, from);
x = MulM4V3(transform_matrix, x);
y = MulM4V3(transform_matrix, y);
z = MulM4V3(transform_matrix, z);
dbgcol(LIGHTBLUE)
dbgsquare3d(y);
dbgcol(RED)
dbg3dline(from, x);
dbgcol(GREEN)
dbg3dline(from, y);
dbgcol(BLUE)
dbg3dline(from, z);
for(int col = 0; col < 4; col++)
{
Vec4 to_upload = final.Columns[col];
int bytes_per_pixel = 4;
int bytes_per_column_of_mat = bytes_per_pixel * 4;
int bytes_per_row = bytes_per_pixel * armature->bones_texture_width;
for(int elem = 0; elem < 4; elem++)
{
float after_decoding = decode_normalized_float32(encode_normalized_float32(to_upload.Elements[elem]));
assert(fabsf(after_decoding - to_upload.Elements[elem]) < 0.01f);
}
memcpy(&bones_tex[bytes_per_column_of_mat*col + bytes_per_row*i + bytes_per_pixel*0], encode_normalized_float32(to_upload.Elements[0]).rgba, bytes_per_pixel);
memcpy(&bones_tex[bytes_per_column_of_mat*col + bytes_per_row*i + bytes_per_pixel*1], encode_normalized_float32(to_upload.Elements[1]).rgba, bytes_per_pixel);
memcpy(&bones_tex[bytes_per_column_of_mat*col + bytes_per_row*i + bytes_per_pixel*2], encode_normalized_float32(to_upload.Elements[2]).rgba, bytes_per_pixel);
memcpy(&bones_tex[bytes_per_column_of_mat*col + bytes_per_row*i + bytes_per_pixel*3], encode_normalized_float32(to_upload.Elements[3]).rgba, bytes_per_pixel);
}
}
sg_update_image(armature->bones_texture, &(sg_image_data){
.subimage[0][0] = (sg_range){bones_tex, bones_tex_size},
});
MD_ReleaseScratch(scratch);
}
}
}
// do the shadow pass
Mat4 light_space_matrix;
{
@ -5347,6 +5360,8 @@ void frame(void)
light_space_matrix = MulM4(shadow_projection, shadow_view);
sg_begin_pass(state.shadows.pass, &state.shadows.pass_action);
// shadows for meshes
sg_apply_pipeline(state.shadows.pip);
SLICE_ITER(DrawnThing, drawn_this_frame)
{
@ -5369,9 +5384,33 @@ void frame(void)
num_vertices += (int)it->mesh->num_vertices;
sg_draw(0, (int)it->mesh->num_vertices, 1);
}
}
// shadows for armatures
sg_apply_pipeline(state.shadows.armature_pip);
SLICE_ITER(DrawnThing, drawn_this_frame)
{
if(it->armature)
{
// @TODO
sg_bindings bindings = {0};
bindings.vs_images[SLOT_threedee_bones_tex] = it->armature->bones_texture;
bindings.fs_images[SLOT_threedee_tex] = it->armature->image;
bindings.vertex_buffers[0] = it->armature->loaded_buffer;
sg_apply_bindings(&bindings);
Mat4 model = transform_to_matrix(it->t);
threedee_skeleton_vs_params_t params = {
.model = model,
.view = shadow_view,
.projection = shadow_projection,
.directional_light_space_matrix = light_space_matrix,
.bones_tex_size = V2((float)it->armature->bones_texture_width,(float)it->armature->bones_texture_height),
};
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_threedee_skeleton_vs_params, &SG_RANGE(params));
num_draw_calls += 1;
num_vertices += (int)it->armature->vertices_length;
sg_draw(0, (int)it->armature->vertices_length, 1);
}
}
sg_end_pass();
@ -5381,8 +5420,8 @@ void frame(void)
{
sg_begin_default_pass(&state.clear_everything_pass_action, sapp_width(), sapp_height());
// draw meshes
sg_apply_pipeline(state.threedee_pip);
state.threedee_bind.fs_images[SLOT_threedee_shadow_map] = state.shadows.color_img;
SLICE_ITER(DrawnThing, drawn_this_frame)
{
if(it->mesh)
@ -5410,12 +5449,47 @@ void frame(void)
sg_draw(0, (int)it->mesh->num_vertices, 1);
}
}
// draw armatures armature rendering
sg_apply_pipeline(state.armature_pip);
SLICE_ITER(DrawnThing, drawn_this_frame)
{
if(it->armature)
{
sg_bindings bindings = {0};
bindings.vs_images[SLOT_threedee_bones_tex] = it->armature->bones_texture;
bindings.fs_images[SLOT_threedee_tex] = it->armature->image;
bindings.fs_images[SLOT_threedee_shadow_map] = state.shadows.color_img;
bindings.vertex_buffers[0] = it->armature->loaded_buffer;
sg_apply_bindings(&bindings);
Mat4 model = transform_to_matrix(it->t);
threedee_skeleton_vs_params_t params = {
.model = model,
.view = view,
.projection = projection,
.directional_light_space_matrix = light_space_matrix,
.bones_tex_size = V2((float)it->armature->bones_texture_width,(float)it->armature->bones_texture_height),
};
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_threedee_skeleton_vs_params, &SG_RANGE(params));
threedee_fs_params_t fs_params = {0};
fs_params.shadow_map_dimension = SHADOW_MAP_DIMENSION;
sg_apply_uniforms(SG_SHADERSTAGE_FS, SLOT_threedee_fs_params, &SG_RANGE(fs_params));
num_draw_calls += 1;
num_vertices += (int)it->armature->vertices_length;
sg_draw(0, (int)it->armature->vertices_length, 1);
}
*it = (DrawnThing){0};
}
// zero out everything
SLICE_ITER(DrawnThing, drawn_this_frame)
{
*it = (DrawnThing){0};
}
sg_end_pass();
}
drawn_this_frame_length = 0;

@ -272,3 +272,4 @@ void main() {
@program mesh vs fs
@program armature vs_skeleton fs
@program mesh_shadow_mapping vs fs_shadow_mapping
@program armature_shadow_mapping vs_skeleton fs_shadow_mapping

Loading…
Cancel
Save