Skip to content

Commit

Permalink
Add a Preview Bake button for quick iteration with BakedLightmap
Browse files Browse the repository at this point in the history
When using the Preview Bake button instead of Bake Lightmaps,
low quality settings will be used instead of settings from the
BakedLightmap node. A node configuration warning will be displayed
besides the BakedLightmap node to inform the user that the bake
was done in preview mode. This preview bake warning is persisted
to storage to make teamwork easier.

This helps iterate quicker on a scene's lighting since you don't
need to wait as much time to see results.

On a simple test scene, Preview Bake was about 3 times faster
than a "final" bake with the default BakedLightmap settings.

The preview bake settings can be adjusted in the Project Settings.
  • Loading branch information
Calinou committed Aug 11, 2023
1 parent 9435c38 commit 916dd11
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 19 deletions.
12 changes: 12 additions & 0 deletions core/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,18 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("editor/version_control_autoload_on_startup", false);
GLOBAL_DEF("editor/version_control_plugin_name", "");

GLOBAL_DEF("rendering/cpu_lightmapper/preview_bake/quality", 0); // Low quality.
custom_prop_info["rendering/cpu_lightmapper/preview_bake/quality"] = PropertyInfo(Variant::INT, "rendering/cpu_lightmapper/preview_bake/quality", PROPERTY_HINT_ENUM, "Low,Medium,High,Ultra");

GLOBAL_DEF("rendering/cpu_lightmapper/preview_bake/max_bounces", 1);
custom_prop_info["rendering/cpu_lightmapper/preview_bake/max_bounces"] = PropertyInfo(Variant::INT, "rendering/cpu_lightmapper/preview_bake/max_bounces", PROPERTY_HINT_RANGE, "0,16,1");

// Enabled by default so dynamic objects can be lit correctly even in preview mode.
GLOBAL_DEF("rendering/cpu_lightmapper/preview_bake/allow_capture", true);

GLOBAL_DEF("rendering/cpu_lightmapper/preview_bake/capture_quality", 0); // Low quality.
custom_prop_info["rendering/cpu_lightmapper/preview_bake/capture_quality"] = PropertyInfo(Variant::INT, "rendering/cpu_lightmapper/preview_bake/capture_quality", PROPERTY_HINT_ENUM, "Low,Medium,High");

action = Dictionary();
action["deadzone"] = Variant(0.5f);
events = Array();
Expand Down
20 changes: 12 additions & 8 deletions doc/classes/BakedLightmap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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]Procedural generation:[/b] Lightmap baking functionality is only available in the editor. This means [BakedLightmap] is not suited to procedurally generated or user-built levels. For procedurally generated or user-built levels, use [GIProbe] instead.
[b]Note:[/b] Due to how lightmaps work, most properties only have a visible effect once lightmaps are baked again.
[b]Bake modes:[/b] In the editor, after selecting a [BakedLightmap] node, you can choose between performing a [b]Preview Bake[/b] or a "final" bake using the [b]Bake Lightmaps[/b] button. Preview bakes use lower quality settings but are significantly faster to bake (run-time performance is identical). Using preview bakes during development allows you to iterate on your 3D scene's lighting faster. You can change the preview bake quality settings by adjusting the [ProjectSettings]' [code]rendering/cpu_lightmapper/*[/code] properties.
</description>
<tutorials>
<link>$DOCS_URL/tutorials/3d/baked_lightmaps.html</link>
Expand All @@ -16,8 +17,11 @@
<return type="int" enum="BakedLightmap.BakeError" />
<argument index="0" name="from_node" type="Node" default="null" />
<argument index="1" name="data_save_path" type="String" default="&quot;&quot;" />
<argument index="2" name="preview" type="bool" default="false" />
<description>
Bakes the lightmap, scanning from the given [code]from_node[/code] root and saves the resulting [BakedLightmapData] in [code]data_save_path[/code]. If no root node is provided, parent of this node will be used as root instead. If no save path is provided it will try to match the path from the current [member light_data].
Bakes the lightmap, scanning from the given [code]from_node[/code] root and saves the resulting [BakedLightmapData] in [code]data_save_path[/code]. If no root node is provided, parent of this node will be used as root instead. If no save path is provided, it will try to match the path from the current [member light_data].
If [code]preview[/code] is [code]true[/code], performs a preview bake which uses low-quality settings defined in [ProjectSettings] but is faster to bake.
[b]Note:[/b] Only effective when called from editor builds, as Godot doesn't support baking lightmaps at run-time.
</description>
</method>
</methods>
Expand All @@ -37,13 +41,13 @@
[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. See also [member bounce_indirect_energy].
Number of light bounces that are taken into account during baking. See also [member bounce_indirect_energy]. When using Preview Bake, this value will be overridden if [member ProjectSettings.rendering/cpu_lightmapper/preview_bake/max_bounces] is lower than [member bounces].
</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.
</member>
<member name="capture_enabled" type="bool" setter="set_capture_enabled" getter="get_capture_enabled" default="true">
When enabled, an octree containing the scene's lighting information will be computed. This octree will then be used to light dynamic objects in the scene.
If [code]true[/code], an octree containing the scene's lighting information will be computed. This octree will then be used to light dynamic objects in the scene. If [code]true[/code], when using Preview Bake, this value will be overridden by [member ProjectSettings.rendering/cpu_lightmapper/preview_bake/allow_capture].
</member>
<member name="capture_propagation" type="float" setter="set_capture_propagation" getter="get_capture_propagation" default="1.0">
Bias value to reduce the amount of light propagation in the captured octree.
Expand Down Expand Up @@ -76,19 +80,19 @@
Size of the baked lightmap. Only meshes inside this region will be included in the baked lightmap, also used as the bounds of the captured region for dynamic lighting.
</member>
<member name="image_path" type="String" setter="set_image_path" getter="get_image_path">
Deprecated, in previous versions it determined the location where lightmaps were be saved.
[i]Deprecated.[/i] In previous versions, it determined the location where lightmaps were be saved.
</member>
<member name="light_data" type="BakedLightmapData" setter="set_light_data" getter="get_light_data">
The calculated light data.
</member>
<member name="quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="BakedLightmap.BakeQuality" default="1">
Determines the amount of samples per texel used in indirect light baking. The amount of samples for each quality level can be configured in the project settings.
Determines the amount of samples per texel used in indirect light baking. The amount of samples for each quality level can be configured in the project settings. When using Preview Bake, this value will be overridden by [member ProjectSettings.rendering/cpu_lightmapper/preview_bake/quality].
</member>
<member name="use_color" type="bool" setter="set_use_color" getter="is_using_color" default="true">
Store full color values in the lightmap textures. When disabled, lightmap textures will store a single brightness channel. Can be disabled to reduce disk usage if the scene contains only white lights or you don't mind losing color information in indirect lighting.
</member>
<member name="use_denoiser" type="bool" setter="set_use_denoiser" getter="is_using_denoiser" default="true">
When enabled, a lightmap denoiser will be used to reduce the noise inherent to Monte Carlo based global illumination.
When enabled, a lightmap denoiser will be used to reduce the noise inherent to Monte Carlo-based global illumination. This denoising is performed on the CPU after baking lightmaps, and will increase bake times when enabled.
</member>
<member name="use_hdr" type="bool" setter="set_use_hdr" getter="is_using_hdr" default="true">
If [code]true[/code], stores the lightmap textures in a high dynamic range format (EXR). If [code]false[/code], stores the lightmap texture in a low dynamic range PNG image. This can be set to [code]false[/code] to reduce disk usage, but light values over 1.0 will be clamped and you may see banding caused by the reduced precision.
Expand All @@ -97,7 +101,7 @@
</members>
<constants>
<constant name="BAKE_QUALITY_LOW" value="0" enum="BakeQuality">
The lowest bake quality mode. Fastest to calculate.
The lowest bake quality mode (and the default when using Preview Bake). Fastest to calculate.
</constant>
<constant name="BAKE_QUALITY_MEDIUM" value="1" enum="BakeQuality">
The default bake quality mode.
Expand Down Expand Up @@ -127,7 +131,7 @@
Some mesh contains UV2 values outside the [code][0,1][/code] range.
</constant>
<constant name="BAKE_ERROR_USER_ABORTED" value="6" enum="BakeError">
Returns if user cancels baking.
Returned if the user cancels baking.
</constant>
<constant name="BAKE_ERROR_NO_LIGHTMAPPER" value="7" enum="BakeError">
Returns if lightmapper can't be created. Unless you are using a custom lightmapper, please report this as bug.
Expand Down
4 changes: 4 additions & 0 deletions doc/classes/BakedLightmapData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
</member>
<member name="octree" type="PoolByteArray" setter="set_octree" getter="get_octree" default="PoolByteArray( )">
</member>
<member name="preview_bake" type="bool" setter="set_preview_bake" getter="is_preview_bake" default="false">
If [code]true[/code], the bake is considered to be a "preview bake". This is set internally to [code]true[/code] by the editor when using the [b]Preview Bake[/b] button at the top of the 3D editor, and [code]false[/code] when using the [b]Bake Lightmaps[/b] button. This property can also be used by plugins.
See the [BakedLightmap] class description for more information.
</member>
</members>
<constants>
</constants>
Expand Down
14 changes: 14 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1514,6 +1514,20 @@
The amount of UV contraction. This figure is divided by 1000000, and is a proportion of the total texture dimensions, where the width and height are both ranged from 0.0 to 1.0.
Use the default unless correcting for a problem on particular hardware.
</member>
<member name="rendering/cpu_lightmapper/preview_bake/allow_capture" type="bool" setter="" getter="" default="true">
Overrides [member BakedLightmap.capture_enabled] when using the [b]Preview Bake[/b] button after selecting a [BakedLightmap] node in the editor.
If [member BakedLightmap.capture_enabled] is [code]false[/code], this setting will not forcibly enable dynamic object capture.
</member>
<member name="rendering/cpu_lightmapper/preview_bake/capture_quality" type="int" setter="" getter="" default="0">
Overrides [member BakedLightmap.capture_quality] when using the [b]Preview Bake[/b] button after selecting a [BakedLightmap] node in the editor.
</member>
<member name="rendering/cpu_lightmapper/preview_bake/max_bounces" type="int" setter="" getter="" default="1">
Reduces [member BakedLightmap.bounces] when using the [b]Preview Bake[/b] button after selecting a [BakedLightmap] node in the editor.
If the number of bounces defined in the [BakedLightmap] node is lower than this setting, the number of bounces defined in the [BakedLightmap] will be used instead.
</member>
<member name="rendering/cpu_lightmapper/preview_bake/quality" type="int" setter="" getter="" default="0">
Overrides [member BakedLightmap.quality] when using the [b]Preview Bake[/b] button after selecting a [BakedLightmap] node in the editor.
</member>
<member name="rendering/cpu_lightmapper/quality/high_quality_ray_count" type="int" setter="" getter="" default="512">
Amount of light samples taken when using [constant BakedLightmap.BAKE_QUALITY_HIGH].
</member>
Expand Down
1 change: 1 addition & 0 deletions editor/icons/icon_bake_preview.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 17 additions & 4 deletions editor/plugins/baked_lightmap_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ void BakedLightmapEditorPlugin::_bake_select_file(const String &p_file) {
if (lightmap) {
BakedLightmap::BakeError err;
if (get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root() == lightmap) {
err = lightmap->bake(lightmap, p_file);
err = lightmap->bake(lightmap, p_file, preview_mode);
} else {
err = lightmap->bake(lightmap->get_parent(), p_file);
err = lightmap->bake(lightmap->get_parent(), p_file, preview_mode);
}

switch (err) {
Expand Down Expand Up @@ -76,7 +76,8 @@ void BakedLightmapEditorPlugin::_bake_select_file(const String &p_file) {
}
}

void BakedLightmapEditorPlugin::_bake() {
void BakedLightmapEditorPlugin::_bake(bool p_preview) {
preview_mode = p_preview;
_bake_select_file("");
}

Expand All @@ -95,8 +96,10 @@ bool BakedLightmapEditorPlugin::handles(Object *p_object) const {

void BakedLightmapEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
bake_preview->show();
bake->show();
} else {
bake_preview->hide();
bake->hide();
}
}
Expand Down Expand Up @@ -152,11 +155,20 @@ void BakedLightmapEditorPlugin::_bind_methods() {

BakedLightmapEditorPlugin::BakedLightmapEditorPlugin(EditorNode *p_node) {
editor = p_node;

bake_preview = memnew(ToolButton);
bake_preview->set_icon(editor->get_gui_base()->get_icon("BakePreview", "EditorIcons"));
bake_preview->set_tooltip(TTR("Bakes lightmaps with low-quality settings for quick iteration.\nPreview bake quality can be changed in the Project Settings."));
bake_preview->set_text(TTR("Preview Bake"));
bake_preview->hide();
bake_preview->connect("pressed", this, "_bake", varray(true));

bake = memnew(ToolButton);
bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons"));
bake->set_tooltip(TTR("Bakes lightmaps with quality settings defined in the BakedLightmap node.\nThis will take more time compared to a Preview Bake."));
bake->set_text(TTR("Bake Lightmaps"));
bake->hide();
bake->connect("pressed", this, "_bake");
bake->connect("pressed", this, "_bake", varray(false));

file_dialog = memnew(EditorFileDialog);
file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
Expand All @@ -165,6 +177,7 @@ BakedLightmapEditorPlugin::BakedLightmapEditorPlugin(EditorNode *p_node) {
file_dialog->connect("file_selected", this, "_bake_select_file");
bake->add_child(file_dialog);

add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake_preview);
add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake);
lightmap = nullptr;

Expand Down
6 changes: 5 additions & 1 deletion editor/plugins/baked_lightmap_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@ class BakedLightmapEditorPlugin : public EditorPlugin {

BakedLightmap *lightmap;

ToolButton *bake_preview;
ToolButton *bake;
EditorNode *editor;

// If `true`, low-quality bake settings will be used for the next bake.
bool preview_mode = false;

EditorFileDialog *file_dialog;
static EditorProgress *tmp_progress;
static EditorProgress *tmp_subprogress;
Expand All @@ -53,7 +57,7 @@ class BakedLightmapEditorPlugin : public EditorPlugin {
static void bake_func_end(uint32_t p_time_started);

void _bake_select_file(const String &p_file);
void _bake();
void _bake(bool p_preview = false);

protected:
static void _bind_methods();
Expand Down

0 comments on commit 916dd11

Please sign in to comment.