Skip to content

Commit

Permalink
Fix source_color for 2D shader parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
huwpascoe committed Feb 14, 2025
1 parent 23c1389 commit 51a13dc
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 47 deletions.
2 changes: 1 addition & 1 deletion drivers/gles3/storage/material_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2025,7 +2025,7 @@ void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) {
global_shader_uniforms.instance_buffer_pos.erase(p_instance);
}

void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count) {
void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count, bool p_use_linear_color) {
if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) {
return; //just not allocated, ignore
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gles3/storage/material_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ class MaterialStorage : public RendererMaterialStorage {

virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override;
virtual void global_shader_parameters_instance_free(RID p_instance) override;
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override;
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0, bool p_use_linear_color = true) override;

GLuint global_shader_parameters_get_uniform_buffer() const;

Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/dummy/storage/material_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class MaterialStorage : public RendererMaterialStorage {

virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override { return 0; }
virtual void global_shader_parameters_instance_free(RID p_instance) override {}
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override {}
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0, bool p_use_linear_color = true) override {}

/* SHADER API */

Expand Down
7 changes: 4 additions & 3 deletions servers/rendering/instance_uniforms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ void InstanceUniforms::free(RID p_self) {
_invalidate_items();
}

void InstanceUniforms::materials_start() {
void InstanceUniforms::materials_start(bool p_use_linear_color) {
_use_linear_color = p_use_linear_color;
_invalidate_items();
}

Expand Down Expand Up @@ -93,7 +94,7 @@ bool InstanceUniforms::materials_finish(RID p_self) {
for (KeyValue<StringName, Item> &kv : _parameters) {
Item &i = kv.value;
if (i.is_valid()) {
RSG::material_storage->global_shader_parameters_instance_update(p_self, i.index, i.value, i.flags);
RSG::material_storage->global_shader_parameters_instance_update(p_self, i.index, i.value, i.flags, _use_linear_color);
}
}

Expand All @@ -114,7 +115,7 @@ void InstanceUniforms::set(RID p_self, const StringName &p_name, const Variant &
if (Item *ptr = _parameters.getptr(p_name); ptr) {
ptr->value = p_value;
if (ptr->is_valid()) {
RSG::material_storage->global_shader_parameters_instance_update(p_self, ptr->index, ptr->value, ptr->flags);
RSG::material_storage->global_shader_parameters_instance_update(p_self, ptr->index, ptr->value, ptr->flags, _use_linear_color);
}
} else {
Item i; // Initialize in materials_finish.
Expand Down
3 changes: 2 additions & 1 deletion servers/rendering/instance_uniforms.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class InstanceUniforms {
public:
void free(RID p_self);

void materials_start();
void materials_start(bool p_use_linear_color);
void materials_append(RID p_material);

// Assign location() to instance offset if materials_finish returns true.
Expand All @@ -65,6 +65,7 @@ class InstanceUniforms {
};
int32_t _location = -1;
HashMap<StringName, Item> _parameters;
bool _use_linear_color = {};

void _init_param(Item &r_item, const RendererMaterialStorage::InstanceShaderParam &p_param) const;
void _invalidate_items();
Expand Down
23 changes: 22 additions & 1 deletion servers/rendering/renderer_canvas_cull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,10 +593,12 @@ void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) {
ci.item = canvas_item;
canvas->child_items.push_back(ci);
canvas->children_order_dirty = true;
canvas_item->use_linear_color = canvas->use_linear_color;
} else if (canvas_item_owner.owns(p_parent)) {
Item *item_owner = canvas_item_owner.get_or_null(p_parent);
item_owner->child_items.push_back(canvas_item);
item_owner->children_order_dirty = true;
canvas_item->use_linear_color = item_owner->use_linear_color;

if (item_owner->sort_y) {
_mark_ysort_dirty(item_owner);
Expand Down Expand Up @@ -2526,7 +2528,7 @@ void RendererCanvasCull::_update_dirty_item(Item *p_item) {

p_item->dependency_tracker.update_begin();

p_item->instance_uniforms.materials_start();
p_item->instance_uniforms.materials_start(p_item->use_linear_color);

if (material.is_valid()) {
p_item->instance_uniforms.materials_append(material);
Expand All @@ -2543,6 +2545,25 @@ void RendererCanvasCull::_update_dirty_item(Item *p_item) {
p_item->update_dependencies = false;
}

void RendererCanvasCull::Canvas::set_use_linear_color(bool p_use_linear_color) {
use_linear_color = p_use_linear_color;

for (ChildItem &child_item : child_items) {
_set_item_use_linear_color(child_item.item, use_linear_color);
}

RSG::canvas->update_dirty_items();
}

void RendererCanvasCull::Canvas::_set_item_use_linear_color(Item *item, bool p_use_linear_color) {
item->use_linear_color = p_use_linear_color;
RSG::canvas->_item_queue_update(item, true);

for (Item *child : item->child_items) {
_set_item_use_linear_color(child, p_use_linear_color);
}
}

void RendererCanvasCull::update() {
update_dirty_items();
}
Expand Down
53 changes: 19 additions & 34 deletions servers/rendering/renderer_canvas_cull.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,21 @@ class RendererCanvasCull {
struct Item : public RendererCanvasRender::Item {
RID parent; // canvas it belongs to
RID self;
List<Item *>::Element *E;
int z_index;
bool z_relative;
bool sort_y;
Color modulate;
Color self_modulate;
bool use_parent_material;
int index;
bool children_order_dirty;
int ysort_children_count;
List<Item *>::Element *E = nullptr;
int z_index = 0;
bool z_relative = true;
bool sort_y = false;
bool use_parent_material = false;
bool use_linear_color = false;
bool children_order_dirty = true;
Color modulate = Color(1, 1, 1, 1);
Color self_modulate = Color(1, 1, 1, 1);
int index = 0;
int ysort_children_count = -1;
Color ysort_modulate;
Transform2D ysort_xform; // Relative to y-sorted subtree's root item (identity for such root). Its `origin.y` is used for sorting.
int ysort_index;
int ysort_parent_abs_z_index; // Absolute Z index of parent. Only populated and used when y-sorting.
int ysort_index = 0;
int ysort_parent_abs_z_index = 0; // Absolute Z index of parent. Only populated and used when y-sorting.
uint32_t visibility_layer = 0xffffffff;

Vector<Item *> child_items;
Expand All @@ -84,20 +85,6 @@ class RendererCanvasCull {

Item() :
update_item(this) {
children_order_dirty = true;
E = nullptr;
z_index = 0;
modulate = Color(1, 1, 1, 1);
self_modulate = Color(1, 1, 1, 1);
sort_y = false;
use_parent_material = false;
z_relative = true;
index = 0;
ysort_children_count = -1;
ysort_xform = Transform2D();
ysort_index = 0;
ysort_parent_abs_z_index = 0;

dependency_tracker.userdata = this;
dependency_tracker.changed_callback = &RendererCanvasCull::_dependency_changed;
dependency_tracker.deleted_callback = &RendererCanvasCull::_dependency_deleted;
Expand Down Expand Up @@ -156,11 +143,12 @@ class RendererCanvasCull {

HashSet<RendererCanvasRender::LightOccluderInstance *> occluders;

bool children_order_dirty;
bool children_order_dirty = true;
bool use_linear_color = false;
Vector<ChildItem> child_items;
Color modulate;
Color modulate = Color(1, 1, 1, 1);
RID parent;
float parent_scale;
float parent_scale = 1.0;

int find_item(Item *p_item) {
for (int i = 0; i < child_items.size(); i++) {
Expand All @@ -177,11 +165,8 @@ class RendererCanvasCull {
}
}

Canvas() {
modulate = Color(1, 1, 1, 1);
children_order_dirty = true;
parent_scale = 1.0;
}
void set_use_linear_color(bool p_use_linear_color);
void _set_item_use_linear_color(Item *item, bool p_use_linear_color);
};

mutable RID_Owner<Canvas, true> canvas_owner;
Expand Down
4 changes: 2 additions & 2 deletions servers/rendering/renderer_rd/storage_rd/material_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1805,7 +1805,7 @@ void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) {
global_shader_uniforms.instance_buffer_pos.erase(p_instance);
}

void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count) {
void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count, bool p_use_linear_color) {
if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) {
return; //just not allocated, ignore
}
Expand Down Expand Up @@ -1863,7 +1863,7 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i

pos += p_index;

_fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_shader_uniforms.buffer_values[pos], true); //instances always use linear color in this renderer
_fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_shader_uniforms.buffer_values[pos], p_use_linear_color);
_global_shader_uniform_mark_buffer_dirty(pos, 1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ class MaterialStorage : public RendererMaterialStorage {

virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override;
virtual void global_shader_parameters_instance_free(RID p_instance) override;
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override;
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0, bool p_use_linear_color = true) override;

RID global_shader_uniforms_get_storage_buffer() const;

Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/renderer_scene_cull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4047,7 +4047,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) const {
bool can_cast_shadows = true;
bool is_animated = false;

p_instance->instance_uniforms.materials_start();
p_instance->instance_uniforms.materials_start(true);

if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
can_cast_shadows = false;
Expand Down
7 changes: 7 additions & 0 deletions servers/rendering/renderer_viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,7 @@ void RendererViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) {
ERR_FAIL_NULL(canvas);

canvas->viewports.insert(p_viewport);
canvas->set_use_linear_color(viewport->use_hdr_2d);
viewport->canvas_map[p_canvas] = Viewport::CanvasData();
viewport->canvas_map[p_canvas].layer = 0;
viewport->canvas_map[p_canvas].sublayer = 0;
Expand Down Expand Up @@ -1339,6 +1340,12 @@ void RendererViewport::viewport_set_use_hdr_2d(RID p_viewport, bool p_use_hdr_2d
}
viewport->use_hdr_2d = p_use_hdr_2d;
RSG::texture_storage->render_target_set_use_hdr(viewport->render_target, p_use_hdr_2d);

for (KeyValue<RID, Viewport::CanvasData> &kv : viewport->canvas_map) {
RendererCanvasCull::Canvas *canvas = RSG::canvas->canvas_owner.get_or_null(kv.key);
ERR_FAIL_NULL(canvas);
canvas->set_use_linear_color(viewport->use_hdr_2d);
}
}

bool RendererViewport::viewport_is_using_hdr_2d(RID p_viewport) const {
Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/storage/material_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class RendererMaterialStorage {

virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) = 0;
virtual void global_shader_parameters_instance_free(RID p_instance) = 0;
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) = 0;
virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0, bool p_use_linear_color = true) = 0;

/* SHADER API */
virtual RID shader_allocate() = 0;
Expand Down

0 comments on commit 51a13dc

Please sign in to comment.