Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.2] New CPU lightmapper #44628

Merged
merged 7 commits into from
Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
36 changes: 36 additions & 0 deletions core/math/geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@
#include "geometry.h"

#include "core/print_string.h"

#include "thirdparty/misc/clipper.hpp"
#include "thirdparty/misc/triangulator.h"
#define STB_RECT_PACK_IMPLEMENTATION
#include "thirdparty/stb_rect_pack/stb_rect_pack.h"
Comment on lines +37 to +38
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick as it's preexisting code, but please add a separation line between Godot headers ("core/print_string.h") and thirdparty/system headers.


#define SCALE_FACTOR 100000.0 // Based on CMP_EPSILON.

Expand Down Expand Up @@ -1224,3 +1227,36 @@ Vector<Vector3> Geometry::compute_convex_mesh_points(const Plane *p_planes, int

return points;
}

Vector<Geometry::PackRectsResult> Geometry::partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size) {

Vector<stbrp_node> nodes;
nodes.resize(p_atlas_size.width);
zeromem(nodes.ptrw(), sizeof(stbrp_node) * nodes.size());

stbrp_context context;
stbrp_init_target(&context, p_atlas_size.width, p_atlas_size.height, nodes.ptrw(), p_atlas_size.width);

Vector<stbrp_rect> rects;
rects.resize(p_sizes.size());

for (int i = 0; i < p_sizes.size(); i++) {
rects.write[i].id = i;
rects.write[i].w = p_sizes[i].width;
rects.write[i].h = p_sizes[i].height;
rects.write[i].x = 0;
rects.write[i].y = 0;
rects.write[i].was_packed = 0;
}

stbrp_pack_rects(&context, rects.ptrw(), rects.size());

Vector<PackRectsResult> ret;
ret.resize(p_sizes.size());

for (int i = 0; i < p_sizes.size(); i++) {
ret.write[rects[i].id] = { rects[i].x, rects[i].y, static_cast<bool>(rects[i].was_packed) };
}

return ret;
}
28 changes: 28 additions & 0 deletions core/math/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,27 @@ class Geometry {
return (cn.cross(an) > 0) == orientation;
}

static Vector3 barycentric_coordinates_2d(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) {
// http://www.blackpawn.com/texts/pointinpoly/
Vector2 v0 = c - a;
Vector2 v1 = b - a;
Vector2 v2 = s - a;

// Compute dot products
double dot00 = v0.dot(v0);
double dot01 = v0.dot(v1);
double dot02 = v0.dot(v2);
double dot11 = v1.dot(v1);
double dot12 = v1.dot(v2);

// Compute barycentric coordinates
double invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
double b2 = (dot11 * dot02 - dot01 * dot12) * invDenom;
double b1 = (dot00 * dot12 - dot01 * dot02) * invDenom;
double b0 = 1.0f - b2 - b1;
return Vector3(b0, b1, b2);
}

static Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 *p_segment) {

Vector2 p = p_point - p_segment[0];
Expand Down Expand Up @@ -1014,6 +1035,13 @@ class Geometry {

static void make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size);

struct PackRectsResult {
int x;
int y;
bool packed;
};
static Vector<PackRectsResult> partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size);

static Vector<Vector3> compute_convex_mesh_points(const Plane *p_planes, int p_plane_count);

private:
Expand Down
106 changes: 70 additions & 36 deletions doc/classes/BakedLightmap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,54 +16,71 @@
</return>
<argument index="0" name="from_node" type="Node" default="null">
</argument>
<argument index="1" name="create_visual_debug" type="bool" default="false">
<argument index="1" name="data_save_path" type="String" default="&quot;&quot;">
</argument>
<description>
Bakes the lightmaps within the currently edited scene. Returns a [enum BakeError] to signify if the bake was successful, or if unsuccessful, how the bake failed.
</description>
</method>
<method name="debug_bake">
<return type="void">
</return>
<description>
Executes a dry run bake of lightmaps within the currently edited scene.
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 save path is provided it will try to match the path from the current [member light_data].
</description>
</method>
</methods>
<members>
<member name="bake_cell_size" type="float" setter="set_bake_cell_size" getter="get_bake_cell_size" default="0.25">
Grid subdivision size for lightmapper calculation. The default value will work for most cases. Increase for better lighting on small details or if your scene is very large.
<member name="atlas_generate" type="bool" setter="set_generate_atlas" getter="is_generate_atlas_enabled" default="true">
When enabled, the lightmapper will merge the textures for all meshes into a single large layered texture. Not supported in GLES2.
</member>
<member name="bake_default_texels_per_unit" type="float" setter="set_bake_default_texels_per_unit" getter="get_bake_default_texels_per_unit" default="20.0">
If a [member Mesh.lightmap_size_hint] isn't specified, the lightmap baker will dynamically set the lightmap size using this value. This value is measured in texels per world unit. The maximum lightmap texture size is 4096x4096.
<member name="atlas_max_size" type="int" setter="set_max_atlas_size" getter="get_max_atlas_size" default="4096">
Maximum size of each lightmap layer, only used when [member atlas_generate] is enabled.
</member>
<member name="bake_energy" type="float" setter="set_energy" getter="get_energy" default="1.0">
Multiplies the light sources' intensity by this value. For instance, if the value is set to 2, lights will be twice as bright. If the value is set to 0.5, lights will be half as bright.
<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.
</member>
<member name="bake_extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3( 10, 10, 10 )">
The size of the affected area.
<member name="bounces" type="int" setter="set_bounces" getter="get_bounces" default="3">
Number of light bounces that are taken into account during baking.
</member>
<member name="bake_hdr" type="bool" setter="set_hdr" getter="is_hdr" default="false">
If [code]true[/code], the lightmap can capture light values greater than [code]1.0[/code]. Turning this off will result in a smaller file size.
<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="bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="BakedLightmap.BakeMode" default="0">
Lightmapping mode. See [enum BakeMode].
<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.
</member>
<member name="bake_propagation" type="float" setter="set_propagation" getter="get_propagation" default="1.0">
Defines how far the light will travel before it is no longer effective. The higher the number, the farther the light will travel. For instance, if the value is set to 2, the light will go twice as far. If the value is set to 0.5, the light will only go half as far.
<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 proagation in the captured octree.
</member>
<member name="bake_quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="BakedLightmap.BakeQuality" default="1">
Three quality modes are available. Higher quality requires more rendering time. See [enum BakeQuality].
<member name="capture_quality" type="int" setter="set_capture_quality" getter="get_capture_quality" enum="BakedLightmap.BakeQuality" default="1">
Bake quality of the capture data.
</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. Cannot be larger than [member bake_cell_size].
<member name="default_texels_per_unit" type="float" setter="set_default_texels_per_unit" getter="get_default_texels_per_unit" default="16.0">
If a baked mesh doesn't have a UV2 size hint, this value will be used to roughly compute a suitable lightmap size.
</member>
<member name="environment_custom_color" type="Color" setter="set_environment_custom_color" getter="get_environment_custom_color">
The environment color when [member environment_mode] is set to [constant ENVIRONMENT_MODE_CUSTOM_COLOR].
</member>
<member name="environment_custom_energy" type="float" setter="set_environment_custom_energy" getter="get_environment_custom_energy">
The energy scaling factor when when [member environment_mode] is set to [constant ENVIRONMENT_MODE_CUSTOM_COLOR] or [constant ENVIRONMENT_MODE_CUSTOM_SKY].
</member>
<member name="environment_custom_sky" type="Sky" setter="set_environment_custom_sky" getter="get_environment_custom_sky">
The [Sky] resource to use when [member environment_mode] is set o [constant ENVIRONMENT_MODE_CUSTOM_SKY].
</member>
<member name="environment_custom_sky_rotation_degrees" type="Vector3" setter="set_environment_custom_sky_rotation_degrees" getter="get_environment_custom_sky_rotation_degrees">
The rotation of the baked custom sky.
</member>
<member name="environment_mode" type="int" setter="set_environment_mode" getter="get_environment_mode" enum="BakedLightmap.EnvironmentMode" default="0">
Decides which environment to use during baking.
</member>
<member name="image_path" type="String" setter="set_image_path" getter="get_image_path" default="&quot;.&quot;">
The location where lightmaps will be saved.
<member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3( 10, 10, 10 )">
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.
</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 indrect light baking. The amount of samples for each quality level can be configured in the project settings.
</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.
</member>
</members>
<constants>
<constant name="BAKE_QUALITY_LOW" value="0" enum="BakeQuality">
Expand All @@ -73,13 +90,10 @@
The default bake quality mode.
</constant>
<constant name="BAKE_QUALITY_HIGH" value="2" enum="BakeQuality">
The highest bake quality mode. Takes longer to calculate.
A higher bake quality mode. Takes longer to calculate.
</constant>
<constant name="BAKE_MODE_CONE_TRACE" value="0" enum="BakeMode">
Less precise but faster bake mode.
</constant>
<constant name="BAKE_MODE_RAY_TRACE" value="1" enum="BakeMode">
More precise bake mode but can take considerably longer to bake.
<constant name="BAKE_QUALITY_ULTRA" value="3" enum="BakeQuality">
The highest bake quality mode. Takes the longest to calculate.
</constant>
<constant name="BAKE_ERROR_OK" value="0" enum="BakeError">
Baking was successful.
Expand All @@ -93,8 +107,28 @@
<constant name="BAKE_ERROR_CANT_CREATE_IMAGE" value="3" enum="BakeError">
Returns when the baker cannot save per-mesh textures to file.
</constant>
<constant name="BAKE_ERROR_USER_ABORTED" value="4" enum="BakeError">
<constant name="BAKE_ERROR_LIGHTMAP_SIZE" value="4" enum="BakeError">
The size of the generated lightmaps is too large.
</constant>
<constant name="BAKE_ERROR_INVALID_MESH" value="5" enum="BakeError">
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.
</constant>
<constant name="BAKE_ERROR_NO_LIGHTMAPPER" value="7" enum="BakeError">
</constant>
<constant name="ENVIRONMENT_MODE_DISABLED" value="0" enum="EnvironmentMode">
No environment is used during baking.
</constant>
<constant name="ENVIRONMENT_MODE_SCENE" value="1" enum="EnvironmentMode">
The baked environment is automatically picked from the current scene.
</constant>
<constant name="ENVIRONMENT_MODE_CUSTOM_SKY" value="2" enum="EnvironmentMode">
A custom sky is used as environment during baking.
</constant>
<constant name="ENVIRONMENT_MODE_CUSTOM_COLOR" value="3" enum="EnvironmentMode">
A custom solid color is used as environment during baking.
</constant>
</constants>
</class>
10 changes: 7 additions & 3 deletions doc/classes/BakedLightmapData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
</return>
<argument index="0" name="path" type="NodePath">
</argument>
<argument index="1" name="lightmap" type="Texture">
<argument index="1" name="lightmap" type="Resource">
</argument>
<argument index="2" name="instance" type="int">
<argument index="2" name="lightmap_slice" type="int">
</argument>
<argument index="3" name="lightmap_uv_rect" type="Rect2">
</argument>
<argument index="4" name="instance" type="int">
</argument>
<description>
</description>
Expand All @@ -32,7 +36,7 @@
</description>
</method>
<method name="get_user_lightmap" qualifiers="const">
<return type="Texture">
<return type="Resource">
</return>
<argument index="0" name="user_idx" type="int">
</argument>
Expand Down
20 changes: 20 additions & 0 deletions doc/classes/GeometryInstance.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
<member name="extra_cull_margin" type="float" setter="set_extra_cull_margin" getter="get_extra_cull_margin" default="0.0">
The extra distance added to the GeometryInstance's bounding box ([AABB]) to increase its cull box.
</member>
<member name="generate_lightmap" type="bool" setter="set_generate_lightmap" getter="get_generate_lightmap" default="true">
When disabled, the mesh will be taken into account when computing indirect lighting, but the resulting lightmap will not be saved. Useful for emissive only materials or shadow casters.
</member>
<member name="lightmap_scale" type="int" setter="set_lightmap_scale" getter="get_lightmap_scale" enum="GeometryInstance.LightmapScale" default="0">
Scale factor for the generated baked lightmap. Useful for adding detail to certain mesh instances.
</member>
<member name="lod_max_distance" type="float" setter="set_lod_max_distance" getter="get_lod_max_distance" default="0.0">
The GeometryInstance's max LOD distance.
[b]Note:[/b] This property currently has no effect.
Expand All @@ -71,6 +77,20 @@
</member>
</members>
<constants>
<constant name="LIGHTMAP_SCALE_1X" value="0" enum="LightmapScale">
The generated lightmap texture will have the original size.
</constant>
<constant name="LIGHTMAP_SCALE_2X" value="1" enum="LightmapScale">
The generated lightmap texture will be twice as large, on each axis.
</constant>
<constant name="LIGHTMAP_SCALE_4X" value="2" enum="LightmapScale">
The generated lightmap texture will be 4 times as large, on each axis.
</constant>
<constant name="LIGHTMAP_SCALE_8X" value="3" enum="LightmapScale">
The generated lightmap texture will be 8 times as large, on each axis.
</constant>
<constant name="LIGHTMAP_SCALE_MAX" value="4" enum="LightmapScale">
</constant>
<constant name="SHADOW_CASTING_SETTING_OFF" value="0" enum="ShadowCastingSetting">
Will not cast any shadows.
</constant>
Expand Down
2 changes: 1 addition & 1 deletion doc/classes/Mesh.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
</methods>
<members>
<member name="lightmap_size_hint" type="Vector2" setter="set_lightmap_size_hint" getter="get_lightmap_size_hint" default="Vector2( 0, 0 )">
Sets a hint to be used for lightmap resolution in [BakedLightmap]. Overrides [member BakedLightmap.bake_default_texels_per_unit].
Sets a hint to be used for lightmap resolution in [BakedLightmap]. Overrides [member BakedLightmap.default_texels_per_unit].
</member>
</members>
<constants>
Expand Down
18 changes: 18 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,18 @@
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/quality/high_quality_ray_count" type="int" setter="" getter="" default="512">
Amount of light samples taken when using [constant BakedLightmap.BAKE_QUALITY_HIGH].
</member>
<member name="rendering/cpu_lightmapper/quality/low_quality_ray_count" type="int" setter="" getter="" default="64">
Amount of light samples taken when using [constant BakedLightmap.BAKE_QUALITY_LOW].
</member>
<member name="rendering/cpu_lightmapper/quality/medium_quality_ray_count" type="int" setter="" getter="" default="256">
Amount of light samples taken when using [constant BakedLightmap.BAKE_QUALITY_MEDIUM].
</member>
<member name="rendering/cpu_lightmapper/quality/ultra_quality_ray_count" type="int" setter="" getter="" default="1024">
Amount of light samples taken when using [constant BakedLightmap.BAKE_QUALITY_ULTRA].
</member>
<member name="rendering/environment/default_clear_color" type="Color" setter="" getter="" default="Color( 0.3, 0.3, 0.3, 1 )">
Default background clear color. Overridable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method VisualServer.set_default_clear_color].
</member>
Expand Down Expand Up @@ -1169,6 +1181,12 @@
<member name="rendering/quality/intended_usage/framebuffer_allocation.mobile" type="int" setter="" getter="" default="3">
Lower-end override for [member rendering/quality/intended_usage/framebuffer_allocation] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/quality/lightmapping/use_bicubic_sampling" type="bool" setter="" getter="" default="true">
Enable usage of bicubic sampling in baked lightmaps. This results in smoother looking lighting at the expense of more bandwidth usage. On GLES2, changes to this setting will only be applied upon restarting the application.
</member>
<member name="rendering/quality/lightmapping/use_bicubic_sampling.mobile" type="bool" setter="" getter="" default="false">
Lower-end override for [member rendering/quality/lightmapping/use_bicubic_sampling] on mobile devices, in order to reduce bandwidth usage.
</member>
<member name="rendering/quality/reflections/atlas_size" type="int" setter="" getter="" default="2048">
Size of the atlas used by reflection probes. A larger size can result in higher visual quality, while a smaller size will be faster and take up less memory.
</member>
Expand Down
4 changes: 4 additions & 0 deletions doc/classes/VisualServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2045,6 +2045,10 @@
</argument>
<argument index="2" name="lightmap" type="RID">
</argument>
<argument index="3" name="lightmap_slice" type="int" default="-1">
</argument>
<argument index="4" name="lightmap_uv_rect" type="Rect2" default="Rect2( 0, 0, 1, 1 )">
</argument>
<description>
Sets the lightmap to use with this instance.
</description>
Expand Down
7 changes: 7 additions & 0 deletions drivers/gles2/rasterizer_scene_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2572,6 +2572,9 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,

if (rebind_lightmap && lightmap) {
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHTMAP_ENERGY, lightmap_energy);
if (storage->config.use_lightmap_filter_bicubic) {
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHTMAP_TEXTURE_SIZE, Vector2(lightmap->width, lightmap->height));
}
}

state.scene_shader.set_uniform(SceneShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
Expand Down Expand Up @@ -4047,6 +4050,10 @@ void RasterizerSceneGLES2::initialize() {
}
}

if (storage->config.use_lightmap_filter_bicubic) {
state.scene_shader.add_custom_define("#define USE_LIGHTMAP_FILTER_BICUBIC\n");
}

shadow_filter_mode = SHADOW_FILTER_NEAREST;

glFrontFace(GL_CW);
Expand Down
Loading