diff --git a/res/engine/shaders/fancy.frag b/res/engine/shaders/fancy.frag index 3c8a7b2..bb93668 100644 --- a/res/engine/shaders/fancy.frag +++ b/res/engine/shaders/fancy.frag @@ -34,6 +34,10 @@ float GGXDist(float alpha_2, float N_dot_H) { void main() { + const vec4 albedo_alpha = texture(materialSetAlbedoSampler, fragUV); + if (albedo_alpha.a < 0.9) discard; // discard fragments without alpha = 1.0 + const vec3 albedo = albedo_alpha.xyz; + const vec3 occlusion_roughness_metallic = vec3(texture(materialSetOcclusionRoughnessMetallic, fragUV)); const float ao = occlusion_roughness_metallic.r; const float roughness = occlusion_roughness_metallic.g; @@ -52,7 +56,6 @@ void main() { const vec3 emission = vec3(0.0, 0.0, 0.0); - const vec3 albedo = vec3(texture(materialSetAlbedoSampler, fragUV)); const vec3 N = GetNormal(); const vec3 V = normalize(fragViewPosTangentSpace - fragPosTangentSpace); @@ -91,19 +94,19 @@ void main() { projCoords.y = projCoords.y * 0.5 + 0.5; //float closestDepth = texture(globalSetShadowmap, projCoords.xy).r; const float currentDepth = max(projCoords.z, 0.0); - const float bias = max(0.02 * (1.0 - L_dot_N), 0.005); + const float bias = max(0.01 * (1.0 - L_dot_N), 0.005); //float shadow = currentDepth - bias > closestDepth ? 0.0 : 1.0; float shadow = 0.0; vec2 texelSize = 1.0 / textureSize(globalSetShadowmap, 0); - for(int x = -1; x <= 1; ++x) + for(int x = -2; x <= 2; ++x) { - for(int y = -1; y <= 1; ++y) + for(int y = -2; y <= 2; ++y) { float pcfDepth = texture(globalSetShadowmap, projCoords.xy + vec2(x, y) * texelSize).r; shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; } } - shadow /= 9.0; + shadow /= 25.0; lighting *= (1.0 - shadow); diff --git a/res/engine/shaders/shadow.frag b/res/engine/shaders/shadow.frag index a5e029e..d128cca 100644 --- a/res/engine/shaders/shadow.frag +++ b/res/engine/shaders/shadow.frag @@ -1,5 +1,9 @@ #version 450 +layout(set = 2, binding = 0) uniform sampler2D materialSetAlbedoSampler; + +layout(location = 0) in vec2 fragUV; + void main() { - // empty fragment shader + if (texture(materialSetAlbedoSampler, fragUV).a < 1.0) discard; } diff --git a/res/engine/shaders/shadow.vert b/res/engine/shaders/shadow.vert index ef94832..223830c 100644 --- a/res/engine/shaders/shadow.vert +++ b/res/engine/shaders/shadow.vert @@ -10,8 +10,12 @@ layout( push_constant ) uniform Constants { } constants; layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec2 inUV; + +layout(location = 0) out vec2 fragUV; void main() { + fragUV = inUV; gl_Position = globalSetUniformBuffer.lightSpaceMatrix * constants.model * vec4(inPosition, 1.0); //gl_Position.y *= -1.0; } diff --git a/src/gfx_device_vulkan.cpp b/src/gfx_device_vulkan.cpp index f988e7b..8b48cc6 100644 --- a/src/gfx_device_vulkan.cpp +++ b/src/gfx_device_vulkan.cpp @@ -72,7 +72,7 @@ static constexpr uint32_t FRAMES_IN_FLIGHT = 2; // This improved FPS by 5x static constexpr size_t PUSH_CONSTANT_MAX_SIZE = 128; // bytes static constexpr VkIndexType INDEX_TYPE = VK_INDEX_TYPE_UINT32; -static constexpr int kShadowmapSize = 2048; +static constexpr int kShadowmapSize = 4096; // structures and enums diff --git a/src/renderer.cpp b/src/renderer.cpp index 6ff15e0..743ff26 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -33,9 +33,9 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati global_uniform.layout = device_->CreateDescriptorSetLayout(globalSetBindings); global_uniform.set = device_->AllocateDescriptorSet(global_uniform.layout); const glm::vec3 light_location = glm::vec3{-0.4278, 0.7923, 0.43502} * 40.0f; - //const glm::vec3 light_location = glm::vec3{10.0f, 0.0f, 10.0f}; + // const glm::vec3 light_location = glm::vec3{10.0f, 0.0f, 10.0f}; const glm::mat4 light_proj = glm::orthoRH_ZO(-24.0f, 24.0f, -15.0f, 15.0f, 10.0f, 65.0f); - //const glm::mat4 light_proj = glm::perspectiveFovRH_ZO(glm::radians(90.0f), 1.0f, 1.0f, 5.0f, 50.0f); + // const glm::mat4 light_proj = glm::perspectiveFovRH_ZO(glm::radians(90.0f), 1.0f, 1.0f, 5.0f, 50.0f); const glm::mat4 light_view = glm::lookAtRH(light_location, glm::vec3{0.0f, 0.0f, 0.0f}, glm::vec3{0.0f, 0.0f, 1.0f}); global_uniform.uniform_buffer_data.data.proj = light_proj; global_uniform.uniform_buffer_data.data.lightSpaceMatrix = light_proj * light_view; @@ -195,6 +195,7 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati gfx::VertexFormat shadowVertexFormat{}; shadowVertexFormat.stride = sizeof(float) * 12; // using the full meshes so a lot of data is skipped shadowVertexFormat.attribute_descriptions.emplace_back(0, gfx::VertexAttribFormat::kFloat3, 0); // position + shadowVertexFormat.attribute_descriptions.emplace_back(1, gfx::VertexAttribFormat::kFloat2, sizeof(float) * 10); // uv gfx::PipelineInfo shadowPipelineInfo{}; shadowPipelineInfo.vert_shader_path = GetResourcePath("engine/shaders/shadow.vert"); shadowPipelineInfo.frag_shader_path = GetResourcePath("engine/shaders/shadow.frag"); @@ -205,6 +206,8 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati shadowPipelineInfo.line_primitives = false; shadowPipelineInfo.depth_attachment_only = true; shadowPipelineInfo.descriptor_set_layouts.emplace_back(GetGlobalSetLayout()); + shadowPipelineInfo.descriptor_set_layouts.emplace_back(GetFrameSetLayout()); + shadowPipelineInfo.descriptor_set_layouts.emplace_back(GetMaterialSetLayout()); shadow_pipeline = device_->CreatePipeline(shadowPipelineInfo); // shadow map image and sampler @@ -212,7 +215,7 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati gfx::SamplerInfo sampler_info{}; sampler_info.magnify = gfx::Filter::kLinear; sampler_info.minify = gfx::Filter::kLinear; - sampler_info.mipmap = gfx::Filter::kLinear; // trilinear is apparently good for shadow maps + sampler_info.mipmap = gfx::Filter::kNearest; // bilinear is apparently good for shadow maps, mips aren't used anyway sampler_info.wrap_u = gfx::WrapMode::kClampToBorder; // sampler reads 1.0 out of bounds which ensures no shadowing there sampler_info.wrap_v = gfx::WrapMode::kClampToBorder; sampler_info.wrap_w = gfx::WrapMode::kClampToBorder; @@ -272,10 +275,11 @@ void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_l gfx::DrawBuffer* shadow_draw = device_->BeginShadowmapRender(shadow_map); device_->CmdBindPipeline(shadow_draw, shadow_pipeline); device_->CmdBindDescriptorSet(shadow_draw, shadow_pipeline, global_uniform.set, 0); // only need light space matrix - if (static_list) { // only create shadow map with static meshes + if (static_list) { // only create shadow map with static meshes if (!static_list->empty()) { for (const auto& entry : *static_list) { device_->CmdPushConstants(shadow_draw, shadow_pipeline, 0, sizeof(entry.model_matrix), &entry.model_matrix); + device_->CmdBindDescriptorSet(shadow_draw, shadow_pipeline, entry.material_set, 2); device_->CmdBindVertexBuffer(shadow_draw, 0, entry.vertex_buffer); device_->CmdBindIndexBuffer(shadow_draw, entry.index_buffer); device_->CmdDrawIndexed(shadow_draw, entry.index_count, 1, 0, 0, 0); diff --git a/test/res/models/floorwhite.glb b/test/res/models/floorwhite.glb new file mode 100644 index 0000000..903e9de Binary files /dev/null and b/test/res/models/floorwhite.glb differ diff --git a/test/res/models/tree.glb b/test/res/models/tree.glb new file mode 100644 index 0000000..29f970b Binary files /dev/null and b/test/res/models/tree.glb differ diff --git a/test/src/camera_controller.cpp b/test/src/camera_controller.cpp index 4d338d6..a51161d 100644 --- a/test/src/camera_controller.cpp +++ b/test/src/camera_controller.cpp @@ -14,6 +14,7 @@ #include "scene_manager.h" #include "window.h" #include +#include CameraControllerSystem::CameraControllerSystem(engine::Scene* scene) : System(scene, {typeid(engine::TransformComponent).hash_code(), typeid(CameraControllerComponent).hash_code()}) @@ -212,6 +213,8 @@ void CameraControllerSystem::OnUpdate(float ts) LOG_INFO("Ray direction: {} {} {}", ray.direction.x, ray.direction.y, ray.direction.z); LOG_INFO("Hit Entity: {}", scene_->GetComponent(cast.hit_entity)->tag); c->perm_lines.emplace_back(ray.origin, cast.location, glm::vec3{0.0f, 0.0f, 1.0f}); + scene_->GetComponent(cast.hit_entity)->visible ^= true; + scene_->GetSystem()->RebuildStaticRenderList(); } } diff --git a/test/src/game.cpp b/test/src/game.cpp index 0e6a49f..7c5a03b 100644 --- a/test/src/game.cpp +++ b/test/src/game.cpp @@ -48,7 +48,7 @@ void PlayGame(GameSettings settings) engine::gfx::GraphicsSettings graphics_settings{}; graphics_settings.enable_validation = settings.enable_validation; graphics_settings.vsync = true; - graphics_settings.wait_for_present = false; + graphics_settings.wait_for_present = true; graphics_settings.msaa_level = engine::gfx::MSAALevel::kOff; graphics_settings.enable_anisotropy = true; @@ -94,7 +94,7 @@ void PlayGame(GameSettings settings) /* floor */ engine::Entity floor = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/floor.glb"), true); - // main_scene->GetComponent(main_scene->GetEntity("Cube", floor))->visible = false; + //main_scene->GetComponent(main_scene->GetEntity("Cube", floor))->visible = false; engine::Entity monke = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/monke.glb"), true); main_scene->GetComponent(monke)->position.y += 10.0f; @@ -141,6 +141,9 @@ void PlayGame(GameSettings settings) main_scene->GetPosition(teapot).y += 5.0f; main_scene->GetPosition(teapot).x -= 5.0f; main_scene->GetScale(teapot) *= 5.0f; + + engine::Entity tree = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/tree.glb"), true); + main_scene->GetPosition(tree) = glm::vec3{-5.0f, -5.0f, 0.0f}; } start_scene->GetSystem()->next_scene_ = main_scene;