From 7010ee3cb980fca18248fa168a4dabd78cf51e9d Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 15 Nov 2017 12:39:24 -0300 Subject: [PATCH] -Ability to choose operator for emission, closes #10441 -Ability to use proper operator for GI Probe, closes #10534 -Closes #12938 as it's no longer needed (thanks for the work though) --- scene/3d/gi_probe.cpp | 19 +++++++++++++------ scene/3d/gi_probe.h | 2 +- scene/resources/material.cpp | 27 ++++++++++++++++++++++++++- scene/resources/material.h | 12 ++++++++++++ 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index c0ca358717e..002ce1793b2 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -891,7 +891,7 @@ void GIProbe::_fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, Bak } } -Vector GIProbe::_get_bake_texture(Ref p_image, const Color &p_color) { +Vector GIProbe::_get_bake_texture(Ref p_image, const Color &p_color, bool p_color_add) { Vector ret; @@ -919,9 +919,16 @@ Vector GIProbe::_get_bake_texture(Ref p_image, const Color &p_colo for (int i = 0; i < bake_texture_size * bake_texture_size; i++) { Color c; - c.r = (r[i * 4 + 0] / 255.0) * p_color.r; - c.g = (r[i * 4 + 1] / 255.0) * p_color.g; - c.b = (r[i * 4 + 2] / 255.0) * p_color.b; + if (p_color_add) { + c.r = (r[i * 4 + 0] / 255.0) + p_color.r; + c.g = (r[i * 4 + 1] / 255.0) + p_color.g; + c.b = (r[i * 4 + 2] / 255.0) + p_color.b; + } else { + c.r = (r[i * 4 + 0] / 255.0) * p_color.r; + c.g = (r[i * 4 + 1] / 255.0) * p_color.g; + c.b = (r[i * 4 + 2] / 255.0) * p_color.b; + } + c.a = r[i * 4 + 3] / 255.0; ret[i] = c; @@ -954,7 +961,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref p_mater } else { } - mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo()); + mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo(), false); Ref emission_tex = mat->get_texture(SpatialMaterial::TEXTURE_EMISSION); @@ -970,7 +977,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref p_mater img_emission = emission_tex->get_data(); } - mc.emission = _get_bake_texture(img_emission, emission_col); + mc.emission = _get_bake_texture(img_emission, emission_col, mat->get_emission_operator() == SpatialMaterial::EMISSION_OP_ADD); } else { Ref empty; diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index 50d0c33d4fd..8aca2c549bb 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -178,7 +178,7 @@ private: int color_scan_cell_width; int bake_texture_size; - Vector _get_bake_texture(Ref p_image, const Color &p_color); + Vector _get_bake_texture(Ref p_image, const Color &p_color, bool p_color_add = false); Baker::MaterialCache _get_material_cache(Ref p_material, Baker *p_baker); void _plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector2 *p_uv, const Baker::MaterialCache &p_material, const Rect3 &p_aabb, Baker *p_baker); void _plot_mesh(const Transform &p_xform, Ref &p_mesh, Baker *p_baker, const Vector > &p_materials, const Ref &p_override_material); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 12434b39fa6..286840656b2 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -723,7 +723,11 @@ void SpatialMaterial::_update_shader() { } else { code += "\tvec3 emission_tex = texture(texture_emission,base_uv).rgb;\n"; } - code += "\tEMISSION = (emission.rgb+emission_tex)*emission_energy;\n"; + if (emission_op == EMISSION_OP_ADD) { + code += "\tEMISSION = (emission.rgb+emission_tex)*emission_energy;\n"; + } else { + code += "\tEMISSION = (emission.rgb*emission_tex)*emission_energy;\n"; + } } if (features[FEATURE_REFRACTION] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //refraction not supported with triplanar @@ -1635,6 +1639,19 @@ float SpatialMaterial::get_distance_fade_min_distance() const { return distance_fade_min_distance; } +void SpatialMaterial::set_emission_operator(EmissionOperator p_op) { + + if (emission_op == p_op) + return; + emission_op = p_op; + _queue_shader_change(); +} + +SpatialMaterial::EmissionOperator SpatialMaterial::get_emission_operator() const { + + return emission_op; +} + RID SpatialMaterial::get_shader_rid() const { ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); @@ -1769,6 +1786,9 @@ void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_grow", "amount"), &SpatialMaterial::set_grow); ClassDB::bind_method(D_METHOD("get_grow"), &SpatialMaterial::get_grow); + ClassDB::bind_method(D_METHOD("set_emission_operator", "operator"), &SpatialMaterial::set_emission_operator); + ClassDB::bind_method(D_METHOD("get_emission_operator"), &SpatialMaterial::get_emission_operator); + ClassDB::bind_method(D_METHOD("set_ao_light_affect", "amount"), &SpatialMaterial::set_ao_light_affect); ClassDB::bind_method(D_METHOD("get_ao_light_affect"), &SpatialMaterial::get_ao_light_affect); @@ -1854,6 +1874,7 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_enabled"), "set_feature", "get_feature", FEATURE_EMISSION); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "emission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_emission", "get_emission"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_emission_energy", "get_emission_energy"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_operator", PROPERTY_HINT_ENUM, "Add,Multiply"), "set_emission_operator", "get_emission_operator"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); ADD_GROUP("NormalMap", "normal_"); @@ -2022,6 +2043,9 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(TEXTURE_CHANNEL_BLUE); BIND_ENUM_CONSTANT(TEXTURE_CHANNEL_ALPHA); BIND_ENUM_CONSTANT(TEXTURE_CHANNEL_GRAYSCALE); + + BIND_ENUM_CONSTANT(EMISSION_OP_ADD); + BIND_ENUM_CONSTANT(EMISSION_OP_MULTIPLY); } SpatialMaterial::SpatialMaterial() @@ -2057,6 +2081,7 @@ SpatialMaterial::SpatialMaterial() set_particles_anim_v_frames(1); set_particles_anim_loop(false); set_alpha_scissor_threshold(0.98); + emission_op = EMISSION_OP_ADD; proximity_fade_enabled = false; distance_fade_enabled = false; diff --git a/scene/resources/material.h b/scene/resources/material.h index 2425f1a1747..877d4dfd41b 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -215,6 +215,11 @@ public: TEXTURE_CHANNEL_GRAYSCALE }; + enum EmissionOperator { + EMISSION_OP_ADD, + EMISSION_OP_MULTIPLY + }; + private: union MaterialKey { @@ -234,6 +239,7 @@ private: uint64_t grow : 1; uint64_t proximity_fade : 1; uint64_t distance_fade : 1; + uint64_t emission_op : 1; }; uint64_t key; @@ -278,6 +284,7 @@ private: mk.grow = grow_enabled; mk.proximity_fade = proximity_fade_enabled; mk.distance_fade = distance_fade_enabled; + mk.emission_op = emission_op; return mk; } @@ -394,6 +401,7 @@ private: SpecularMode specular_mode; DiffuseMode diffuse_mode; BillboardMode billboard_mode; + EmissionOperator emission_op; TextureChannel metallic_texture_channel; TextureChannel roughness_texture_channel; @@ -571,6 +579,9 @@ public: void set_distance_fade_min_distance(float p_distance); float get_distance_fade_min_distance() const; + void set_emission_operator(EmissionOperator p_op); + EmissionOperator get_emission_operator() const; + void set_metallic_texture_channel(TextureChannel p_channel); TextureChannel get_metallic_texture_channel() const; void set_roughness_texture_channel(TextureChannel p_channel); @@ -603,6 +614,7 @@ VARIANT_ENUM_CAST(SpatialMaterial::DiffuseMode) VARIANT_ENUM_CAST(SpatialMaterial::SpecularMode) VARIANT_ENUM_CAST(SpatialMaterial::BillboardMode) VARIANT_ENUM_CAST(SpatialMaterial::TextureChannel) +VARIANT_ENUM_CAST(SpatialMaterial::EmissionOperator) //////////////////////