Commit 70b833df authored by Florian Oetke's avatar Florian Oetke
Browse files

added options to disable all effects, shadowmapping and TAA

parent df081fc2
......@@ -25,6 +25,7 @@ layout(set=2, binding = 1) uniform samplerShadow shadowmap_shadow_sampler; // sa
layout(set=2, binding = 2) uniform sampler shadowmap_depth_sampler; // sampler2D
layout (constant_id = 0) const int SHADOW_QUALITY = 1;
layout (constant_id = 1) const int SHADOWS = 1;
layout(push_constant) uniform Per_model_uniforms {
mat4 model;
......@@ -77,6 +78,9 @@ float calc_penumbra(vec3 surface_lightspace, float light_size, float rand,
out int num_occluders);
float sample_shadowmap(vec3 view_pos) {
if(SHADOWS==0)
return 1.0;
int shadowmap = int(model_uniforms.light_data2.r);
if(shadowmap<0)
return 1.0;
......
......@@ -47,18 +47,35 @@ namespace mirrage::renderer {
float min_display_luminance = 2.f;
float max_display_luminance = 150.0f;
bool taa = true;
bool ssao = true;
bool bloom = true;
float background_intensity = 0.f;
bool dynamic_shadows = false;
int debug_gi_layer = -1;
bool debug_geometry = true;
bool shadows = true;
bool dynamic_lighting = true;
int debug_gi_layer = -1;
bool debug_geometry = true;
};
#ifdef sf2_structDef
sf2_structDef(Renderer_settings, shadowmap_resolution, shadow_quality, gi, dynamic_shadows);
sf2_structDef(Renderer_settings,
shadowmap_resolution,
shadow_quality,
gi,
gi_highres,
gi_shadows,
gi_diffuse_mip_level,
gi_low_quality_mip_levels,
min_display_luminance,
max_display_luminance,
taa,
ssao,
bloom,
shadows,
dynamic_lighting,
debug_geometry);
#endif
struct Global_uniforms {
......
......@@ -7,7 +7,10 @@ namespace mirrage::renderer {
struct GBuffer {
public:
GBuffer(graphic::Device& device, std::int32_t width, std::int32_t height);
GBuffer(graphic::Device& device,
graphic::Descriptor_pool& desc_pool,
std::int32_t width,
std::int32_t height);
std::int32_t mip_levels;
......@@ -31,6 +34,8 @@ namespace mirrage::renderer {
vk::UniqueDescriptorSetLayout animation_data_layout;
vk::DescriptorSet animation_data; //< might change each frame!
bool shadowmapping_enabled = false;
std::int32_t max_shadowmaps = 1;
vk::UniqueDescriptorSetLayout shadowmaps_layout;
graphic::DescriptorSet shadowmaps;
......
......@@ -31,7 +31,8 @@ namespace mirrage::renderer {
vk::DescriptorType::eStorageImage,
vk::DescriptorType::eSampledImage,
vk::DescriptorType::eSampler}))
, _gbuffer(std::make_unique<GBuffer>(device(), factory._window.width(), factory._window.height()))
, _gbuffer(std::make_unique<GBuffer>(
device(), _descriptor_set_pool, factory._window.width(), factory._window.height()))
, _profiler(device(), 64)
, _global_uniform_descriptor_set_layout(
......@@ -84,13 +85,15 @@ namespace mirrage::renderer {
device().wait_idle();
for(auto& pass : _passes) {
pass.reset();
if(pass)
pass.reset();
}
_gbuffer.reset();
// recreate gbuffer and renderpasses
_gbuffer = std::make_unique<GBuffer>(device(), _factory->_window.width(), _factory->_window.height());
_gbuffer = std::make_unique<GBuffer>(
device(), _descriptor_set_pool, _factory->_window.width(), _factory->_window.height());
auto write_first_pp_buffer = true;
for(auto i = std::size_t(0); i < _passes.size(); i++) {
......@@ -127,7 +130,8 @@ namespace mirrage::renderer {
_frame_counter = (_frame_counter + 1) % 1000000;
for(auto& pass : _passes) {
pass->update(dt);
if(pass)
pass->update(dt);
}
}
void Deferred_renderer::draw()
......@@ -163,9 +167,10 @@ namespace mirrage::renderer {
// draw subpasses
for(auto& pass : _passes) {
auto _ = _profiler.push(pass->name());
pass->draw(_frame_data);
if(pass) {
auto _ = _profiler.push(pass->name());
pass->draw(_frame_data);
}
}
_frame_data.geometry_queue.clear();
......@@ -225,7 +230,8 @@ namespace mirrage::renderer {
_active_camera = Camera_state(*active, transform, viewport);
for(auto& p : _passes) {
p->process_camera(_active_camera.get_or_throw());
if(p)
p->process_camera(_active_camera.get_or_throw());
}
return _active_camera.get_or_throw();
......
......@@ -40,7 +40,10 @@ namespace mirrage::renderer {
}
} // namespace
GBuffer::GBuffer(graphic::Device& device, std::int32_t width, std::int32_t height)
GBuffer::GBuffer(graphic::Device& device,
graphic::Descriptor_pool& desc_pool,
std::int32_t width,
std::int32_t height)
: mip_levels(static_cast<std::int32_t>(std::floor(std::log2(std::min(width, height))) - 2))
, depth_format(get_depth_format(device))
, depth(device,
......@@ -104,6 +107,18 @@ namespace mirrage::renderer {
| vk::ImageUsageFlagBits::eInputAttachment | vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eStorage,
vk::ImageAspectFlagBits::eColor)
, shadowmaps_layout(device.create_descriptor_set_layout(std::array<vk::DescriptorSetLayoutBinding, 3>{
vk::DescriptorSetLayoutBinding{0,
vk::DescriptorType::eSampledImage,
gsl::narrow<std::uint32_t>(max_shadowmaps),
vk::ShaderStageFlagBits::eFragment},
vk::DescriptorSetLayoutBinding{
1, vk::DescriptorType::eSampler, 1, vk::ShaderStageFlagBits::eFragment},
vk::DescriptorSetLayoutBinding{
2, vk::DescriptorType::eSampler, 1, vk::ShaderStageFlagBits::eFragment},
}))
, shadowmaps(desc_pool.create_descriptor(*shadowmaps_layout, 3))
{
}
} // namespace mirrage::renderer
......@@ -264,6 +264,9 @@ namespace mirrage::renderer {
Engine&,
bool& write_first_pp_buffer) -> std::unique_ptr<Render_pass>
{
if(!renderer.settings().bloom)
return {};
auto& src = !write_first_pp_buffer ? renderer.gbuffer().colorA : renderer.gbuffer().colorB;
return std::make_unique<Bloom_pass>(renderer, src);
......
......@@ -39,32 +39,26 @@ namespace mirrage::renderer {
auto create_point_light_mesh(graphic::Device& device, std::uint32_t owner_qfamily)
{
static auto vertices = std::vector<glm::vec3>();
const auto t = (1.0f + std::sqrt(5.0f)) / 2.0f;
glm::vec3 base_vertices[]{{-1, t, 0},
{1, t, 0},
{-1, -t, 0},
{1, -t, 0},
{0, -1, t},
{0, 1, t},
{0, -1, -t},
{0, 1, -t},
{t, 0, -1},
{t, 0, 1},
{-t, 0, -1},
{-t, 0, 1}};
for(auto& v : base_vertices)
v = glm::normalize(v);
auto vertices = std::vector<glm::vec3>{glm::normalize(glm::vec3{-1, t, 0}),
glm::normalize(glm::vec3{1, t, 0}),
glm::normalize(glm::vec3{-1, -t, 0}),
glm::normalize(glm::vec3{1, -t, 0}),
glm::normalize(glm::vec3{0, -1, t}),
glm::normalize(glm::vec3{0, 1, t}),
glm::normalize(glm::vec3{0, -1, -t}),
glm::normalize(glm::vec3{0, 1, -t}),
glm::normalize(glm::vec3{t, 0, -1}),
glm::normalize(glm::vec3{t, 0, 1}),
glm::normalize(glm::vec3{-t, 0, -1}),
glm::normalize(glm::vec3{-t, 0, 1})};
auto indices = std::vector<std::uint32_t>();
auto add_triange = [&](int a, int b, int c) {
vertices.emplace_back(base_vertices[a]);
vertices.emplace_back(base_vertices[b]);
vertices.emplace_back(base_vertices[c]);
indices.emplace_back(a);
indices.emplace_back(b);
indices.emplace_back(c);
};
// 5 faces around point 0
......@@ -95,45 +89,6 @@ namespace mirrage::renderer {
add_triange(8, 6, 7);
add_triange(9, 8, 1);
/*
auto middle = [](const glm::vec3& a, const glm::vec3& b) {
return glm::normalize((a + b) / 2.f);
};
// refine triangles
for(int i = 0; i < 2; i++) {
auto vertex_count = vertices.size();
auto new_vertices = std::vector<glm::vec3>{};
new_vertices.reserve(vertex_count * 4);
auto add_tri = [&](auto& a, auto& b, auto& c) {
new_vertices.push_back(a);
new_vertices.push_back(b);
new_vertices.push_back(c);
};
for(uint32_t j = 0; j < vertex_count; j += 3) {
auto& v1 = vertices[j];
auto& v2 = vertices[j + 1];
auto& v3 = vertices[j + 2];
// split in 4 triangles;
auto a = middle(v1, v2);
auto b = middle(v2, v3);
auto c = middle(v3, v1);
add_tri(v1, a, c);
add_tri(v2, b, a);
add_tri(v3, c, b);
add_tri(a, b, c);
}
vertices = std::move(new_vertices);
}
*/
static auto indices =
util::build_vector(vertices.size(), [](auto i) { return static_cast<std::uint32_t>(i); });
return graphic::Mesh(device, owner_qfamily, vertices, indices);
}
......@@ -186,9 +141,7 @@ namespace mirrage::renderer {
graphic::Pipeline_description& p)
{
p.add_descriptor_set_layout(*_input_attachment_descriptor_set_layout);
if(renderer.gbuffer().shadowmaps_layout) {
p.add_descriptor_set_layout(*renderer.gbuffer().shadowmaps_layout);
}
p.add_descriptor_set_layout(*renderer.gbuffer().shadowmaps_layout);
}
void Deferred_lighting_subpass::configure_subpass(Deferred_renderer& renderer,
......@@ -199,7 +152,9 @@ namespace mirrage::renderer {
graphic::Shader_stage::fragment,
"main",
0,
renderer.settings().shadow_quality)
renderer.settings().shadow_quality,
1,
renderer.gbuffer().shadowmapping_enabled ? 1 : 0)
.shader("vert_shader:light_directional"_aid, graphic::Shader_stage::vertex);
auto& point_light_pipeline =
......@@ -223,11 +178,7 @@ namespace mirrage::renderer {
render_pass.set_stage("light_dir"_strid);
render_pass.bind_descriptor_sets(1, {_input_attachment_descriptor_set.get_ptr(), 1});
if(_gbuffer.shadowmaps) {
auto desc_set = *_gbuffer.shadowmaps;
render_pass.bind_descriptor_sets(2, {&desc_set, 1});
}
render_pass.bind_descriptor_set(2, *_gbuffer.shadowmaps);
Deferred_push_constants dpc{};
......
......@@ -72,10 +72,13 @@ namespace mirrage::renderer {
// directional lights are always treated as visible (for now).
// so just check if its "on"
if(light.color().length() * light.intensity() > 0.000001f) {
auto viewer_mask = light.shadowcaster() ? (std::uint32_t(1) << viewers.size()) : 0;
auto viewer_mask = _renderer.gbuffer().shadowmapping_enabled && light.shadowcaster()
? (std::uint32_t(1) << viewers.size())
: 0;
frame.light_queue.emplace_back(entity, transform, light, viewer_mask);
if(light.shadowcaster() && light.needs_update()) {
if(_renderer.gbuffer().shadowmapping_enabled && light.shadowcaster()
&& light.needs_update()) {
viewers.emplace_back(extract_planes(light.calc_shadowmap_view_proj(transform)), true);
}
}
......
......@@ -189,6 +189,9 @@ namespace mirrage::renderer {
Engine&,
bool&) -> std::unique_ptr<Render_pass>
{
if(!renderer.settings().gi)
return {};
return std::make_unique<Gen_mipmap_pass>(renderer);
}
......
......@@ -1324,6 +1324,9 @@ namespace mirrage::renderer {
Engine&,
bool& write_first_pp_buffer) -> std::unique_ptr<Render_pass>
{
if(!renderer.settings().gi)
return {};
auto& in_out = !write_first_pp_buffer ? renderer.gbuffer().colorA : renderer.gbuffer().colorB;
auto& in_diff = !write_first_pp_buffer ? renderer.gbuffer().colorB : renderer.gbuffer().colorA;
......
......@@ -213,30 +213,19 @@ namespace mirrage::renderer {
vk::Filter::eLinear,
vk::SamplerMipmapMode::eNearest,
false))
, _shadowmaps(util::make_vector(
Shadowmap(renderer.device(), renderer.settings().shadowmap_resolution, _shadowmap_format),
Shadowmap(renderer.device(), renderer.settings().shadowmap_resolution, _shadowmap_format)))
, _shadowmaps(util::build_vector(renderer.gbuffer().max_shadowmaps,
[&](auto) {
return Shadowmap(renderer.device(),
renderer.settings().shadowmap_resolution,
_shadowmap_format);
}))
, _render_pass(build_render_pass(
renderer, _depth, get_depth_format(renderer.device()), _shadowmap_format, _shadowmaps))
{
entities.register_component_type<Directional_light_comp>();
entities.register_component_type<Shadowcaster_comp>();
auto shadowmap_bindings = std::array<vk::DescriptorSetLayoutBinding, 3>();
shadowmap_bindings[0] = vk::DescriptorSetLayoutBinding{0,
vk::DescriptorType::eSampledImage,
gsl::narrow<std::uint32_t>(_shadowmaps.size()),
vk::ShaderStageFlagBits::eFragment};
shadowmap_bindings[1] = vk::DescriptorSetLayoutBinding{
1, vk::DescriptorType::eSampler, 1, vk::ShaderStageFlagBits::eFragment};
shadowmap_bindings[2] = vk::DescriptorSetLayoutBinding{
2, vk::DescriptorType::eSampler, 1, vk::ShaderStageFlagBits::eFragment};
MIRRAGE_INVARIANT(!renderer.gbuffer().shadowmaps_layout,
"More than one shadowmapping implementation active!");
renderer.gbuffer().shadowmaps_layout =
renderer.device().create_descriptor_set_layout(shadowmap_bindings);
renderer.gbuffer().shadowmaps = renderer.create_descriptor_set(*renderer.gbuffer().shadowmaps_layout,
shadowmap_bindings.size());
renderer.gbuffer().shadowmapping_enabled = true;
auto shadowmap_infos = std::vector<vk::DescriptorImageInfo>();
......@@ -377,7 +366,10 @@ namespace mirrage::renderer {
Engine&,
bool&) -> std::unique_ptr<Render_pass>
{
return std::make_unique<Shadowmapping_pass>(renderer, entities);
if(renderer.settings().shadows)
return std::make_unique<Shadowmapping_pass>(renderer, entities);
else
return {};
}
auto Shadowmapping_pass_factory::rank_device(vk::PhysicalDevice,
......
......@@ -242,6 +242,9 @@ namespace mirrage::renderer {
auto Ssao_pass_factory::create_pass(Deferred_renderer& renderer, ecs::Entity_manager&, Engine&, bool&)
-> std::unique_ptr<Render_pass>
{
if(!renderer.settings().ssao)
return {};
return std::make_unique<Ssao_pass>(renderer);
}
......
......@@ -221,6 +221,9 @@ namespace mirrage::renderer {
Engine&,
bool& write_first_pp_buffer) -> std::unique_ptr<Render_pass>
{
if(!renderer.settings().taa)
return {};
auto& write = write_first_pp_buffer ? renderer.gbuffer().colorA : renderer.gbuffer().colorB;
auto& read = !write_first_pp_buffer ? renderer.gbuffer().colorA : renderer.gbuffer().colorB;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment