diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/gdscript/gdscript.cpp | 20 | ||||
-rw-r--r-- | modules/gdscript/gdscript.h | 1 | ||||
-rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 31 | ||||
-rw-r--r-- | modules/lightmapper_rd/lightmapper_rd.cpp | 45 | ||||
-rw-r--r-- | modules/lightmapper_rd/lightmapper_rd.h | 9 | ||||
-rw-r--r-- | modules/lightmapper_rd/lm_common_inc.glsl | 3 | ||||
-rw-r--r-- | modules/lightmapper_rd/lm_compute.glsl | 86 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs | 2 |
8 files changed, 138 insertions, 59 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 617db883f8..e6aeef2fd1 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1254,6 +1254,14 @@ GDScript::~GDScript() { memdelete(E.value); } + if (implicit_initializer) { + memdelete(implicit_initializer); + } + + if (implicit_ready) { + memdelete(implicit_ready); + } + if (GDScriptCache::singleton) { // Cache may have been already destroyed at engine shutdown. GDScriptCache::remove_script(get_path()); } @@ -1541,6 +1549,18 @@ bool GDScriptInstance::has_method(const StringName &p_method) const { Variant GDScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { GDScript *sptr = script.ptr(); + if (unlikely(p_method == SNAME("_ready"))) { + // Call implicit ready first, including for the super classes. + while (sptr) { + if (sptr->implicit_ready) { + sptr->implicit_ready->call(this, nullptr, 0, r_error); + } + sptr = sptr->_base; + } + + // Reset this back for the regular call. + sptr = script.ptr(); + } while (sptr) { HashMap<StringName, GDScriptFunction *>::Iterator E = sptr->member_functions.find(p_method); if (E) { diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 0057962d5e..feb0a237df 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -120,6 +120,7 @@ class GDScript : public Script { GDScriptFunction *implicit_initializer = nullptr; GDScriptFunction *initializer = nullptr; //direct pointer to new , faster to locate + GDScriptFunction *implicit_ready = nullptr; int subclass_count = 0; RBSet<Object *> instances; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 25454030b1..16a0b17d61 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1990,18 +1990,18 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ // Parse initializer if applies. bool is_implicit_initializer = !p_for_ready && !p_func && !p_for_lambda; - bool is_initializer = p_func && !p_for_lambda && String(p_func->identifier->name) == GDScriptLanguage::get_singleton()->strings._init; - bool is_for_ready = p_for_ready || (p_func && !p_for_lambda && String(p_func->identifier->name) == "_ready"); + bool is_initializer = p_func && !p_for_lambda && p_func->identifier->name == GDScriptLanguage::get_singleton()->strings._init; + bool is_implicit_ready = !p_func && p_for_ready; - if (!p_for_lambda && (is_implicit_initializer || is_for_ready)) { + if (!p_for_lambda && (is_implicit_initializer || is_implicit_ready)) { // Initialize class fields. for (int i = 0; i < p_class->members.size(); i++) { if (p_class->members[i].type != GDScriptParser::ClassNode::Member::VARIABLE) { continue; } const GDScriptParser::VariableNode *field = p_class->members[i].variable; - if (field->onready != is_for_ready) { - // Only initialize in _ready. + if (field->onready != is_implicit_ready) { + // Only initialize in @implicit_ready. continue; } @@ -2123,6 +2123,8 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ p_script->initializer = gd_function; } else if (is_implicit_initializer) { p_script->implicit_initializer = gd_function; + } else if (is_implicit_ready) { + p_script->implicit_ready = gd_function; } if (p_func) { @@ -2140,7 +2142,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ #endif } - if (!p_for_lambda) { + if (!is_implicit_initializer && !is_implicit_ready && !p_for_lambda) { p_script->member_functions[func_name] = gd_function; } @@ -2208,11 +2210,19 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar for (const KeyValue<StringName, GDScriptFunction *> &E : p_script->member_functions) { memdelete(E.value); } + if (p_script->implicit_initializer) { + memdelete(p_script->implicit_initializer); + } + if (p_script->implicit_ready) { + memdelete(p_script->implicit_ready); + } p_script->member_functions.clear(); p_script->member_indices.clear(); p_script->member_info.clear(); p_script->_signals.clear(); p_script->initializer = nullptr; + p_script->implicit_initializer = nullptr; + p_script->implicit_ready = nullptr; p_script->tool = parser->is_tool(); p_script->name = p_class->identifier ? p_class->identifier->name : ""; @@ -2456,15 +2466,10 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { //parse methods - bool has_ready = false; - for (int i = 0; i < p_class->members.size(); i++) { const GDScriptParser::ClassNode::Member &member = p_class->members[i]; if (member.type == member.FUNCTION) { const GDScriptParser::FunctionNode *function = member.function; - if (!has_ready && function->identifier->name == "_ready") { - has_ready = true; - } Error err = OK; _parse_function(err, p_script, p_class, function); if (err) { @@ -2498,8 +2503,8 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa } } - if (!has_ready && p_class->onready_used) { - //create a _ready constructor + if (p_class->onready_used) { + // Create an implicit_ready constructor. Error err = OK; _parse_function(err, p_script, p_class, nullptr, true); if (err) { diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 214c60091c..2ce3715bea 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -51,7 +51,7 @@ void LightmapperRD::add_mesh(const MeshData &p_mesh) { mesh_instances.push_back(mi); } -void LightmapperRD::add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance) { +void LightmapperRD::add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance, float p_shadow_blur) { Light l; l.type = LIGHT_TYPE_DIRECTIONAL; l.direction[0] = p_direction.x; @@ -62,11 +62,12 @@ void LightmapperRD::add_directional_light(bool p_static, const Vector3 &p_direct l.color[2] = p_color.b; l.energy = p_energy; l.static_bake = p_static; - l.size = p_angular_distance; + l.size = Math::tan(Math::deg2rad(p_angular_distance)); + l.shadow_blur = p_shadow_blur; lights.push_back(l); } -void LightmapperRD::add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size) { +void LightmapperRD::add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size, float p_shadow_blur) { Light l; l.type = LIGHT_TYPE_OMNI; l.position[0] = p_position.x; @@ -80,10 +81,11 @@ void LightmapperRD::add_omni_light(bool p_static, const Vector3 &p_position, con l.energy = p_energy; l.static_bake = p_static; l.size = p_size; + l.shadow_blur = p_shadow_blur; lights.push_back(l); } -void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) { +void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size, float p_shadow_blur) { Light l; l.type = LIGHT_TYPE_SPOT; l.position[0] = p_position.x; @@ -102,6 +104,7 @@ void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, con l.energy = p_energy; l.static_bake = p_static; l.size = p_size; + l.shadow_blur = p_shadow_blur; lights.push_back(l); } @@ -1140,6 +1143,23 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d RID light_uniform_set = rd->uniform_set_create(uniforms, compute_shader_primary, 1); + switch (p_quality) { + case BAKE_QUALITY_LOW: { + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/low_quality_ray_count"); + } break; + case BAKE_QUALITY_MEDIUM: { + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/medium_quality_ray_count"); + } break; + case BAKE_QUALITY_HIGH: { + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/high_quality_ray_count"); + } break; + case BAKE_QUALITY_ULTRA: { + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/ultra_quality_ray_count"); + } break; + } + + push_constant.ray_count = CLAMP(push_constant.ray_count, 16u, 8192u); + RD::ComputeListID compute_list = rd->compute_list_begin(); rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_primary_pipeline); rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0); @@ -1230,23 +1250,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d uniforms.write[1].set_id(0, light_dest_tex); secondary_uniform_set[1] = rd->uniform_set_create(uniforms, compute_shader_secondary, 1); - switch (p_quality) { - case BAKE_QUALITY_LOW: { - push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/low_quality_ray_count"); - } break; - case BAKE_QUALITY_MEDIUM: { - push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/medium_quality_ray_count"); - } break; - case BAKE_QUALITY_HIGH: { - push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/high_quality_ray_count"); - } break; - case BAKE_QUALITY_ULTRA: { - push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/ultra_quality_ray_count"); - } break; - } - - push_constant.ray_count = CLAMP(push_constant.ray_count, 16u, 8192u); - int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size"))); int max_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_rays_per_pass"); diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index bf9f9b5954..8cb4b58a18 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -57,8 +57,9 @@ class LightmapperRD : public Lightmapper { float attenuation = 0.0; float cos_spot_angle = 0.0; float inv_spot_attenuation = 0.0; + float shadow_blur = 0.0; uint32_t static_bake = 0; - uint32_t pad[3] = {}; + uint32_t pad[2] = {}; bool operator<(const Light &p_light) const { return type < p_light.type; @@ -236,9 +237,9 @@ class LightmapperRD : public Lightmapper { public: virtual void add_mesh(const MeshData &p_mesh) override; - virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance) override; - virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size) override; - virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) override; + virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance, float p_shadow_blur) override; + virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size, float p_shadow_blur) override; + virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size, float p_shadow_blur) override; virtual void add_probe(const Vector3 &p_position) override; virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_bake_userdata = nullptr) override; diff --git a/modules/lightmapper_rd/lm_common_inc.glsl b/modules/lightmapper_rd/lm_common_inc.glsl index 58523dc1f8..e0e8000f56 100644 --- a/modules/lightmapper_rd/lm_common_inc.glsl +++ b/modules/lightmapper_rd/lm_common_inc.glsl @@ -51,8 +51,9 @@ struct Light { float cos_spot_angle; float inv_spot_attenuation; + float shadow_blur; bool static_bake; - uint pad[3]; + uint pad[2]; }; layout(set = 0, binding = 4, std430) restrict readonly buffer Lights { diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl index 0b6b72a310..efa6cd50b4 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -316,19 +316,24 @@ void main() { for (uint i = 0; i < params.light_count; i++) { vec3 light_pos; + float dist; float attenuation; + float soft_shadowing_disk_size; if (lights.data[i].type == LIGHT_TYPE_DIRECTIONAL) { vec3 light_vec = lights.data[i].direction; light_pos = position - light_vec * length(params.world_size); + dist = length(params.world_size); attenuation = 1.0; + soft_shadowing_disk_size = lights.data[i].size; } else { light_pos = lights.data[i].position; - float d = distance(position, light_pos); - if (d > lights.data[i].range) { + dist = distance(position, light_pos); + if (dist > lights.data[i].range) { continue; } + soft_shadowing_disk_size = lights.data[i].size / dist; - attenuation = get_omni_attenuation(d, 1.0 / lights.data[i].range, lights.data[i].attenuation); + attenuation = get_omni_attenuation(dist, 1.0 / lights.data[i].range, lights.data[i].attenuation); if (lights.data[i].type == LIGHT_TYPE_SPOT) { vec3 rel = normalize(position - light_pos); @@ -352,27 +357,70 @@ void main() { continue; //no need to do anything } - if (trace_ray(position + light_dir * params.bias, light_pos) == RAY_MISS) { - vec3 light = lights.data[i].color * lights.data[i].energy * attenuation; - if (lights.data[i].static_bake) { - static_light += light; -#ifdef USE_SH_LIGHTMAPS + float penumbra = 0.0; + if (lights.data[i].size > 0.0) { + vec3 light_to_point = -light_dir; + vec3 aux = light_to_point.y < 0.777 ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0); + vec3 light_to_point_tan = normalize(cross(light_to_point, aux)); + vec3 light_to_point_bitan = normalize(cross(light_to_point, light_to_point_tan)); + + const uint shadowing_rays_check_penumbra_denom = 2; + uint shadowing_ray_count = params.ray_count; + + uint hits = 0; + uint noise = random_seed(ivec3(atlas_pos, 43573547 /* some prime */)); + vec3 light_disk_to_point = light_to_point; + for (uint j = 0; j < shadowing_ray_count; j++) { + // Optimization: + // Once already traced an important proportion of rays, if all are hits or misses, + // assume we're not in the penumbra so we can infer the rest would have the same result + if (j == shadowing_ray_count / shadowing_rays_check_penumbra_denom) { + if (hits == j) { + // Assume totally lit + hits = shadowing_ray_count; + break; + } else if (hits == 0) { + // Assume totally dark + hits = 0; + break; + } + } - float c[4] = float[]( - 0.282095, //l0 - 0.488603 * light_dir.y, //l1n1 - 0.488603 * light_dir.z, //l1n0 - 0.488603 * light_dir.x //l1p1 - ); + float r = randomize(noise); + float a = randomize(noise) * 2.0 * PI; + vec2 disk_sample = (r * vec2(cos(a), sin(a))) * soft_shadowing_disk_size * lights.data[i].shadow_blur; + light_disk_to_point = normalize(light_to_point + disk_sample.x * light_to_point_tan + disk_sample.y * light_to_point_bitan); - for (uint j = 0; j < 4; j++) { - sh_accum[j].rgb += light * c[j] * (1.0 / 3.0); + if (trace_ray(position - light_disk_to_point * params.bias, position - light_disk_to_point * dist) == RAY_MISS) { + hits++; } -#endif + } + penumbra = float(hits) / float(shadowing_ray_count); + } else { + if (trace_ray(position + light_dir * params.bias, light_pos) == RAY_MISS) { + penumbra = 1.0; + } + } - } else { - dynamic_light += light; + vec3 light = lights.data[i].color * lights.data[i].energy * attenuation * penumbra; + if (lights.data[i].static_bake) { + static_light += light; +#ifdef USE_SH_LIGHTMAPS + + float c[4] = float[]( + 0.282095, //l0 + 0.488603 * light_dir.y, //l1n1 + 0.488603 * light_dir.z, //l1n0 + 0.488603 * light_dir.x //l1p1 + ); + + for (uint j = 0; j < 4; j++) { + sh_accum[j].rgb += light * c[j] * (1.0 / 3.0); } +#endif + + } else { + dynamic_light += light; } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs index 9e8f7ef1b1..3c020a2589 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs @@ -126,7 +126,7 @@ namespace GodotTools.Build { base._Ready(); - MinimumSize = new Vector2(0, 228) * EditorScale; + CustomMinimumSize = new Vector2(0, 228) * EditorScale; SizeFlagsVertical = (int)SizeFlags.ExpandFill; var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill }; |