Implement configurable lighting

This commit is contained in:
Camden Dixie O'Brien committed 2025-10-05 13:51:14 +01:00
1 parent 070758b6cc
commit b5bda150d2
6 files changed
+148 -49

No files matched your search

+44 -18
View File
@@ -13,7 +13,7 @@
#define MAX_MODEL_COUNT 4
#define SHADOW_IMG_SIZE 2048
#define SHADOW_IMG_SIZE 4096
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
@@ -24,6 +24,11 @@
typedef struct {
mat4_t vp;
mat4_t light_vp;
} vps_t;
typedef struct {
vps_t vps;
light_params_t light;
} push_t;
static const char *layers[] = { "VK_LAYER_KHRONOS_validation" };
@@ -570,11 +575,18 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
.pAttachments = &colour_blend_attatchment,
};
// Set up push constant config
const VkPushConstantRange push_constant_range = {
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = 0,
.size = sizeof(push_t),
// Push constant configs
const VkPushConstantRange push_constants[] = {
{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = offsetof(push_t, vps),
.size = sizeof(vps_t),
},
{
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.offset = offsetof(push_t, light),
.size = sizeof(light_params_t),
},
};
// Load vertex and fragment shader modules
@@ -638,8 +650,8 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = &ctx->floor_desc_set_layout,
.pushConstantRangeCount = 1,
.pPushConstantRanges = &push_constant_range,
.pushConstantRangeCount = 2,
.pPushConstantRanges = push_constants,
};
result = vkCreatePipelineLayout(
ctx->dev, &floor_pipeline_layout_config, nullptr,
@@ -753,8 +765,8 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = &ctx->desc_set_layout,
.pushConstantRangeCount = 1,
.pPushConstantRanges = &push_constant_range,
.pushConstantRangeCount = 2,
.pPushConstantRanges = push_constants,
};
result = vkCreatePipelineLayout(
ctx->dev, &model_pipeline_layout_config, nullptr,
@@ -1187,12 +1199,18 @@ void gpu_model_cleanup(const gpu_ctx_t *ctx, const gpu_model_t *model)
}
void gpu_render(
const gpu_ctx_t *ctx, mat4_t vp, mat4_t light_vp, size_t model_count,
const gpu_model_t *models, const mat4_t **bone_matrices,
const mat4_t *model_transforms)
const gpu_ctx_t *ctx, mat4_t vp, light_params_t light,
size_t model_count, const gpu_model_t *models,
const mat4_t **bone_matrices, const mat4_t *model_transforms)
{
VkResult result;
// Compute light VP
const mat4_t light_view = mat4_lookat(
light.sun_dir, (vec3_t) { 0, 0, 0 }, (vec3_t) { 0, 1, 0 });
const mat4_t light_proj = mat4_orthographic(8, 8, -10, 10);
const mat4_t light_vp = mat4_mul(light_proj, light_view);
// Wait for previous frame to finish
vkWaitForFences(ctx->dev, 1, &ctx->in_flight, VK_TRUE, UINT64_MAX);
vkResetFences(ctx->dev, 1, &ctx->in_flight);
@@ -1238,7 +1256,7 @@ void gpu_render(
ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->shadow_pipeline);
vkCmdPushConstants(
ctx->cmd_buf, ctx->model_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT,
0, sizeof(push_t), &(push_t) { .vp = light_vp });
0, sizeof(vps_t), &(vps_t) { .vp = light_vp });
for (unsigned i = 0; i < model_count; ++i) {
vkCmdBindVertexBuffers(
ctx->cmd_buf, 0, 1, &models[i].vertex_buf,
@@ -1290,14 +1308,18 @@ void gpu_render(
vkCmdBeginRenderPass(
ctx->cmd_buf, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
const push_t push = { .vp = vp, .light_vp = light_vp };
const vps_t vps = { .vp = vp, .light_vp = light_vp };
// Draw floor
vkCmdBindPipeline(
ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->floor_pipeline);
vkCmdPushConstants(
ctx->cmd_buf, ctx->model_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT,
0, sizeof(push_t), &push);
ctx->cmd_buf, ctx->floor_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT,
offsetof(push_t, vps), sizeof(vps_t), &vps);
vkCmdPushConstants(
ctx->cmd_buf, ctx->floor_pipeline_layout,
VK_SHADER_STAGE_FRAGMENT_BIT, offsetof(push_t, light),
sizeof(light_params_t), &light);
vkCmdBindDescriptorSets(
ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx->floor_pipeline_layout, 0, 1, ctx->floor_desc_sets + curr_img, 0,
@@ -1309,7 +1331,11 @@ void gpu_render(
ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->model_pipeline);
vkCmdPushConstants(
ctx->cmd_buf, ctx->model_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT,
0, sizeof(push_t), &push);
offsetof(push_t, vps), sizeof(vps_t), &vps);
vkCmdPushConstants(
ctx->cmd_buf, ctx->model_pipeline_layout,
VK_SHADER_STAGE_FRAGMENT_BIT, offsetof(push_t, light),
sizeof(light_params_t), &light);
for (unsigned i = 0; i < model_count; ++i) {
vkCmdBindVertexBuffers(
ctx->cmd_buf, 0, 1, &models[i].vertex_buf,