diff --git a/doc/classes/LightmapGIData.xml b/doc/classes/LightmapGIData.xml
index 0d0ee679fbc2..296be65d8e86 100644
--- a/doc/classes/LightmapGIData.xml
+++ b/doc/classes/LightmapGIData.xml
@@ -15,8 +15,9 @@
+
- Adds an object that is considered baked within this [LightmapGIData].
+ Adds an object that is considered baked within this [LightmapGIData]. [member texture_size] must match the size of the [i]entire[/i] lightmap texture, which is used for bicubic filtering when rendering the lightmap.
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 3d8f7924a78b..61da7832b2d2 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -125,7 +125,7 @@ void RasterizerSceneGLES3::GeometryInstanceGLES3::_mark_dirty() {
RasterizerSceneGLES3::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element);
}
-void RasterizerSceneGLES3::GeometryInstanceGLES3::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
+void RasterizerSceneGLES3::GeometryInstanceGLES3::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index, const Vector2 &p_lightmap_texture_size) {
}
void RasterizerSceneGLES3::GeometryInstanceGLES3::set_lightmap_capture(const Color *p_sh9) {
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index b4e787ad857d..22f3bf145e4c 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -259,7 +259,7 @@ class RasterizerSceneGLES3 : public RendererSceneRender {
dirty_list_element(this) {}
virtual void _mark_dirty() override;
- virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
+ virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index, const Vector2 &p_lightmap_texture_size) override;
virtual void set_lightmap_capture(const Color *p_sh9) override;
virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override;
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index 3ee08fd5485f..05c3b44c13fc 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -39,12 +39,13 @@
#include "scene/resources/environment.h"
#include "scene/resources/sky.h"
-void LightmapGIData::add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance) {
+void LightmapGIData::add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance, const Vector2 &p_texture_size) {
User user;
user.path = p_path;
user.uv_scale = p_uv_scale;
user.slice_index = p_slice_index;
user.sub_instance = p_sub_instance;
+ user.texture_size = p_texture_size;
users.push_back(user);
}
@@ -72,6 +73,11 @@ int LightmapGIData::get_user_lightmap_slice_index(int p_user) const {
return users[p_user].slice_index;
}
+Vector2 LightmapGIData::get_user_lightmap_texture_size(int p_user) const {
+ ERR_FAIL_INDEX_V(p_user, users.size(), Vector2());
+ return users[p_user].texture_size;
+}
+
void LightmapGIData::clear_users() {
users.clear();
}
@@ -92,6 +98,7 @@ Array LightmapGIData::_get_user_data() const {
ret.push_back(users[i].uv_scale);
ret.push_back(users[i].slice_index);
ret.push_back(users[i].sub_instance);
+ ret.push_back(users[i].texture_size);
}
return ret;
}
@@ -1294,12 +1301,12 @@ void LightmapGI::_assign_lightmaps() {
if (instance_idx >= 0) {
RID instance_id = node->call("get_bake_mesh_instance", instance_idx);
if (instance_id.is_valid()) {
- RS::get_singleton()->instance_geometry_set_lightmap(instance_id, get_instance(), light_data->get_user_lightmap_uv_scale(i), light_data->get_user_lightmap_slice_index(i));
+ RS::get_singleton()->instance_geometry_set_lightmap(instance_id, get_instance(), light_data->get_user_lightmap_uv_scale(i), light_data->get_user_lightmap_slice_index(i), light_data->get_user_lightmap_texture_size(i));
}
} else {
VisualInstance3D *vi = Object::cast_to(node);
ERR_CONTINUE(!vi);
- RS::get_singleton()->instance_geometry_set_lightmap(vi->get_instance(), get_instance(), light_data->get_user_lightmap_uv_scale(i), light_data->get_user_lightmap_slice_index(i));
+ RS::get_singleton()->instance_geometry_set_lightmap(vi->get_instance(), get_instance(), light_data->get_user_lightmap_uv_scale(i), light_data->get_user_lightmap_slice_index(i), light_data->get_user_lightmap_texture_size(i));
}
}
}
@@ -1312,12 +1319,12 @@ void LightmapGI::_clear_lightmaps() {
if (instance_idx >= 0) {
RID instance_id = node->call("get_bake_mesh_instance", instance_idx);
if (instance_id.is_valid()) {
- RS::get_singleton()->instance_geometry_set_lightmap(instance_id, RID(), Rect2(), 0);
+ RS::get_singleton()->instance_geometry_set_lightmap(instance_id, RID(), Rect2(), 0, Vector2());
}
} else {
VisualInstance3D *vi = Object::cast_to(node);
ERR_CONTINUE(!vi);
- RS::get_singleton()->instance_geometry_set_lightmap(vi->get_instance(), RID(), Rect2(), 0);
+ RS::get_singleton()->instance_geometry_set_lightmap(vi->get_instance(), RID(), Rect2(), 0, Vector2());
}
}
}
diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h
index b9e33cf30044..20e8788a3bb0 100644
--- a/scene/3d/lightmap_gi.h
+++ b/scene/3d/lightmap_gi.h
@@ -56,6 +56,7 @@ class LightmapGIData : public Resource {
NodePath path;
int32_t sub_instance = 0;
Rect2 uv_scale;
+ Vector2 texture_size;
int slice_index = 0;
};
@@ -72,12 +73,13 @@ class LightmapGIData : public Resource {
static void _bind_methods();
public:
- void add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance = -1);
+ void add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance = -1, const Vector2 &p_texture_size = Vector2());
int get_user_count() const;
NodePath get_user_path(int p_user) const;
int32_t get_user_sub_instance(int p_user) const;
Rect2 get_user_lightmap_uv_scale(int p_user) const;
int get_user_lightmap_slice_index(int p_user) const;
+ Vector2 get_user_lightmap_texture_size(int p_user) const;
void clear_users();
void set_light_texture(const Ref &p_light_texture);
diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h
index 965d837ea80e..e317d1dedb2c 100644
--- a/servers/rendering/dummy/rasterizer_scene_dummy.h
+++ b/servers/rendering/dummy/rasterizer_scene_dummy.h
@@ -57,7 +57,7 @@ class RasterizerSceneDummy : public RendererSceneRender {
virtual void set_transparency(float p_transparency) override {}
virtual void set_use_baked_light(bool p_enable) override {}
virtual void set_use_dynamic_gi(bool p_enable) override {}
- virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override {}
+ virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index, const Vector2 &p_lightmap_texture_size) override {}
virtual void set_lightmap_capture(const Color *p_sh9) override {}
virtual void set_instance_shader_uniforms_offset(int32_t p_offset) override {}
virtual void set_cast_double_sided_shadows(bool p_enable) override {}
diff --git a/servers/rendering/renderer_geometry_instance.h b/servers/rendering/renderer_geometry_instance.h
index 600c52639645..2c25559f073f 100644
--- a/servers/rendering/renderer_geometry_instance.h
+++ b/servers/rendering/renderer_geometry_instance.h
@@ -58,7 +58,7 @@ class RenderGeometryInstance {
virtual void set_transparency(float p_transparency) = 0;
virtual void set_use_baked_light(bool p_enable) = 0;
virtual void set_use_dynamic_gi(bool p_enable) = 0;
- virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0;
+ virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index, const Vector2 &p_lightmap_texture_size) = 0;
virtual void set_lightmap_capture(const Color *p_sh9) = 0;
virtual void set_instance_shader_uniforms_offset(int32_t p_offset) = 0;
virtual void set_cast_double_sided_shadows(bool p_enable) = 0;
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index eea891792a07..abd546a9641f 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -745,6 +745,8 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i
instance_data.lightmap_uv_scale[1] = inst->lightmap_uv_scale.position.y;
instance_data.lightmap_uv_scale[2] = inst->lightmap_uv_scale.size.x;
instance_data.lightmap_uv_scale[3] = inst->lightmap_uv_scale.size.y;
+ instance_data.lightmap_texture_size[0] = inst->lightmap_texture_size.x;
+ instance_data.lightmap_texture_size[1] = inst->lightmap_texture_size.y;
bool cant_repeat = instance_data.flags & INSTANCE_DATA_FLAG_MULTIMESH || inst->mesh_instance.is_valid();
@@ -3814,9 +3816,10 @@ void RenderForwardClustered::GeometryInstanceForwardClustered::set_transform(con
RenderGeometryInstanceBase::set_transform(p_transform, p_aabb, p_transformed_aabbb);
}
-void RenderForwardClustered::GeometryInstanceForwardClustered::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
+void RenderForwardClustered::GeometryInstanceForwardClustered::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index, const Vector2 &p_lightmap_texture_size) {
lightmap_instance = p_lightmap_instance;
lightmap_uv_scale = p_lightmap_uv_scale;
+ lightmap_texture_size = p_lightmap_texture_size;
lightmap_slice_index = p_lightmap_slice_index;
_mark_dirty();
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
index 7ab9e67bac4d..5e5b9fd93bfc 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -297,6 +297,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index)
uint32_t layer_mask;
float lightmap_uv_scale[4];
+ float lightmap_texture_size[2];
};
UBO ubo;
@@ -448,6 +449,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
// lightmap
RID lightmap_instance;
Rect2 lightmap_uv_scale;
+ Vector2 lightmap_texture_size; // Used for bicubic filtering in the scene shader.
uint32_t lightmap_slice_index;
GeometryInstanceLightmapSH *lightmap_sh = nullptr;
@@ -476,7 +478,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
virtual void _mark_dirty() override;
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override;
- virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
+ virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index, const Vector2 &p_lightmap_texture_size) override;
virtual void set_lightmap_capture(const Color *p_sh9) override;
virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override {}
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 0b4157c5d63d..a315f82e6d9f 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -2264,9 +2264,10 @@ RenderGeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base
return ginstance;
}
-void RenderForwardMobile::GeometryInstanceForwardMobile::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
+void RenderForwardMobile::GeometryInstanceForwardMobile::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index, const Vector2 &p_lightmap_texture_size) {
lightmap_instance = p_lightmap_instance;
lightmap_uv_scale = p_lightmap_uv_scale;
+ lightmap_texture_size = p_lightmap_texture_size;
lightmap_slice_index = p_lightmap_slice_index;
_mark_dirty();
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
index 214b39c49666..7dd6b419f50b 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -480,6 +480,7 @@ class RenderForwardMobile : public RendererSceneRenderRD {
uint32_t gi_offset_cache = 0; // !BAS! Should rename this to lightmap_offset_cache, in forward clustered this was shared between gi and lightmap
RID lightmap_instance;
Rect2 lightmap_uv_scale;
+ Vector2 lightmap_texture_size; // Used for bicubic filtering in the scene shader.
uint32_t lightmap_slice_index;
GeometryInstanceLightmapSH *lightmap_sh = nullptr;
@@ -503,7 +504,7 @@ class RenderForwardMobile : public RendererSceneRenderRD {
virtual void _mark_dirty() override;
- virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
+ virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index, const Vector2 &p_lightmap_texture_size) override;
virtual void set_lightmap_capture(const Color *p_sh9) override;
virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override;
diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
index cec54a2c5f93..a7bc97d73805 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
@@ -545,6 +545,68 @@ layout(location = 9) in float dp_clip;
layout(location = 10) in flat uint instance_index_interp;
+// #ifdef USE_LIGHTMAP_FILTER_BICUBIC
+
+// w0, w1, w2, and w3 are the four cubic B-spline basis functions
+float w0(float a) {
+ return (1.0 / 6.0) * (a * (a * (-a + 3.0) - 3.0) + 1.0);
+}
+
+float w1(float a) {
+ return (1.0 / 6.0) * (a * a * (3.0 * a - 6.0) + 4.0);
+}
+
+float w2(float a) {
+ return (1.0 / 6.0) * (a * (a * (-3.0 * a + 3.0) + 3.0) + 1.0);
+}
+
+float w3(float a) {
+ return (1.0 / 6.0) * (a * a * a);
+}
+
+// g0 and g1 are the two amplitude functions
+float g0(float a) {
+ return w0(a) + w1(a);
+}
+
+float g1(float a) {
+ return w2(a) + w3(a);
+}
+
+// h0 and h1 are the two offset functions
+float h0(float a) {
+ return -1.0 + w1(a) / (w0(a) + w1(a));
+}
+
+float h1(float a) {
+ return 1.0 + w3(a) / (w2(a) + w3(a));
+}
+
+vec4 textureArray_bicubic(texture2DArray tex, vec3 uv, vec2 texture_size) {
+ // FIXME: Don't hardcode lightmap texture size and pass it via an uniform instead.
+ vec2 texel_size = vec2(1.0) / texture_size;
+
+ uv.xy = uv.xy * texture_size + vec2(0.5);
+
+ vec2 iuv = floor(uv.xy);
+ vec2 fuv = fract(uv.xy);
+
+ float g0x = g0(fuv.x);
+ float g1x = g1(fuv.x);
+ float h0x = h0(fuv.x);
+ float h1x = h1(fuv.x);
+ float h0y = h0(fuv.y);
+ float h1y = h1(fuv.y);
+
+ vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5)) * texel_size;
+ vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5)) * texel_size;
+ vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5)) * texel_size;
+ vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5)) * texel_size;
+
+ return (g0(fuv.y) * (g0x * texture(sampler2DArray(tex, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(p0, uv.z)) + g1x * texture(sampler2DArray(tex, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(p1, uv.z)))) +
+ (g1(fuv.y) * (g0x * texture(sampler2DArray(tex, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(p2, uv.z)) + g1x * texture(sampler2DArray(tex, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(p3, uv.z))));
+}
+
#ifdef USE_MULTIVIEW
#ifdef has_VK_KHR_multiview
#define ViewIndex gl_ViewIndex
@@ -1209,10 +1271,10 @@ void fragment_shader(in SceneData scene_data) {
if (uses_sh) {
uvw.z *= 4.0; //SH textures use 4 times more data
- vec3 lm_light_l0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb;
- vec3 lm_light_l1n1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb;
- vec3 lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb;
- vec3 lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb;
+ vec3 lm_light_l0 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 0.0), instances.data[instance_index].lightmap_texture_size).rgb;
+ vec3 lm_light_l1n1 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 1.0), instances.data[instance_index].lightmap_texture_size).rgb;
+ vec3 lm_light_l1_0 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 2.0), instances.data[instance_index].lightmap_texture_size).rgb;
+ vec3 lm_light_l1p1 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 3.0), instances.data[instance_index].lightmap_texture_size).rgb;
uint idx = instances.data[instance_index].gi_offset >> 20;
vec3 n = normalize(lightmaps.data[idx].normal_xform * normal);
@@ -1231,7 +1293,7 @@ void fragment_shader(in SceneData scene_data) {
} else {
uint idx = instances.data[instance_index].gi_offset >> 20;
- ambient_light += textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw, 0.0).rgb * lightmaps.data[idx].exposure_normalization;
+ ambient_light += textureArray_bicubic(lightmap_textures[ofs], uvw, instances.data[instance_index].lightmap_texture_size).rgb * lightmaps.data[idx].exposure_normalization;
}
}
#else
diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl
index 043bba1e4ebe..833d3b74cb24 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl
@@ -224,6 +224,7 @@ struct InstanceData {
uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
uint layer_mask;
vec4 lightmap_uv_scale;
+ vec2 lightmap_texture_size; // Used for bicubic filtering in the scene shader.
};
layout(set = 1, binding = 2, std430) buffer restrict readonly InstanceDataBuffer {
diff --git a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
index b57ee1852175..eaef194a5dde 100644
--- a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
@@ -64,6 +64,4 @@ struct SceneData {
bool pancake_shadows;
uint camera_visible_layers;
- uint pad2;
- uint pad3;
};
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index c5eabba326ce..e08bc26453ca 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -564,7 +564,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
InstanceLightmapData *lightmap_data = static_cast(instance->base_data);
//erase dependencies, since no longer a lightmap
while (lightmap_data->users.begin()) {
- instance_geometry_set_lightmap((*lightmap_data->users.begin())->self, RID(), Rect2(), 0);
+ instance_geometry_set_lightmap((*lightmap_data->users.begin())->self, RID(), Rect2(), 0, Vector2());
}
RSG::light_storage->lightmap_instance_free(lightmap_data->instance);
} break;
@@ -651,7 +651,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
geom->geometry_instance->set_transparency(instance->transparency);
geom->geometry_instance->set_use_baked_light(instance->baked_light);
geom->geometry_instance->set_use_dynamic_gi(instance->dynamic_gi);
- geom->geometry_instance->set_use_lightmap(RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index);
+ geom->geometry_instance->set_use_lightmap(RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index, instance->lightmap_texture_size);
geom->geometry_instance->set_instance_shader_uniforms_offset(instance->instance_allocated_shader_uniforms_offset);
geom->geometry_instance->set_cast_double_sided_shadows(instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
if (instance->lightmap_sh.size() == 9) {
@@ -1423,7 +1423,7 @@ void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_ins
}
}
-void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) {
+void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index, const Vector2 &p_lightmap_texture_size) {
Instance *instance = instance_owner.get_or_null(p_instance);
ERR_FAIL_COND(!instance);
@@ -1438,6 +1438,7 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig
instance->lightmap = lightmap_instance;
instance->lightmap_uv_scale = p_lightmap_uv_scale;
instance->lightmap_slice_index = p_slice_index;
+ instance->lightmap_texture_size = p_lightmap_texture_size;
RID lightmap_instance_rid;
@@ -1450,7 +1451,7 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
InstanceGeometryData *geom = static_cast(instance->base_data);
ERR_FAIL_NULL(geom->geometry_instance);
- geom->geometry_instance->set_use_lightmap(lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index);
+ geom->geometry_instance->set_use_lightmap(lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index, p_lightmap_texture_size);
}
}
@@ -4053,7 +4054,7 @@ bool RendererSceneCull::free(RID p_rid) {
Instance *instance = instance_owner.get_or_null(p_rid);
- instance_geometry_set_lightmap(p_rid, RID(), Rect2(), 0);
+ instance_geometry_set_lightmap(p_rid, RID(), Rect2(), 0, Vector2());
instance_set_scenario(p_rid, RID());
instance_set_base(p_rid, RID());
instance_geometry_set_material_override(p_rid, RID());
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index 4745c3d1d3ac..ea45fa0168d5 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -412,6 +412,7 @@ class RendererSceneCull : public RenderingMethod {
Instance *lightmap = nullptr;
Rect2 lightmap_uv_scale;
+ Vector2 lightmap_texture_size; // Used for bicubic filtering in the scene shader.
int lightmap_slice_index;
uint32_t lightmap_cull_index;
Vector lightmap_sh; //spherical harmonic
@@ -993,7 +994,7 @@ class RendererSceneCull : public RenderingMethod {
virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, RS::VisibilityRangeFadeMode p_fade_mode);
- virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index);
+ virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index, const Vector2 &p_lightmap_texture_size = Vector2());
virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias);
void _update_instance_shader_uniforms_from_material(HashMap &isparams, const HashMap &existing_isparams, RID p_material);
diff --git a/servers/rendering/rendering_method.h b/servers/rendering/rendering_method.h
index f705603a1cbc..a3727a7ecb76 100644
--- a/servers/rendering/rendering_method.h
+++ b/servers/rendering/rendering_method.h
@@ -100,7 +100,7 @@ class RenderingMethod {
virtual void instance_geometry_set_material_overlay(RID p_instance, RID p_material) = 0;
virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, RS::VisibilityRangeFadeMode p_fade_mode) = 0;
- virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) = 0;
+ virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index, const Vector2 &p_lightmap_texture_size = Vector2()) = 0;
virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0;
virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) = 0;
virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List *p_parameters) const = 0;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 797fe73ba037..f219f499d8a1 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -792,7 +792,7 @@ class RenderingServerDefault : public RenderingServer {
FUNC2(instance_geometry_set_material_overlay, RID, RID)
FUNC6(instance_geometry_set_visibility_range, RID, float, float, float, float, VisibilityRangeFadeMode)
- FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
+ FUNC5(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int, const Vector2 &)
FUNC2(instance_geometry_set_lod_bias, RID, float)
FUNC2(instance_geometry_set_transparency, RID, float)
FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 4d41343ff853..9e7754713bdf 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2511,7 +2511,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("instance_geometry_set_material_override", "instance", "material"), &RenderingServer::instance_geometry_set_material_override);
ClassDB::bind_method(D_METHOD("instance_geometry_set_material_overlay", "instance", "material"), &RenderingServer::instance_geometry_set_material_overlay);
ClassDB::bind_method(D_METHOD("instance_geometry_set_visibility_range", "instance", "min", "max", "min_margin", "max_margin", "fade_mode"), &RenderingServer::instance_geometry_set_visibility_range);
- ClassDB::bind_method(D_METHOD("instance_geometry_set_lightmap", "instance", "lightmap", "lightmap_uv_scale", "lightmap_slice"), &RenderingServer::instance_geometry_set_lightmap);
+ ClassDB::bind_method(D_METHOD("instance_geometry_set_lightmap", "instance", "lightmap", "lightmap_uv_scale", "lightmap_slice", "lightmap_texture_size"), &RenderingServer::instance_geometry_set_lightmap, DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("instance_geometry_set_lod_bias", "instance", "lod_bias"), &RenderingServer::instance_geometry_set_lod_bias);
ClassDB::bind_method(D_METHOD("instance_geometry_set_shader_parameter", "instance", "parameter", "value"), &RenderingServer::instance_geometry_set_shader_parameter);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index deac2a59f92e..d70628584dce 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -1271,7 +1271,7 @@ class RenderingServer : public Object {
virtual void instance_geometry_set_material_override(RID p_instance, RID p_material) = 0;
virtual void instance_geometry_set_material_overlay(RID p_instance, RID p_material) = 0;
virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, VisibilityRangeFadeMode p_fade_mode) = 0;
- virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice) = 0;
+ virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice, const Vector2 &p_lightmap_texture_size = Vector2()) = 0;
virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0;
virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency) = 0;