Add a property to control the bounce indirect energy in BakedLightmap
Higher values will make indirect lighting brighter. A value of 1.0 represents physically accurate behavior, but higher values can be used to make indirect lighting propagate more visibly when using a low number of bounces. This can be used to speed up bake times by lowering the number of bounces then increasing the bounce indirect energy. Unlike BakedLightmapData's energy property, this property does not affect direct lighting emitted by light nodes or emissive materials.
This commit is contained in:
parent
d22f487dfe
commit
974d3aa9cd
7 changed files with 34 additions and 8 deletions
|
@ -5,6 +5,7 @@
|
|||
</brief_description>
|
||||
<description>
|
||||
Baked lightmaps are an alternative workflow for adding indirect (or baked) lighting to a scene. Unlike the [GIProbe] approach, baked lightmaps work fine on low-end PCs and mobile devices as they consume almost no resources in run-time.
|
||||
[b]Note:[/b] Due to how lightmaps work, most properties only have a visible effect once lightmaps are baked again.
|
||||
</description>
|
||||
<tutorials>
|
||||
<link>https://docs.godotengine.org/en/3.3/tutorials/3d/baked_lightmaps.html</link>
|
||||
|
@ -30,10 +31,14 @@
|
|||
Maximum size of each lightmap layer, only used when [member atlas_generate] is enabled.
|
||||
</member>
|
||||
<member name="bias" type="float" setter="set_bias" getter="get_bias" default="0.005">
|
||||
Raycasting bias used during baking to avoid floating point precission issues.
|
||||
Raycasting bias used during baking to avoid floating point precision issues.
|
||||
</member>
|
||||
<member name="bounce_indirect_energy" type="float" setter="set_bounce_indirect_energy" getter="get_bounce_indirect_energy" default="1.0">
|
||||
The energy multiplier for each bounce. Higher values will make indirect lighting brighter. A value of [code]1.0[/code] represents physically accurate behavior, but higher values can be used to make indirect lighting propagate more visibly when using a low number of bounces. This can be used to speed up bake times by lowering the number of [member bounces] then increasing [member bounce_indirect_energy]. Unlike [member BakedLightmapData.energy], this property does not affect direct lighting emitted by light nodes, emissive materials and the environment.
|
||||
[b]Note:[/b] [member bounce_indirect_energy] only has an effect if [member bounces] is set to a value greater than or equal to [code]1[/code].
|
||||
</member>
|
||||
<member name="bounces" type="int" setter="set_bounces" getter="get_bounces" default="3">
|
||||
Number of light bounces that are taken into account during baking.
|
||||
Number of light bounces that are taken into account during baking. See also [member bounce_indirect_energy].
|
||||
</member>
|
||||
<member name="capture_cell_size" type="float" setter="set_capture_cell_size" getter="get_capture_cell_size" default="0.5">
|
||||
Grid size used for real-time capture information on dynamic objects.
|
||||
|
|
|
@ -66,7 +66,8 @@
|
|||
<member name="cell_subdiv" type="int" setter="set_cell_subdiv" getter="get_cell_subdiv" default="1">
|
||||
</member>
|
||||
<member name="energy" type="float" setter="set_energy" getter="get_energy" default="1.0">
|
||||
Global energy multiplier for baked and dynamic capture objects.
|
||||
Global energy multiplier for baked and dynamic capture objects. This can be changed at run-time without having to bake lightmaps again.
|
||||
To adjust only the energy of indirect lighting (without affecting direct lighting or emissive materials), adjust [member BakedLightmap.bounce_indirect_energy] and bake lightmaps again.
|
||||
</member>
|
||||
<member name="interior" type="bool" setter="set_interior" getter="is_interior" default="false">
|
||||
Controls whether dynamic capture objects receive environment lighting or not.
|
||||
|
|
|
@ -897,7 +897,7 @@ void LightmapperCPU::_compute_indirect_light(uint32_t p_idx, void *r_lightmap) {
|
|||
|
||||
color += throughput * sample.emission;
|
||||
throughput *= sample.albedo;
|
||||
color += throughput * sample.direct_light;
|
||||
color += throughput * sample.direct_light * parameters.bounce_indirect_energy;
|
||||
|
||||
// Russian Roulette
|
||||
// https://computergraphics.stackexchange.com/questions/2316/is-russian-roulette-really-the-answer
|
||||
|
@ -1256,7 +1256,7 @@ void LightmapperCPU::_blit_lightmap(const Vector<Vector3> &p_src, const Vector2i
|
|||
p_dst->unlock();
|
||||
}
|
||||
|
||||
LightmapperCPU::BakeError LightmapperCPU::bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, bool p_generate_atlas, int p_max_texture_size, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function, void *p_bake_userdata, BakeStepFunc p_substep_function) {
|
||||
LightmapperCPU::BakeError LightmapperCPU::bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bounce_indirect_energy, float p_bias, bool p_generate_atlas, int p_max_texture_size, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function, void *p_bake_userdata, BakeStepFunc p_substep_function) {
|
||||
if (p_step_function) {
|
||||
bool cancelled = p_step_function(0.0, TTR("Begin Bake"), p_bake_userdata, true);
|
||||
if (cancelled) {
|
||||
|
@ -1272,6 +1272,7 @@ LightmapperCPU::BakeError LightmapperCPU::bake(BakeQuality p_quality, bool p_use
|
|||
parameters.use_denoiser = p_use_denoiser;
|
||||
parameters.bias = p_bias;
|
||||
parameters.bounces = p_bounces;
|
||||
parameters.bounce_indirect_energy = p_bounce_indirect_energy;
|
||||
parameters.environment_transform = p_environment_transform;
|
||||
parameters.environment_panorama = p_environment_panorama;
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ class LightmapperCPU : public Lightmapper {
|
|||
struct BakeParams {
|
||||
float bias;
|
||||
int bounces;
|
||||
float bounce_indirect_energy;
|
||||
int samples;
|
||||
bool use_denoiser = true;
|
||||
Ref<Image> environment_panorama;
|
||||
|
@ -169,7 +170,7 @@ public:
|
|||
virtual void add_directional_light(bool p_bake_direct, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_size);
|
||||
virtual void add_omni_light(bool p_bake_direct, const Vector3 &p_position, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_size);
|
||||
virtual void add_spot_light(bool p_bake_direct, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size);
|
||||
virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, bool p_generate_atlas, int p_max_texture_size, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_bake_userdata = nullptr, BakeStepFunc p_substep_function = nullptr);
|
||||
virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bounce_energy, float p_bias, bool p_generate_atlas, int p_max_texture_size, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_bake_userdata = nullptr, BakeStepFunc p_substep_function = nullptr);
|
||||
|
||||
int get_bake_texture_count() const;
|
||||
Ref<Image> get_bake_texture(int p_index) const;
|
||||
|
|
|
@ -815,7 +815,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_data_sa
|
|||
|
||||
bool gen_atlas = OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2 ? false : generate_atlas;
|
||||
|
||||
Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, bounces, bias, gen_atlas, max_atlas_size, environment_image, environment_xform, _lightmap_bake_step_function, &bsud, bake_substep_function);
|
||||
Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, bounces, bounce_indirect_energy, bias, gen_atlas, max_atlas_size, environment_image, environment_xform, _lightmap_bake_step_function, &bsud, bake_substep_function);
|
||||
|
||||
if (bake_err != Lightmapper::BAKE_OK) {
|
||||
switch (bake_err) {
|
||||
|
@ -1412,6 +1412,15 @@ int BakedLightmap::get_bounces() const {
|
|||
return bounces;
|
||||
}
|
||||
|
||||
void BakedLightmap::set_bounce_indirect_energy(float p_indirect_energy) {
|
||||
ERR_FAIL_COND(p_indirect_energy < 0.0);
|
||||
bounce_indirect_energy = p_indirect_energy;
|
||||
}
|
||||
|
||||
float BakedLightmap::get_bounce_indirect_energy() const {
|
||||
return bounce_indirect_energy;
|
||||
}
|
||||
|
||||
void BakedLightmap::set_bias(float p_bias) {
|
||||
ERR_FAIL_COND(p_bias < 0.00001f);
|
||||
bias = p_bias;
|
||||
|
@ -1460,6 +1469,9 @@ void BakedLightmap::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_bounces", "bounces"), &BakedLightmap::set_bounces);
|
||||
ClassDB::bind_method(D_METHOD("get_bounces"), &BakedLightmap::get_bounces);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_bounce_indirect_energy", "bounce_indirect_energy"), &BakedLightmap::set_bounce_indirect_energy);
|
||||
ClassDB::bind_method(D_METHOD("get_bounce_indirect_energy"), &BakedLightmap::get_bounce_indirect_energy);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_bias", "bias"), &BakedLightmap::set_bias);
|
||||
ClassDB::bind_method(D_METHOD("get_bias"), &BakedLightmap::get_bias);
|
||||
|
||||
|
@ -1524,6 +1536,7 @@ void BakedLightmap::_bind_methods() {
|
|||
ADD_GROUP("Tweaks", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "quality", PROPERTY_HINT_ENUM, "Low,Medium,High,Ultra"), "set_bake_quality", "get_bake_quality");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "bounces", PROPERTY_HINT_RANGE, "0,16,1"), "set_bounces", "get_bounces");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bounce_indirect_energy", "get_bounce_indirect_energy");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_denoiser"), "set_use_denoiser", "is_using_denoiser");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_color"), "set_use_color", "is_using_color");
|
||||
|
@ -1583,6 +1596,7 @@ BakedLightmap::BakedLightmap() {
|
|||
capture_propagation = 1;
|
||||
capture_enabled = true;
|
||||
bounces = 3;
|
||||
bounce_indirect_energy = 1.0;
|
||||
image_path = "";
|
||||
set_disable_scale(true);
|
||||
capture_cell_size = 0.5;
|
||||
|
|
|
@ -163,6 +163,7 @@ private:
|
|||
int max_atlas_size;
|
||||
bool capture_enabled;
|
||||
int bounces;
|
||||
float bounce_indirect_energy;
|
||||
bool use_denoiser;
|
||||
bool use_hdr;
|
||||
bool use_color;
|
||||
|
@ -266,6 +267,9 @@ public:
|
|||
void set_bounces(int p_bounces);
|
||||
int get_bounces() const;
|
||||
|
||||
void set_bounce_indirect_energy(float p_indirect_energy);
|
||||
float get_bounce_indirect_energy() const;
|
||||
|
||||
void set_bias(float p_bias);
|
||||
float get_bias() const;
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ public:
|
|||
virtual void add_directional_light(bool p_bake_direct, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_size) = 0;
|
||||
virtual void add_omni_light(bool p_bake_direct, const Vector3 &p_position, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_size) = 0;
|
||||
virtual void add_spot_light(bool p_bake_direct, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) = 0;
|
||||
virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, bool p_generate_atlas, int p_max_texture_size, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr, BakeStepFunc p_substep_function = nullptr) = 0;
|
||||
virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bounce_indirect_energy, float p_bias, bool p_generate_atlas, int p_max_texture_size, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr, BakeStepFunc p_substep_function = nullptr) = 0;
|
||||
|
||||
virtual int get_bake_texture_count() const = 0;
|
||||
virtual Ref<Image> get_bake_texture(int p_index) const = 0;
|
||||
|
|
Loading…
Reference in a new issue