mirror of
https://github.com/Redot-Engine/redot-engine.git
synced 2025-12-06 15:21:56 -05:00
Add option to enable HDR rendering in 2D
This is needed to allow 2D to fully make use of 3D effects (e.g. glow), and can be used to substantially improve quality of 2D rendering at the cost of performance Additionally, the 2D rendering pipeline is done in linear space (we skip linear_to_srgb conversion in 3D tonemapping) so the entire Viewport can be kept linear. This is necessary for proper HDR screen support in the future.
This commit is contained in:
@@ -363,7 +363,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI
|
||||
bool use_normal;
|
||||
bool use_specular;
|
||||
|
||||
bool success = RendererRD::TextureStorage::get_singleton()->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular);
|
||||
bool success = RendererRD::TextureStorage::get_singleton()->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, bool(push_constant.flags & FLAGS_CONVERT_ATTRIBUTES_TO_LINEAR), uniform_set, size, specular_shininess, use_normal, use_specular);
|
||||
//something odd happened
|
||||
if (!success) {
|
||||
_bind_canvas_texture(p_draw_list, default_canvas_texture, p_base_filter, p_base_repeat, r_last_texture, push_constant, r_texpixel_size);
|
||||
@@ -421,6 +421,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
_update_transform_2d_to_mat2x3(base_transform, push_constant.world);
|
||||
|
||||
Color base_color = p_item->final_modulate;
|
||||
bool use_linear_colors = texture_storage->render_target_is_using_hdr(p_render_target);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
push_constant.modulation[i] = 0;
|
||||
@@ -441,6 +442,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
push_constant.lights[3] = 0;
|
||||
|
||||
uint32_t base_flags = 0;
|
||||
base_flags |= use_linear_colors ? FLAGS_CONVERT_ATTRIBUTES_TO_LINEAR : 0;
|
||||
|
||||
uint16_t light_count = 0;
|
||||
PipelineLightMode light_mode;
|
||||
@@ -566,10 +568,15 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
push_constant.flags |= FLAGS_USE_LCD;
|
||||
}
|
||||
|
||||
push_constant.modulation[0] = rect->modulate.r * base_color.r;
|
||||
push_constant.modulation[1] = rect->modulate.g * base_color.g;
|
||||
push_constant.modulation[2] = rect->modulate.b * base_color.b;
|
||||
push_constant.modulation[3] = rect->modulate.a * base_color.a;
|
||||
Color modulated = rect->modulate * base_color;
|
||||
if (use_linear_colors) {
|
||||
modulated = modulated.srgb_to_linear();
|
||||
}
|
||||
|
||||
push_constant.modulation[0] = modulated.r;
|
||||
push_constant.modulation[1] = modulated.g;
|
||||
push_constant.modulation[2] = modulated.b;
|
||||
push_constant.modulation[3] = modulated.a;
|
||||
|
||||
push_constant.src_rect[0] = src_rect.position.x;
|
||||
push_constant.src_rect[1] = src_rect.position.y;
|
||||
@@ -618,10 +625,15 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
}
|
||||
}
|
||||
|
||||
push_constant.modulation[0] = np->color.r * base_color.r;
|
||||
push_constant.modulation[1] = np->color.g * base_color.g;
|
||||
push_constant.modulation[2] = np->color.b * base_color.b;
|
||||
push_constant.modulation[3] = np->color.a * base_color.a;
|
||||
Color modulated = np->color * base_color;
|
||||
if (use_linear_colors) {
|
||||
modulated = modulated.srgb_to_linear();
|
||||
}
|
||||
|
||||
push_constant.modulation[0] = modulated.r;
|
||||
push_constant.modulation[1] = modulated.g;
|
||||
push_constant.modulation[2] = modulated.b;
|
||||
push_constant.modulation[3] = modulated.a;
|
||||
|
||||
push_constant.src_rect[0] = src_rect.position.x;
|
||||
push_constant.src_rect[1] = src_rect.position.y;
|
||||
@@ -676,10 +688,15 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
|
||||
_bind_canvas_texture(p_draw_list, polygon->texture, current_filter, current_repeat, last_texture, push_constant, texpixel_size);
|
||||
|
||||
push_constant.modulation[0] = base_color.r;
|
||||
push_constant.modulation[1] = base_color.g;
|
||||
push_constant.modulation[2] = base_color.b;
|
||||
push_constant.modulation[3] = base_color.a;
|
||||
Color color = base_color;
|
||||
if (use_linear_colors) {
|
||||
color = color.srgb_to_linear();
|
||||
}
|
||||
|
||||
push_constant.modulation[0] = color.r;
|
||||
push_constant.modulation[1] = color.g;
|
||||
push_constant.modulation[2] = color.b;
|
||||
push_constant.modulation[3] = color.a;
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
push_constant.src_rect[j] = 0;
|
||||
@@ -718,6 +735,9 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
push_constant.uvs[j * 2 + 0] = primitive->uvs[j].x;
|
||||
push_constant.uvs[j * 2 + 1] = primitive->uvs[j].y;
|
||||
Color col = primitive->colors[j] * base_color;
|
||||
if (use_linear_colors) {
|
||||
col = col.srgb_to_linear();
|
||||
}
|
||||
push_constant.colors[j * 2 + 0] = (uint32_t(Math::make_half_float(col.g)) << 16) | Math::make_half_float(col.r);
|
||||
push_constant.colors[j * 2 + 1] = (uint32_t(Math::make_half_float(col.a)) << 16) | Math::make_half_float(col.b);
|
||||
}
|
||||
@@ -732,6 +752,9 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
push_constant.uvs[j * 2 + 0] = primitive->uvs[j + 1].x;
|
||||
push_constant.uvs[j * 2 + 1] = primitive->uvs[j + 1].y;
|
||||
Color col = primitive->colors[j + 1] * base_color;
|
||||
if (use_linear_colors) {
|
||||
col = col.srgb_to_linear();
|
||||
}
|
||||
push_constant.colors[j * 2 + 0] = (uint32_t(Math::make_half_float(col.g)) << 16) | Math::make_half_float(col.r);
|
||||
push_constant.colors[j * 2 + 1] = (uint32_t(Math::make_half_float(col.a)) << 16) | Math::make_half_float(col.b);
|
||||
}
|
||||
@@ -849,10 +872,15 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
uint32_t surf_count = mesh_storage->mesh_get_surface_count(mesh);
|
||||
static const PipelineVariant variant[RS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_LINES_STRIP, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLE_STRIP };
|
||||
|
||||
push_constant.modulation[0] = base_color.r * modulate.r;
|
||||
push_constant.modulation[1] = base_color.g * modulate.g;
|
||||
push_constant.modulation[2] = base_color.b * modulate.b;
|
||||
push_constant.modulation[3] = base_color.a * modulate.a;
|
||||
Color modulated = modulate * base_color;
|
||||
if (use_linear_colors) {
|
||||
modulated = modulated.srgb_to_linear();
|
||||
}
|
||||
|
||||
push_constant.modulation[0] = modulated.r;
|
||||
push_constant.modulation[1] = modulated.g;
|
||||
push_constant.modulation[2] = modulated.b;
|
||||
push_constant.modulation[3] = modulated.a;
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
push_constant.src_rect[j] = 0;
|
||||
@@ -1113,8 +1141,9 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
|
||||
if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) {
|
||||
pipeline_variants = &material_data->shader_data->pipeline_variants;
|
||||
// Update uniform set.
|
||||
if (material_data->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material_data->uniform_set)) { // Material may not have a uniform set.
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_data->uniform_set, MATERIAL_UNIFORM_SET);
|
||||
RID uniform_set = texture_storage->render_target_is_using_hdr(p_to_render_target) ? material_data->uniform_set : material_data->uniform_set_srgb;
|
||||
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) { // Material may not have a uniform set.
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set, MATERIAL_UNIFORM_SET);
|
||||
material_data->set_as_used();
|
||||
}
|
||||
} else {
|
||||
@@ -2235,12 +2264,14 @@ RendererRD::MaterialStorage::ShaderData *RendererCanvasRenderRD::_create_shader_
|
||||
|
||||
bool RendererCanvasRenderRD::CanvasMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
|
||||
RendererCanvasRenderRD *canvas_singleton = static_cast<RendererCanvasRenderRD *>(RendererCanvasRender::singleton);
|
||||
|
||||
return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET, false);
|
||||
bool uniform_set_changed = update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET, true, false, RD::BARRIER_MASK_ALL_BARRIERS);
|
||||
bool uniform_set_srgb_changed = update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set_srgb, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET, false, false, RD::BARRIER_MASK_ALL_BARRIERS);
|
||||
return uniform_set_changed || uniform_set_srgb_changed;
|
||||
}
|
||||
|
||||
RendererCanvasRenderRD::CanvasMaterialData::~CanvasMaterialData() {
|
||||
free_parameters_uniform_set(uniform_set);
|
||||
free_parameters_uniform_set(uniform_set_srgb);
|
||||
}
|
||||
|
||||
RendererRD::MaterialStorage::MaterialData *RendererCanvasRenderRD::_create_material_func(CanvasShaderData *p_shader) {
|
||||
|
||||
Reference in New Issue
Block a user