mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Fix shadow mapping for alpha-clipped meshes
This commit is contained in:
parent
dfd892b146
commit
716dc8f5f0
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
@ -276,6 +279,7 @@ void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_l
|
||||
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);
|
||||
|
BIN
test/res/models/floorwhite.glb
Normal file
BIN
test/res/models/floorwhite.glb
Normal file
Binary file not shown.
BIN
test/res/models/tree.glb
Normal file
BIN
test/res/models/tree.glb
Normal file
Binary file not shown.
@ -14,6 +14,7 @@
|
||||
#include "scene_manager.h"
|
||||
#include "window.h"
|
||||
#include <systems/collisions.h>
|
||||
#include <components/mesh_renderable.h>
|
||||
|
||||
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<engine::TransformComponent>(cast.hit_entity)->tag);
|
||||
c->perm_lines.emplace_back(ray.origin, cast.location, glm::vec3{0.0f, 0.0f, 1.0f});
|
||||
scene_->GetComponent<engine::MeshRenderableComponent>(cast.hit_entity)->visible ^= true;
|
||||
scene_->GetSystem<engine::MeshRenderSystem>()->RebuildStaticRenderList();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<engine::MeshRenderableComponent>(main_scene->GetEntity("Cube", floor))->visible = false;
|
||||
//main_scene->GetComponent<engine::MeshRenderableComponent>(main_scene->GetEntity("Cube", floor))->visible = false;
|
||||
|
||||
engine::Entity monke = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/monke.glb"), true);
|
||||
main_scene->GetComponent<engine::TransformComponent>(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<CameraControllerSystem>()->next_scene_ = main_scene;
|
||||
|
Loading…
Reference in New Issue
Block a user