From 2e116c0eae9c5271d3fbc4e605ee00e852c5613e Mon Sep 17 00:00:00 2001 From: Cameron Reikes Date: Fri, 7 Jul 2023 16:34:17 -0700 Subject: [PATCH] Broken shadows, move all shaders to one file, reuse fragment shader in armature and mesh programs --- armature.glsl | 79 --------------------------------------- main.c | 44 +++++++++++----------- run_codegen.bat | 1 - threedee.glsl | 99 ++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 112 insertions(+), 111 deletions(-) delete mode 100644 armature.glsl diff --git a/armature.glsl b/armature.glsl deleted file mode 100644 index 2d24dc6..0000000 --- a/armature.glsl +++ /dev/null @@ -1,79 +0,0 @@ -@module armature - -@vs vs -in vec3 pos_in; -in vec2 uv_in; -in vec4 indices_in; // is a sokol SG_VERTEXFORMAT_USHORT4N, a 16 bit unsigned integer treated as a floating point number due to webgl compatibility -in vec4 weights_in; - -out vec3 pos; -out vec2 uv; - -uniform vs_params { - mat4 model; - mat4 view; - mat4 projection; - vec2 bones_tex_size; -}; -uniform sampler2D bones_tex; - -float decode_normalized_float32(vec4 v) -{ - float sign = 2.0 * v.x - 1.0; - - return sign * (v.z*255.0 + v.y); -} - -void main() { - vec4 total_position = vec4(0.0f); - - for(int bone_influence_index = 0; bone_influence_index < 4; bone_influence_index++) - { - float index_float = indices_in[bone_influence_index]; - int index = int(index_float * 65535.0); - float weight = weights_in[bone_influence_index]; - - float y_coord = (0.5 + index)/bones_tex_size.y; - - mat4 bone_mat; - - for(int row = 0; row < 4; row++) - { - for(int col = 0; col < 4; col++) - { - bone_mat[col][row] = decode_normalized_float32(texture(bones_tex, vec2((0.5 + col*4 + row)/bones_tex_size.x, y_coord))); - } - } - - vec4 local_position = bone_mat * vec4(pos_in, 1.0f); - total_position += local_position * weight; - } - - gl_Position = projection * view * model * total_position; - //gl_Position = projection * view * model * vec4(pos_in, 1.0); - - pos = gl_Position.xyz; - uv = uv_in; -} -@end - -@fs fs -uniform sampler2D tex; -in vec3 pos; -in vec2 uv; -out vec4 frag_color; - -void main() { - vec4 col = texture(tex, uv); - if(col.a < 0.5) - { - discard; - } - else - { - frag_color = vec4(col.rgb, 1.0); - } -} -@end - -@program program vs fs diff --git a/main.c b/main.c index b87f767..83ba65b 100644 --- a/main.c +++ b/main.c @@ -1391,7 +1391,6 @@ ThreeDeeLevel load_level(MD_Arena *arena, MD_String8 binary_file) #include "assets.gen.c" #include "quad-sapp.glsl.h" #include "threedee.glsl.h" -#include "armature.glsl.h" #include "shadow_mapper.glsl.h" AABB level_aabb = { .upper_left = { 0.0f, 0.0f }, .lower_right = { TILE_SIZE * LEVEL_TILES, -(TILE_SIZE * LEVEL_TILES) } }; @@ -2827,12 +2826,12 @@ void draw_placed(Mat4 view, Mat4 projection, Mat4 light_matrix, PlacedMesh *cur) Mat4 model = transform_to_matrix(cur->t); - threedee_vs_params_t vs_params = {0}; - memcpy(vs_params.model, (float*)&model, sizeof(model)); - memcpy(vs_params.view, (float*)&view, sizeof(view)); - memcpy(vs_params.projection, (float*)&projection, sizeof(projection)); - - memcpy(vs_params.directional_light_space_matrix, (float*)&light_matrix, sizeof(light_matrix)); + threedee_vs_params_t vs_params = { + .model = model, + .view = view, + .projection = projection, + .directional_light_space_matrix = light_matrix, + }; sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_threedee_vs_params, &SG_RANGE(vs_params)); num_draw_calls += 1; @@ -3329,7 +3328,7 @@ void init(void) .label = "quad-pipeline", }); - desc = threedee_program_shader_desc(sg_query_backend()); + desc = threedee_mesh_shader_desc(sg_query_backend()); assert(desc); shd = sg_make_shader(desc); @@ -3359,7 +3358,7 @@ void init(void) .label = "threedee", }); - desc = armature_program_shader_desc(sg_query_backend()); + desc = threedee_armature_shader_desc(sg_query_backend()); assert(desc); shd = sg_make_shader(desc); @@ -3373,10 +3372,10 @@ void init(void) .layout = { .attrs = { - [ATTR_armature_vs_pos_in].format = SG_VERTEXFORMAT_FLOAT3, - [ATTR_armature_vs_uv_in].format = SG_VERTEXFORMAT_FLOAT2, - [ATTR_armature_vs_indices_in].format = SG_VERTEXFORMAT_USHORT4N, - [ATTR_armature_vs_weights_in].format = SG_VERTEXFORMAT_FLOAT4, + [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, } }, .colors[0].blend = (sg_blend_state) { // allow transparency @@ -4069,12 +4068,12 @@ void draw_armature(Mat4 view, Mat4 projection, Transform t, Armature *armature) Mat4 model = transform_to_matrix(t); - armature_vs_params_t params = {0}; - memcpy(params.model, (float*)&model, sizeof(model)); - memcpy(params.view, (float*)&view, sizeof(view)); - memcpy(params.projection, (float*)&projection, sizeof(projection)); - params.bones_tex_size[0] = (float)armature->bones_texture_width; - params.bones_tex_size[1] = (float)armature->bones_texture_height; + threedee_skeleton_vs_params_t params = { + .model = model, + .view = view, + .projection = projection, + .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); @@ -4151,12 +4150,13 @@ void draw_armature(Mat4 view, Mat4 projection, Transform t, Armature *armature) } state.threedee_bind.vertex_buffers[0] = armature->loaded_buffer; - state.threedee_bind.vs_images[SLOT_armature_bones_tex] = armature->bones_texture; - state.threedee_bind.fs_images[SLOT_armature_tex] = armature->image; + state.threedee_bind.vs_images[SLOT_threedee_bones_tex] = armature->bones_texture; + state.threedee_bind.fs_images[SLOT_threedee_tex] = armature->image; + state.threedee_bind.fs_images[SLOT_threedee_shadow_map] = state.shadows.color_img; sg_apply_bindings(&state.threedee_bind); - sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_armature_vs_params, &SG_RANGE(params)); + sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_threedee_skeleton_vs_params, &SG_RANGE(params)); num_draw_calls += 1; num_vertices += (int)armature->vertices_length; sg_draw(0, (int)armature->vertices_length, 1); diff --git a/run_codegen.bat b/run_codegen.bat index 3fe07a6..7a63ee7 100644 --- a/run_codegen.bat +++ b/run_codegen.bat @@ -15,7 +15,6 @@ mkdir gen @REM shaders thirdparty\sokol-shdc.exe --input quad.glsl --output gen\quad-sapp.glsl.h --slang glsl100:hlsl5:metal_macos:glsl330 || goto :error thirdparty\sokol-shdc.exe --input threedee.glsl --output gen\threedee.glsl.h --slang glsl100:hlsl5:metal_macos:glsl330 || goto :error -thirdparty\sokol-shdc.exe --input armature.glsl --output gen\armature.glsl.h --slang glsl100:hlsl5:metal_macos:glsl330 || goto :error thirdparty\sokol-shdc.exe --input shadow_mapper.glsl --output gen\shadow_mapper.glsl.h --slang glsl100:hlsl5:metal_macos:glsl330 || goto :error @REM metadesk codegen diff --git a/threedee.glsl b/threedee.glsl index 6cff400..f3e9962 100644 --- a/threedee.glsl +++ b/threedee.glsl @@ -1,5 +1,88 @@ @module threedee +@ctype mat4 Mat4 +@ctype vec4 Vec4 +@ctype vec3 Vec3 +@ctype vec2 Vec2 + + +// for this block, define a variable called `model_space_pos` to be used as an input +@block vs_compute_light_output + world_space_frag_pos = model * vec4(model_space_pos, 1.0); + vec4 frag_pos = view * world_space_frag_pos; + + //@Speed I think we can just take the third row here and be fine. + light_dir = normalize(inverse(directional_light_space_matrix) * vec4(0.0, 0.0, -1.0, 0.0)).xyz; + + light_space_fragment_position = directional_light_space_matrix * vec4(world_space_frag_pos.xyz, 1.0); + +@end + +@vs vs_skeleton +in vec3 pos_in; +in vec2 uv_in; +in vec4 indices_in; // is a sokol SG_VERTEXFORMAT_USHORT4N, a 16 bit unsigned integer treated as a floating point number due to webgl compatibility +in vec4 weights_in; + +out vec3 pos; +out vec2 uv; +out vec4 light_space_fragment_position; +out vec3 light_dir; +out vec4 world_space_frag_pos; + +uniform skeleton_vs_params { + mat4 model; + mat4 view; + mat4 projection; + mat4 directional_light_space_matrix; + vec2 bones_tex_size; +}; + +uniform sampler2D bones_tex; + +float decode_normalized_float32(vec4 v) +{ + float sign = 2.0 * v.x - 1.0; + + return sign * (v.z*255.0 + v.y); +} + +void main() { + vec4 total_position = vec4(0.0f); + + for(int bone_influence_index = 0; bone_influence_index < 4; bone_influence_index++) + { + float index_float = indices_in[bone_influence_index]; + int index = int(index_float * 65535.0); + float weight = weights_in[bone_influence_index]; + + float y_coord = (0.5 + index)/bones_tex_size.y; + + mat4 bone_mat; + + for(int row = 0; row < 4; row++) + { + for(int col = 0; col < 4; col++) + { + bone_mat[col][row] = decode_normalized_float32(texture(bones_tex, vec2((0.5 + col*4 + row)/bones_tex_size.x, y_coord))); + } + } + + vec4 local_position = bone_mat * vec4(pos_in, 1.0f); + total_position += local_position * weight; + } + + gl_Position = projection * view * model * total_position; + //gl_Position = projection * view * model * vec4(pos_in, 1.0); + + pos = gl_Position.xyz; + uv = uv_in; + + vec3 model_space_pos = (model * total_position).xyz; + @include_block vs_compute_light_output +} +@end + @vs vs in vec3 pos_in; in vec2 uv_in; @@ -21,14 +104,10 @@ void main() { pos = pos_in; uv = uv_in; - world_space_frag_pos = model * vec4(pos_in, 1.0); - vec4 frag_pos = view * world_space_frag_pos; - gl_Position = projection * frag_pos; - - //@Speed I think we can just take the third row here and be fine. - light_dir = normalize(inverse(directional_light_space_matrix) * vec4(0.0, 0.0, -1.0, 0.0)).xyz; + gl_Position = projection * view * model * vec4(pos_in, 1.0); - light_space_fragment_position = directional_light_space_matrix * vec4(world_space_frag_pos.xyz, 1.0); + vec3 model_space_pos = (model * vec4(pos_in, 1.0f)).xyz; + @include_block vs_compute_light_output } @end @@ -152,10 +231,12 @@ void main() { float lighting_factor = shadow_factor * n_dot_l; lighting_factor = lighting_factor * 0.5 + 0.5; - frag_color = vec4(col.rgb*lighting_factor, 1.0); + //frag_color = vec4(col.rgb*lighting_factor, 1.0); + frag_color = vec4(col.rgb, 1.0); } } @end -@program program vs fs +@program mesh vs fs +@program armature vs_skeleton fs