| 41 | } |
| 42 | |
| 43 | void LightingSubpass::draw(vkb::core::CommandBufferC &command_buffer) |
| 44 | { |
| 45 | allocate_lights<DeferredLights>(scene.get_components<sg::Light>(), MAX_DEFERRED_LIGHT_COUNT); |
| 46 | command_buffer.bind_lighting(get_lighting_state(), 0, 4); |
| 47 | |
| 48 | // Get shaders from cache |
| 49 | auto &resource_cache = command_buffer.get_device().get_resource_cache(); |
| 50 | auto &vert_shader_module = resource_cache.request_shader_module(VK_SHADER_STAGE_VERTEX_BIT, get_vertex_shader(), lighting_variant); |
| 51 | auto &frag_shader_module = resource_cache.request_shader_module(VK_SHADER_STAGE_FRAGMENT_BIT, get_fragment_shader(), lighting_variant); |
| 52 | |
| 53 | std::vector<ShaderModule *> shader_modules{&vert_shader_module, &frag_shader_module}; |
| 54 | |
| 55 | // Create pipeline layout and bind it |
| 56 | auto &pipeline_layout = resource_cache.request_pipeline_layout(shader_modules); |
| 57 | command_buffer.bind_pipeline_layout(pipeline_layout); |
| 58 | |
| 59 | // we know, that the lighting subpass does not have any vertex stage input -> reset the vertex input state |
| 60 | assert(pipeline_layout.get_resources(ShaderResourceType::Input, VK_SHADER_STAGE_VERTEX_BIT).empty()); |
| 61 | command_buffer.set_vertex_input_state({}); |
| 62 | |
| 63 | // Get image views of the attachments |
| 64 | auto &render_target = get_render_context().get_active_frame().get_render_target(); |
| 65 | auto &target_views = render_target.get_views(); |
| 66 | assert(3 < target_views.size()); |
| 67 | |
| 68 | // Bind depth, albedo, and normal as input attachments |
| 69 | auto &depth_view = target_views[1]; |
| 70 | command_buffer.bind_input(depth_view, 0, 0, 0); |
| 71 | |
| 72 | auto &albedo_view = target_views[2]; |
| 73 | command_buffer.bind_input(albedo_view, 0, 1, 0); |
| 74 | |
| 75 | auto &normal_view = target_views[3]; |
| 76 | command_buffer.bind_input(normal_view, 0, 2, 0); |
| 77 | |
| 78 | // Set cull mode to front as full screen triangle is clock-wise |
| 79 | vkb::rendering::RasterizationStateC rasterization_state; |
| 80 | rasterization_state.cull_mode = VK_CULL_MODE_FRONT_BIT; |
| 81 | command_buffer.set_rasterization_state(rasterization_state); |
| 82 | |
| 83 | // Populate uniform values |
| 84 | LightUniform light_uniform; |
| 85 | |
| 86 | // Inverse resolution |
| 87 | light_uniform.inv_resolution.x = 1.0f / render_target.get_extent().width; |
| 88 | light_uniform.inv_resolution.y = 1.0f / render_target.get_extent().height; |
| 89 | |
| 90 | // Inverse view projection |
| 91 | light_uniform.inv_view_proj = glm::inverse(vkb::rendering::vulkan_style_projection(camera.get_projection()) * camera.get_view()); |
| 92 | |
| 93 | // Allocate a buffer using the buffer pool from the active frame to store uniform values and bind it |
| 94 | auto &render_frame = get_render_context().get_active_frame(); |
| 95 | auto allocation = render_frame.allocate_buffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(LightUniform)); |
| 96 | allocation.update(light_uniform); |
| 97 | command_buffer.bind_buffer(allocation.get_buffer(), allocation.get_offset(), allocation.get_size(), 0, 3, 0); |
| 98 | |
| 99 | // Draw full screen triangle triangle |
| 100 | command_buffer.draw(3, 1, 0, 0); |
nothing calls this directly
no test coverage detected