Commit 9e712788 authored by Florian Oetke's avatar Florian Oetke
Browse files

fixed division by 0 in glsl and tweaked color bleeding

parent 68f791f1
......@@ -2,7 +2,7 @@
"Transform":{
},
"Directional_light": {
"source_radius": 1,
"source_radius": 0.8,
"intensity": 60.0,
"temperature": 4500,
"shadow_size": 24,
......
......@@ -46,7 +46,7 @@ vec3 expose(vec3 color, float threshold) {
float avg_luminance = max(exp(texture(avg_log_luminance_sampler, vec2(0.5, 0.5)).r), 0.001);
float key = 1.03f - (2.0f / (2 + log(avg_luminance + 1)/log(10)));
float exposure = clamp(key/avg_luminance, 0.1, 3.0) + 0.5;
float exposure = clamp(key/avg_luminance, 0.1, 5.0) + 0.5;
if(pcs.options.z>0) {
exposure = pcs.options.z;
......
......@@ -24,7 +24,7 @@ vec3 expose(vec3 color, float threshold) {
float avg_luminance = max(exp(texture(avg_log_luminance_sampler, vec2(0.5, 0.5)).r), 0.001);
float key = 1.03f - (2.0f / (2 + log(avg_luminance + 1)/log(10)));
float exposure = clamp(key/avg_luminance, 0.1, 4.0) + 0.5;
float exposure = clamp(key/avg_luminance, 0.1, 6.0) + 0.5;
if(pcs.options.z>0) {
exposure = pcs.options.z;
......
......@@ -17,8 +17,8 @@ vec3 calculate_gi(vec2 uv, vec3 radiance, vec3 specular,
out vec3 diffuse) {
const float PI = 3.14159265359;
radiance /= 1 - luminance_norm(radiance);
specular /= 1 - luminance_norm(specular);
radiance /= max(1, 1 - luminance_norm(radiance));
specular /= max(1, 1 - luminance_norm(specular));
// load / calculate material properties and factors
vec3 albedo = textureLod(albedo_sampler, uv, 0.0).rgb;
......
......@@ -24,7 +24,7 @@ layout (constant_id = 2) const int SAMPLES = 128;
layout (constant_id = 3) const int UPSAMPLE_ONLY = 0;
// nearer samples have a higher weight. Less physically correct but results in more notacable color bleeding
layout (constant_id = 4) const int PRIORITISE_NEAR_SAMPLES = 1;
layout (constant_id = 4) const float PRIORITISE_NEAR_SAMPLES = 0.6;
layout(push_constant) uniform Push_constants {
......@@ -80,6 +80,7 @@ void main() {
out_color.rgb *= ao;
}
out_color.rgb /= (1 + luminance_norm(out_color.rgb));
// calculate the min/max interpolation weights based on the delta time
......@@ -89,7 +90,7 @@ void main() {
out_color *= 1.0 - mix(weight_min, weight_max, history_weight);
}
out_color = max(out_color, vec4(0));
out_color = clamp(out_color, vec4(0), vec4(20));
}
const float PI = 3.14159265359;
......@@ -142,12 +143,13 @@ vec3 gi_sample(int lod, int base_mip) {
float actual_lod = lod - pcs.prev_projection[0][0];
if(PRIORITISE_NEAR_SAMPLES==1)
c = c * pow(2.0, clamp(actual_lod*2, 4, 8));
else
c = c * pow(2.0, actual_lod*2);
float scale_exponent = mix(actual_lod,
pcs.prev_projection[1][0] - pcs.prev_projection[2][0] - 0.8,
PRIORITISE_NEAR_SAMPLES);
c *= pow(2.0, scale_exponent*2);
c *= 128.0 / SAMPLES;
c *= 128.0 / SAMPLES;
return c;
}
......@@ -164,7 +166,7 @@ vec3 calc_illumination_from(int lod, vec2 tex_size, ivec2 src_uv, vec2 shaded_uv
vec3 diff = shaded_point - P;
vec3 dir = normalize(diff);
float r2 = dot(diff, diff);
float r2 = max(dot(diff, diff), 0.01*0.01);
float visibility = 1.0; // TODO: raycast
......@@ -180,7 +182,7 @@ vec3 calc_illumination_from(int lod, vec2 tex_size, ivec2 src_uv, vec2 shaded_uv
float cos_beta = dot(Pn, N);
float z = depth * global_uniforms.proj_planes.y;
float ds = pcs.prev_projection[2][3] * z*z * clamp(cos_alpha / cos_beta, 1.0, 20.0);
float ds = pcs.prev_projection[2][3] * z*z * clamp(cos_alpha / cos_beta, 0.001, 1000.0);
float R2 = REC_PI * NdotL_src * ds;
float area = R2 / (r2 + R2); // point-to-differential area form-factor
......
......@@ -42,4 +42,5 @@ namespace mirrage {
}
void Game_engine::_on_post_frame(util::Time) { _renderer_factory->finish_frame(); }
}
} // namespace mirrage
......@@ -418,9 +418,13 @@ namespace mirrage {
nk_property_int(ctx, "Sample Count", 8, &renderer_settings.gi_samples, 256, 1, 1);
bool_nk_wrapper = renderer_settings.gi_prioritise_near_samples ? 1 : 0;
nk_checkbox_label(ctx, "Prioritise near samples", &bool_nk_wrapper);
renderer_settings.gi_prioritise_near_samples = bool_nk_wrapper == 1;
nk_property_float(ctx,
"Prioritise near samples",
0.f,
&renderer_settings.gi_prioritise_near_samples,
1.f,
0.1,
0.01);
nk_property_int(
ctx, "Low-Quality MIP-Levels", 0, &renderer_settings.gi_low_quality_mip_levels, 8, 1, 1);
......
......@@ -18,7 +18,7 @@ namespace mirrage {
class Entity_manager;
}
class Meta_system;
}
} // namespace mirrage
namespace mirrage::renderer {
......@@ -35,7 +35,7 @@ namespace mirrage::renderer {
int gi_diffuse_mip_level = 1;
int gi_min_mip_level = 0;
int gi_samples = 128;
bool gi_prioritise_near_samples = true;
float gi_prioritise_near_samples = 0.8f;
int gi_low_quality_mip_levels = 0;
float exposure_override = 0.f;
......@@ -72,7 +72,7 @@ namespace mirrage::renderer {
public:
virtual ~Pass() = default;
virtual void update(util::Time dt) = 0;
virtual void update(util::Time dt) = 0;
virtual void draw(vk::CommandBuffer&,
Command_buffer_source&,
vk::DescriptorSet global_uniform_set,
......@@ -238,4 +238,4 @@ namespace mirrage::renderer {
void _write_global_uniform_descriptor_set();
void _update_global_uniforms(vk::CommandBuffer, const Camera_state& camera);
};
}
} // namespace mirrage::renderer
......@@ -28,7 +28,7 @@ namespace mirrage::renderer {
vk::UniqueSampler _sampler;
graphic::Image_descriptor_set_layout _descriptor_set_layout;
vk::Format _luminance_format;
bool _first_frame = true;
int _first_frame = 4;
// calculate scene luminance for tone mapping
graphic::Render_target_2D _luminance_buffer;
......@@ -58,4 +58,4 @@ namespace mirrage::renderer {
util::maybe<std::uint32_t> graphics_queue,
graphic::Device_create_info&) override;
};
}
} // namespace mirrage::renderer
......@@ -32,7 +32,7 @@ namespace mirrage::renderer {
return get_hdr_format(device);
}
}
} // namespace
GBuffer::GBuffer(graphic::Device& device, std::uint32_t width, std::uint32_t height)
: mip_levels(gsl::narrow<std::uint32_t>(std::floor(std::log2(std::min(width, height))) - 2))
......@@ -42,8 +42,7 @@ namespace mirrage::renderer {
mip_levels,
depth_format,
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eSampled
| vk::ImageUsageFlagBits::eInputAttachment
| vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eInputAttachment | vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eTransferDst,
vk::ImageAspectFlagBits::eColor)
, prev_depth(device,
......@@ -61,8 +60,7 @@ namespace mirrage::renderer {
albedo_mat_id_format,
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eSampled
| vk::ImageUsageFlagBits::eInputAttachment
| vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eTransferDst,
| vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eTransferDst,
vk::ImageAspectFlagBits::eColor)
, mat_data_format(device.get_texture_rgba_format().get_or_throw("No rgba-format supported"))
......@@ -71,8 +69,7 @@ namespace mirrage::renderer {
mip_levels,
mat_data_format,
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eSampled
| vk::ImageUsageFlagBits::eInputAttachment
| vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eInputAttachment | vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eTransferDst,
vk::ImageAspectFlagBits::eColor)
......@@ -82,8 +79,7 @@ namespace mirrage::renderer {
mip_levels,
color_format,
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eSampled
| vk::ImageUsageFlagBits::eInputAttachment
| vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eInputAttachment | vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eTransferDst,
vk::ImageAspectFlagBits::eColor)
......@@ -92,8 +88,7 @@ namespace mirrage::renderer {
mip_levels,
color_format,
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eSampled
| vk::ImageUsageFlagBits::eInputAttachment
| vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eInputAttachment | vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eTransferDst,
vk::ImageAspectFlagBits::eColor) {}
}
} // namespace mirrage::renderer
......@@ -192,7 +192,7 @@ namespace mirrage::renderer {
int min_mip_level,
int max_mip_level,
int sample_count,
bool prioritise_near_samples,
float prioritise_near_samples,
Render_target_2D& gi_buffer,
std::vector<Framebuffer>& out_framebuffers) {
......@@ -243,7 +243,7 @@ namespace mirrage::renderer {
2,
sample_count,
4,
prioritise_near_samples ? 1 : 0)
prioritise_near_samples)
.shader("vert_shader:gi_sample"_aid, graphic::Shader_stage::vertex);
pass.stage("upsample"_strid)
......@@ -514,7 +514,7 @@ namespace mirrage::renderer {
return static_cast<int>(std::ceil(glm::log2(diagonal / 40.f)));
}
}
} // namespace
Gi_pass::Gi_pass(Deferred_renderer& renderer,
......@@ -543,8 +543,7 @@ namespace mirrage::renderer {
0,
renderer.gbuffer().color_format,
vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst
| vk::ImageUsageFlagBits::eTransferSrc
| vk::ImageUsageFlagBits::eColorAttachment,
| vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eColorAttachment,
vk::ImageAspectFlagBits::eColor)
, _gi_diffuse_history(renderer.device(),
......@@ -765,8 +764,7 @@ namespace mirrage::renderer {
auto pcs = Gi_constants{};
pcs.reprojection = _prev_view * glm::inverse(_renderer.global_uniforms().view_mat);
INVARIANT(pcs.reprojection[0][3] == 0 && pcs.reprojection[1][3] == 0
&& pcs.reprojection[2][3] == 0
&& pcs.reprojection[3][3] == 1,
&& pcs.reprojection[2][3] == 0 && pcs.reprojection[3][3] == 1,
"m[0][3]!=0 or m[1][3]!=0 or m[2][3]!=0 or m[3][3]!=1");
pcs.reprojection[0][3] = -2.f / _prev_proj[0][0];
......@@ -823,7 +821,7 @@ namespace mirrage::renderer {
return (4.0f * glm::tan(fov_h / 2.f) * glm::tan(fov_v / 2.f) * dp)
/ (screen_width * screen_height);
}
}
} // namespace
void Gi_pass::_generate_gi_samples(vk::CommandBuffer& command_buffer) {
auto begin = _diffuse_mip_level;
auto end = _max_mip_level;
......@@ -831,6 +829,8 @@ namespace mirrage::renderer {
auto pcs = Gi_constants{};
pcs.prev_projection[0][0] = _highres_base_mip_level;
pcs.prev_projection[1][0] = end - 1;
pcs.prev_projection[2][0] = std::min(_min_mip_level, begin);
pcs.prev_projection[1][3] = _max_mip_level - 1;
pcs.prev_projection[3][3] = _min_mip_level;
......@@ -900,7 +900,7 @@ namespace mirrage::renderer {
auto screen_size = glm::vec2{_color_diffuse_in.width(pcs.prev_projection[0][3]),
_color_diffuse_in.height(pcs.prev_projection[0][3])};
auto ndc_to_uv = glm::translate({}, glm::vec3(screen_size / 2.f, 0.f))
auto ndc_to_uv = glm::translate({}, glm::vec3(screen_size / 2.f, 0.f))
* glm::scale({}, glm::vec3(screen_size / 2.f, 1.f));
pcs.reprojection = ndc_to_uv * _renderer.global_uniforms().proj_mat;
......@@ -975,4 +975,4 @@ namespace mirrage::renderer {
void Gi_pass_factory::configure_device(vk::PhysicalDevice,
util::maybe<std::uint32_t>,
graphic::Device_create_info&) {}
}
} // namespace mirrage::renderer
......@@ -144,7 +144,7 @@ namespace mirrage::renderer {
return format.get_or_throw();
}
}
} // namespace
Tone_mapping_pass::Tone_mapping_pass(Deferred_renderer& renderer,
......@@ -214,11 +214,11 @@ namespace mirrage::renderer {
std::size_t) {
auto pcs = Push_constants{};
pcs.parameters.x = 0.08f; // adjustment speed if current luminance > previous
pcs.parameters.y = 0.8f; // adjustment speed if current luminance <= previous
pcs.parameters.x = 0.2f; // adjustment speed if current luminance > previous
pcs.parameters.y = 0.8f; // adjustment speed if current luminance <= previous
if(_first_frame) {
_first_frame = false;
if(_first_frame > 0) {
_first_frame--;
pcs.parameters.x = pcs.parameters.y = 999.f;
......@@ -238,6 +238,7 @@ namespace mirrage::renderer {
vk::ImageLayout::eShaderReadOnlyOptimal,
0,
1);
return;
}
// extract luminance
......@@ -298,4 +299,4 @@ namespace mirrage::renderer {
void Tone_mapping_pass_factory::configure_device(vk::PhysicalDevice,
util::maybe<std::uint32_t>,
graphic::Device_create_info&) {}
}
} // namespace mirrage::renderer
Markdown is supported
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