diff options
author | quou <quou@disroot.org> | 2025-01-02 15:42:05 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2025-01-02 15:42:05 +1100 |
commit | b03109dbb087bd441c0e3905753f3dd97d44d7b8 (patch) | |
tree | 9f4372b2aa643c29cdd338b8776c02d175b4a881 | |
parent | 6d4b56258b89ba12bec5e329b81de62284c47ce1 (diff) |
Simpler depth prepass shader
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | c2.cpp | 4 | ||||
-rw-r--r-- | convmodel.c | 15 | ||||
-rw-r--r-- | intermediate/monkey.glb | bin | 40636 -> 40752 bytes | |||
-rw-r--r-- | intermediate/surface_depthonly.glsl | 43 | ||||
-rw-r--r-- | model.cpp | 48 | ||||
-rw-r--r-- | model.hpp | 3 | ||||
-rw-r--r-- | src/monkey.blend | bin | 544320 -> 545256 bytes | |||
-rw-r--r-- | video.cpp | 49 |
9 files changed, 151 insertions, 20 deletions
@@ -2,7 +2,11 @@ target = c2 data_dir = data -shaders = $(data_dir)/triangle.csh $(data_dir)/ui.csh $(data_dir)/surface.csh +shaders = \ + $(data_dir)/triangle.csh \ + $(data_dir)/ui.csh \ + $(data_dir)/surface.csh \ + $(data_dir)/surface_depthonly.csh textures = \ $(data_dir)/22.tex \ $(data_dir)/kita.tex \ @@ -56,6 +60,9 @@ data/ui.csh: intermediate/ui.glsl | $(data_dir) sc data/surface.csh: intermediate/surface.glsl | $(data_dir) sc ./sc/sc intermediate/surface.glsl $(data_dir)/surface.csh +data/surface_depthonly.csh: intermediate/surface_depthonly.glsl | $(data_dir) sc + ./sc/sc intermediate/surface_depthonly.glsl $(data_dir)/surface_depthonly.csh + data/22.tex: intermediate/22.bmp | $(data_dir) convtexture ./convtexture intermediate/22.bmp $(data_dir)/22.tex bc1 @@ -273,9 +273,13 @@ extern "C" int entrypoint() { camera.asp = (float)bb.w / (float)bb.h; scene.update(camera, dev); ctx.debug_push("scene"); + ctx.debug_push("depth prepass"); scene.render(dev, &frame_arena, depth_prepass, clamped_linear); + ctx.debug_pop(); + ctx.debug_push("forward"); scene.render(dev, &frame_arena, pass2, clamped_linear); ctx.debug_pop(); + ctx.debug_pop(); ctx.debug_push("ui"); ui->render(&frame_arena, dev->get_backbuffer()); diff --git a/convmodel.c b/convmodel.c index 4e7184b..7963881 100644 --- a/convmodel.c +++ b/convmodel.c @@ -12,6 +12,7 @@ typedef struct { const char* shader; + const char* depth_shader; const char* material; } Node_Config; @@ -85,6 +86,17 @@ void parse_node_cfg(const cgltf_node* n, Node_Config* cfg) { } i++; } + if (tcmp(json, "depth_shader", t)) { + cfg->depth_shader = read_str(json, &t[1]); + if (string_len(cfg->depth_shader) > 27) { + print_err( + "depth_shader name %s too long (max 27 chars).\n", + cfg->depth_shader + ); + pbreak(3478); + } + i++; + } if (tcmp(json, "material", t)) { cfg->material = read_str(json, &t[1]); if (string_len(cfg->material) > 27) { @@ -255,6 +267,9 @@ void parse_node_mesh( string_copy(buf, cfg->shader); fwrite(buf, 1, sizeof buf, outfile); zero(buf, sizeof buf); + string_copy(buf, cfg->depth_shader); + fwrite(buf, 1, sizeof buf, outfile); + zero(buf, sizeof buf); string_copy(buf, cfg->material); fwrite(buf, 1, sizeof buf, outfile); fwrite(&vertex_size, 4, 1, outfile); diff --git a/intermediate/monkey.glb b/intermediate/monkey.glb Binary files differindex 3e8fd29..4452d96 100644 --- a/intermediate/monkey.glb +++ b/intermediate/monkey.glb diff --git a/intermediate/surface_depthonly.glsl b/intermediate/surface_depthonly.glsl new file mode 100644 index 0000000..f53a937 --- /dev/null +++ b/intermediate/surface_depthonly.glsl @@ -0,0 +1,43 @@ +#ifdef DESC +[program] +type: graphics +vertex: main +fragment: main + +[binding] +name: mesh +rate: vertex +[attribute] +name: position +type: vec3 + +[struct] +name: MVP +[variable] +name: model +type: mat4 +[variable] +name: view_projection +type: mat4 + +[cbuffer] +name: c_mvp +type: MVP +stage: vertex + +#endif + +#ifdef VERTEX_SHADER + +void main() { + vec4 pos = c_mvp.model * vec4(position, 1.0); + gl_Position = c_mvp.view_projection * pos; +} + +#endif + +#ifdef FRAGMENT_SHADER + +void main() {} + +#endif @@ -98,8 +98,9 @@ Asset* Model_Loader::load( Mesh& mesh = meshes[i]; int vertex_size, vertex_count; char shader_name[28]; + char depth_shader_name[28]; char material_name[28]; - Shader* shader; + Shader* shader, * depth_shader; pack_read(f, magic, 4); if ( magic[0] != 'M' || @@ -111,14 +112,19 @@ Asset* Model_Loader::load( return 0; } pack_read(f, shader_name, sizeof shader_name); + pack_read(f, depth_shader_name, sizeof depth_shader_name); pack_read(f, material_name, sizeof material_name); mesh.offset = icoff; shader = (Shader*)shaders->load(shader_name); + depth_shader = (Shader*)shaders->load(depth_shader_name); mesh.material = (Material*)shaders->load(material_name); assert(shader != 0); + assert(depth_shader != 0); assert(mesh.material != 0); mesh.shader = shader->id; + mesh.depth_shader = depth_shader->id; mesh.mvp_binding = shader->descriptor_binding("c_mvp"); + mesh.mvp_binding_depth = depth_shader->descriptor_binding("c_mvp"); mesh.mat_binding = shader->descriptor_binding("material"); mesh.mesh_binding = shader->binding_index("mesh"); assert(mesh.mvp_binding >= 0); @@ -346,25 +352,33 @@ void Model_Instance::render( draw.first_vertex = mesh.offset; draw.vertex_offset = mesh.vbo_offset; pb.begin(); - if (depth_only) + if (depth_only) { pb.depth(true, true, Depth_Mode::less); - else + pb.shader(mesh.depth_shader); + pb.cbuffer( + mesh.mvp_binding_depth, + mvp, + i * sizeof(MVP_Cbuffer), + sizeof(MVP_Cbuffer) + ); + } else { pb.depth(true, false, Depth_Mode::equal); + pb.shader(mesh.shader); + mesh.material->use(pb, sampler, dev->get_shader(mesh.shader)); + pb.cbuffer( + mesh.mat_binding, + mat, + i * sizeof(Mat_Cbuffer), + sizeof(Mat_Cbuffer) + ); + pb.cbuffer( + mesh.mvp_binding, + mvp, + i * sizeof(MVP_Cbuffer), + sizeof(MVP_Cbuffer) + ); + } pb.cull(Cull_Mode::back); - pb.shader(mesh.shader); - mesh.material->use(pb, sampler, dev->get_shader(mesh.shader)); - pb.cbuffer( - mesh.mvp_binding, - mvp, - i * sizeof(MVP_Cbuffer), - sizeof(MVP_Cbuffer) - ); - pb.cbuffer( - mesh.mat_binding, - mat, - i * sizeof(Mat_Cbuffer), - sizeof(Mat_Cbuffer) - ); pb.vertex_format(shader.vf); Pipeline& pip = pb.build(); ctx.submit(draw, pip, pass); @@ -26,9 +26,10 @@ struct Model; struct Mesh { int offset, vbo_offset, count; int parent, mesh_binding, mvp_binding, mat_binding; + int mvp_binding_depth; bool world_dirty; m4f world, local; - Shader_Id shader; + Shader_Id shader, depth_shader; Material* material; const m4f& get_world(Model& m); }; diff --git a/src/monkey.blend b/src/monkey.blend Binary files differindex cd6fbbc..87c3bad 100644 --- a/src/monkey.blend +++ b/src/monkey.blend @@ -828,6 +828,9 @@ struct Vertex_Format_Vk { void init(Device_Vk* dev, const Vertex_Format_Desc& desc); void destroy(Device_Vk* dev); static VkFormat format_from_svar_type(SVariable_Type type); + + void clone(Arena* arena); + void optimise(const Vertex_Format_Vk* shadervf); }; struct Sampler_Vk : public Late_Terminated { @@ -2608,13 +2611,19 @@ void Pipeline_Vk::init_vertex_input( VkGraphicsPipelineCreateInfo& info, const Pipeline& desc ) { - Vertex_Format_Vk& vf = dev->vertex_formats[desc.vertex_format]; + Vertex_Format_Vk vf = dev->vertex_formats[desc.vertex_format]; VkPipelineVertexInputStateCreateInfo& vi = *(VkPipelineVertexInputStateCreateInfo*)arena_alloc( &scope, sizeof vi ); zero(&vi, sizeof vi); + auto& shader = dev->get_shader(desc.shader); + if (shader.vf != desc.vertex_format) { + auto shader_vf = (Vertex_Format_Vk*)&dev->vertex_formats[shader.vf]; + vf.clone(&scope); + vf.optimise(shader_vf); + } vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vi.vertexBindingDescriptionCount = vf.binding_count; vi.pVertexBindingDescriptions = vf.bindings; @@ -3107,6 +3116,44 @@ void Vertex_Format_Vk::destroy(Device_Vk* dev) { heap_free(dev->heap, bindings); } +void Vertex_Format_Vk::clone(Arena* arena) { + int bc = binding_count * sizeof *bindings; + int ac = attr_count * sizeof *attrs; + auto nb = (VkVertexInputBindingDescription*)arena_alloc( + arena, + bc + ); + auto na = (VkVertexInputAttributeDescription*)arena_alloc( + arena, + ac + ); + memcpy(nb, bindings, bc); + memcpy(na, attrs, ac); + bindings = nb; + attrs = na; +} + +void Vertex_Format_Vk::optimise(const Vertex_Format_Vk* shadervf) { + int i; + if (shadervf->attr_count >= attr_count) return; + for (i = attr_count - 1; i >= 0; i--) { + auto& a = attrs[i]; + int j, idx = -1; + for (j = 0; j < shadervf->attr_count; j++) { + auto& b = shadervf->attrs[j]; + if (b.binding == a.binding && b.location == a.location) { + idx = j; + break; + } + } + if (idx == -1) { + int last = attr_count - 1; + attrs[i] = attrs[last]; + attr_count = last; + } + } +} + bool Shader_Vk::init_module( Device_Vk* dev, int stage, |