Path: blob/master/servers/rendering/renderer_rd/effects/tone_mapper.cpp
10279 views
/**************************************************************************/1/* tone_mapper.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "tone_mapper.h"31#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"32#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"33#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"3435using namespace RendererRD;3637ToneMapper::ToneMapper() {38{39// Initialize tonemapper40Vector<String> tonemap_modes;41tonemap_modes.push_back("\n");42tonemap_modes.push_back("\n#define USE_GLOW_FILTER_BICUBIC\n");43tonemap_modes.push_back("\n#define USE_1D_LUT\n");44tonemap_modes.push_back("\n#define USE_GLOW_FILTER_BICUBIC\n#define USE_1D_LUT\n");45tonemap_modes.push_back("\n#define SUBPASS\n");46tonemap_modes.push_back("\n#define SUBPASS\n#define USE_1D_LUT\n");4748// multiview versions of our shaders49tonemap_modes.push_back("\n#define USE_MULTIVIEW\n");50tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define USE_GLOW_FILTER_BICUBIC\n");51tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define USE_1D_LUT\n");52tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define USE_GLOW_FILTER_BICUBIC\n#define USE_1D_LUT\n");53tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define SUBPASS\n");54tonemap_modes.push_back("\n#define USE_MULTIVIEW\n#define SUBPASS\n#define USE_1D_LUT\n");5556tonemap.shader.initialize(tonemap_modes);5758if (!RendererCompositorRD::get_singleton()->is_xr_enabled()) {59tonemap.shader.set_variant_enabled(TONEMAP_MODE_NORMAL_MULTIVIEW, false);60tonemap.shader.set_variant_enabled(TONEMAP_MODE_BICUBIC_GLOW_FILTER_MULTIVIEW, false);61tonemap.shader.set_variant_enabled(TONEMAP_MODE_1D_LUT_MULTIVIEW, false);62tonemap.shader.set_variant_enabled(TONEMAP_MODE_BICUBIC_GLOW_FILTER_1D_LUT_MULTIVIEW, false);63tonemap.shader.set_variant_enabled(TONEMAP_MODE_SUBPASS_MULTIVIEW, false);64tonemap.shader.set_variant_enabled(TONEMAP_MODE_SUBPASS_1D_LUT_MULTIVIEW, false);65}6667tonemap.shader_version = tonemap.shader.version_create();6869for (int i = 0; i < TONEMAP_MODE_MAX; i++) {70if (tonemap.shader.is_variant_enabled(i)) {71tonemap.pipelines[i].setup(tonemap.shader.version_get_shader(tonemap.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);72} else {73tonemap.pipelines[i].clear();74}75}76}77}7879ToneMapper::~ToneMapper() {80tonemap.shader.version_free(tonemap.shader_version);81}8283void ToneMapper::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {84UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();85ERR_FAIL_NULL(uniform_set_cache);86MaterialStorage *material_storage = MaterialStorage::get_singleton();87ERR_FAIL_NULL(material_storage);8889memset(&tonemap.push_constant, 0, sizeof(TonemapPushConstant));9091tonemap.push_constant.flags |= p_settings.use_bcs ? TONEMAP_FLAG_USE_BCS : 0;92tonemap.push_constant.bcs[0] = p_settings.brightness;93tonemap.push_constant.bcs[1] = p_settings.contrast;94tonemap.push_constant.bcs[2] = p_settings.saturation;9596tonemap.push_constant.flags |= p_settings.use_glow ? TONEMAP_FLAG_USE_GLOW : 0;97tonemap.push_constant.glow_intensity = p_settings.glow_intensity;98tonemap.push_constant.glow_map_strength = p_settings.glow_map_strength;99tonemap.push_constant.glow_levels[0] = p_settings.glow_levels[0]; // clean this up to just pass by pointer or something100tonemap.push_constant.glow_levels[1] = p_settings.glow_levels[1];101tonemap.push_constant.glow_levels[2] = p_settings.glow_levels[2];102tonemap.push_constant.glow_levels[3] = p_settings.glow_levels[3];103tonemap.push_constant.glow_levels[4] = p_settings.glow_levels[4];104tonemap.push_constant.glow_levels[5] = p_settings.glow_levels[5];105tonemap.push_constant.glow_levels[6] = p_settings.glow_levels[6];106tonemap.push_constant.glow_texture_size[0] = p_settings.glow_texture_size.x;107tonemap.push_constant.glow_texture_size[1] = p_settings.glow_texture_size.y;108tonemap.push_constant.glow_mode = p_settings.glow_mode;109110int mode = p_settings.glow_use_bicubic_upscale ? TONEMAP_MODE_BICUBIC_GLOW_FILTER : TONEMAP_MODE_NORMAL;111if (p_settings.use_1d_color_correction) {112mode += 2;113}114115tonemap.push_constant.tonemapper = p_settings.tonemap_mode;116tonemap.push_constant.flags |= p_settings.use_auto_exposure ? TONEMAP_FLAG_USE_AUTO_EXPOSURE : 0;117tonemap.push_constant.exposure = p_settings.exposure;118tonemap.push_constant.white = p_settings.white;119tonemap.push_constant.auto_exposure_scale = p_settings.auto_exposure_scale;120tonemap.push_constant.luminance_multiplier = p_settings.luminance_multiplier;121122tonemap.push_constant.flags |= p_settings.use_color_correction ? TONEMAP_FLAG_USE_COLOR_CORRECTION : 0;123124tonemap.push_constant.flags |= p_settings.use_fxaa ? TONEMAP_FLAG_USE_FXAA : 0;125if (p_settings.debanding_mode == TonemapSettings::DEBANDING_MODE_8_BIT) {126tonemap.push_constant.flags |= TONEMAP_FLAG_USE_8_BIT_DEBANDING;127} else if (p_settings.debanding_mode == TonemapSettings::DEBANDING_MODE_10_BIT) {128tonemap.push_constant.flags |= TONEMAP_FLAG_USE_10_BIT_DEBANDING;129}130tonemap.push_constant.pixel_size[0] = 1.0 / p_settings.texture_size.x;131tonemap.push_constant.pixel_size[1] = 1.0 / p_settings.texture_size.y;132133tonemap.push_constant.flags |= p_settings.convert_to_srgb ? TONEMAP_FLAG_CONVERT_TO_SRGB : 0;134135if (p_settings.view_count > 1) {136// Use USE_MULTIVIEW versions137mode += 6;138}139140RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);141RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);142143RD::Uniform u_source_color(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_color }));144145RD::Uniform u_exposure_texture;146u_exposure_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;147u_exposure_texture.binding = 0;148u_exposure_texture.append_id(default_sampler);149u_exposure_texture.append_id(p_settings.exposure_texture);150151RD::Uniform u_glow_texture;152u_glow_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;153u_glow_texture.binding = 0;154u_glow_texture.append_id(default_mipmap_sampler);155u_glow_texture.append_id(p_settings.glow_texture);156157RD::Uniform u_glow_map;158u_glow_map.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;159u_glow_map.binding = 1;160u_glow_map.append_id(default_mipmap_sampler);161u_glow_map.append_id(p_settings.glow_map);162163RD::Uniform u_color_correction_texture;164u_color_correction_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;165u_color_correction_texture.binding = 0;166u_color_correction_texture.append_id(default_sampler);167u_color_correction_texture.append_id(p_settings.color_correction_texture);168169RID shader = tonemap.shader.version_get_shader(tonemap.shader_version, mode);170ERR_FAIL_COND(shader.is_null());171172RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer);173RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer), false, RD::get_singleton()->draw_list_get_current_pass()));174RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_color), 0);175RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_exposure_texture), 1);176RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 2, u_glow_texture, u_glow_map), 2);177RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 3, u_color_correction_texture), 3);178179RD::get_singleton()->draw_list_set_push_constant(draw_list, &tonemap.push_constant, sizeof(TonemapPushConstant));180RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);181RD::get_singleton()->draw_list_end();182}183184void ToneMapper::tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_color, RD::FramebufferFormatID p_dst_format_id, const TonemapSettings &p_settings) {185UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();186ERR_FAIL_NULL(uniform_set_cache);187MaterialStorage *material_storage = MaterialStorage::get_singleton();188ERR_FAIL_NULL(material_storage);189190memset(&tonemap.push_constant, 0, sizeof(TonemapPushConstant));191192tonemap.push_constant.flags |= p_settings.use_bcs ? TONEMAP_FLAG_USE_BCS : 0;193tonemap.push_constant.bcs[0] = p_settings.brightness;194tonemap.push_constant.bcs[1] = p_settings.contrast;195tonemap.push_constant.bcs[2] = p_settings.saturation;196197ERR_FAIL_COND_MSG(p_settings.use_glow, "Glow is not supported when using subpasses.");198tonemap.push_constant.flags |= p_settings.use_glow ? TONEMAP_FLAG_USE_GLOW : 0;199200int mode = p_settings.use_1d_color_correction ? TONEMAP_MODE_SUBPASS_1D_LUT : TONEMAP_MODE_SUBPASS;201if (p_settings.view_count > 1) {202// Use USE_MULTIVIEW versions203mode += 6;204}205206tonemap.push_constant.tonemapper = p_settings.tonemap_mode;207tonemap.push_constant.flags |= p_settings.use_auto_exposure ? TONEMAP_FLAG_USE_AUTO_EXPOSURE : 0;208tonemap.push_constant.exposure = p_settings.exposure;209tonemap.push_constant.white = p_settings.white;210tonemap.push_constant.auto_exposure_scale = p_settings.auto_exposure_scale;211212tonemap.push_constant.flags |= p_settings.use_color_correction ? TONEMAP_FLAG_USE_COLOR_CORRECTION : 0;213if (p_settings.debanding_mode == TonemapSettings::DEBANDING_MODE_8_BIT) {214tonemap.push_constant.flags |= TONEMAP_FLAG_USE_8_BIT_DEBANDING;215} else if (p_settings.debanding_mode == TonemapSettings::DEBANDING_MODE_10_BIT) {216tonemap.push_constant.flags |= TONEMAP_FLAG_USE_10_BIT_DEBANDING;217}218tonemap.push_constant.luminance_multiplier = p_settings.luminance_multiplier;219220tonemap.push_constant.flags |= p_settings.convert_to_srgb ? TONEMAP_FLAG_CONVERT_TO_SRGB : 0;221222RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);223RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);224225RD::Uniform u_source_color;226u_source_color.uniform_type = RD::UNIFORM_TYPE_INPUT_ATTACHMENT;227u_source_color.binding = 0;228u_source_color.append_id(p_source_color);229230RD::Uniform u_exposure_texture;231u_exposure_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;232u_exposure_texture.binding = 0;233u_exposure_texture.append_id(default_sampler);234u_exposure_texture.append_id(p_settings.exposure_texture);235236RD::Uniform u_glow_texture;237u_glow_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;238u_glow_texture.binding = 0;239u_glow_texture.append_id(default_mipmap_sampler);240u_glow_texture.append_id(p_settings.glow_texture);241242RD::Uniform u_glow_map;243u_glow_map.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;244u_glow_map.binding = 1;245u_glow_map.append_id(default_mipmap_sampler);246u_glow_map.append_id(p_settings.glow_map);247248RD::Uniform u_color_correction_texture;249u_color_correction_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;250u_color_correction_texture.binding = 0;251u_color_correction_texture.append_id(default_sampler);252u_color_correction_texture.append_id(p_settings.color_correction_texture);253254RID shader = tonemap.shader.version_get_shader(tonemap.shader_version, mode);255ERR_FAIL_COND(shader.is_null());256257RD::get_singleton()->draw_list_bind_render_pipeline(p_subpass_draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, p_dst_format_id, false, RD::get_singleton()->draw_list_get_current_pass()));258RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 0, u_source_color), 0);259RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 1, u_exposure_texture), 1); // should be set to a default texture, it's ignored260RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 2, u_glow_texture, u_glow_map), 2); // should be set to a default texture, it's ignored261RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 3, u_color_correction_texture), 3);262263RD::get_singleton()->draw_list_set_push_constant(p_subpass_draw_list, &tonemap.push_constant, sizeof(TonemapPushConstant));264RD::get_singleton()->draw_list_draw(p_subpass_draw_list, false, 1u, 3u);265}266267268