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;