summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-01-02 15:42:05 +1100
committerquou <quou@disroot.org>2025-01-02 15:42:05 +1100
commitb03109dbb087bd441c0e3905753f3dd97d44d7b8 (patch)
tree9f4372b2aa643c29cdd338b8776c02d175b4a881
parent6d4b56258b89ba12bec5e329b81de62284c47ce1 (diff)
Simpler depth prepass shader
-rw-r--r--Makefile9
-rw-r--r--c2.cpp4
-rw-r--r--convmodel.c15
-rw-r--r--intermediate/monkey.glbbin40636 -> 40752 bytes
-rw-r--r--intermediate/surface_depthonly.glsl43
-rw-r--r--model.cpp48
-rw-r--r--model.hpp3
-rw-r--r--src/monkey.blendbin544320 -> 545256 bytes
-rw-r--r--video.cpp49
9 files changed, 151 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index 600bdda..b79b04c 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/c2.cpp b/c2.cpp
index 39a57c4..d7b475e 100644
--- a/c2.cpp
+++ b/c2.cpp
@@ -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
index 3e8fd29..4452d96 100644
--- a/intermediate/monkey.glb
+++ b/intermediate/monkey.glb
Binary files differ
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
diff --git a/model.cpp b/model.cpp
index 6aa6510..0b1dee7 100644
--- a/model.cpp
+++ b/model.cpp
@@ -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);
diff --git a/model.hpp b/model.hpp
index 53fb0fb..7b8f4fb 100644
--- a/model.hpp
+++ b/model.hpp
@@ -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
index cd6fbbc..87c3bad 100644
--- a/src/monkey.blend
+++ b/src/monkey.blend
Binary files differ
diff --git a/video.cpp b/video.cpp
index b8b3f51..06bfc30 100644
--- a/video.cpp
+++ b/video.cpp
@@ -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,