Skip to content

Commit e21747c

Browse files
committed
LightmapGI: Save directional lightmaps as ldr textures
1 parent 31476ef commit e21747c

File tree

22 files changed

+416
-137
lines changed

22 files changed

+416
-137
lines changed

doc/classes/LightmapGIData.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
</method>
5555
</methods>
5656
<members>
57+
<member name="directional_textures" type="TextureLayered[]" setter="set_directional_textures" getter="get_directional_textures" default="[]">
58+
The directional atlas textures generated by the lightmapper.
59+
</member>
5760
<member name="light_texture" type="TextureLayered" setter="set_light_texture" getter="get_light_texture" deprecated="The lightmap atlas can now contain multiple textures. See [member lightmap_textures].">
5861
The lightmap atlas texture generated by the lightmapper.
5962
</member>

drivers/gles3/rasterizer_scene_gles3.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,14 +2681,14 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
26812681
glBlitFramebuffer(0, 0, size.x, size.y,
26822682
0, 0, size.x, size.y,
26832683
GL_COLOR_BUFFER_BIT, GL_NEAREST);
2684-
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 6);
2684+
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 7);
26852685
glBindTexture(GL_TEXTURE_2D, backbuffer);
26862686
}
26872687
if (scene_state.used_depth_texture) {
26882688
glBlitFramebuffer(0, 0, size.x, size.y,
26892689
0, 0, size.x, size.y,
26902690
GL_DEPTH_BUFFER_BIT, GL_NEAREST);
2691-
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 7);
2691+
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 8);
26922692
glBindTexture(GL_TEXTURE_2D, backbuffer_depth);
26932693
}
26942694
}
@@ -3398,6 +3398,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
33983398
material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_TEXTURE_SIZE, light_texture_size, shader->version, instance_variant, spec_constants);
33993399
}
34003400

3401+
// Shadowmasks
34013402
material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_SHADOWMASK_MODE, (uint32_t)lm->shadowmask_mode, shader->version, instance_variant, spec_constants);
34023403

34033404
if (lm->shadow_texture.is_valid()) {
@@ -3408,6 +3409,16 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
34083409

34093410
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 5);
34103411
glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
3412+
3413+
// Directional
3414+
if (lm->directional_texture.is_valid()) {
3415+
tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(lm->directional_texture);
3416+
} else {
3417+
tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(GLES3::TextureStorage::get_singleton()->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE));
3418+
}
3419+
3420+
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 6);
3421+
glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
34113422
}
34123423
}
34133424
}
@@ -3500,7 +3511,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
35003511
material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_LOCAL_MATRIX, inst->reflection_probes_local_transform_cache[0], shader->version, instance_variant, spec_constants);
35013512
material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_BLEND_DISTANCE, probe->blend_distance, shader->version, instance_variant, spec_constants);
35023513

3503-
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 8);
3514+
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 9);
35043515
glBindTexture(GL_TEXTURE_CUBE_MAP, light_storage->reflection_probe_instance_get_texture(inst->reflection_probe_rid_cache[0]));
35053516
}
35063517

@@ -3519,7 +3530,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
35193530
material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_LOCAL_MATRIX, inst->reflection_probes_local_transform_cache[1], shader->version, instance_variant, spec_constants);
35203531
material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_BLEND_DISTANCE, probe->blend_distance, shader->version, instance_variant, spec_constants);
35213532

3522-
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 9);
3533+
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 10);
35233534
glBindTexture(GL_TEXTURE_CUBE_MAP, light_storage->reflection_probe_instance_get_texture(inst->reflection_probe_rid_cache[1]));
35243535

35253536
spec_constants |= SceneShaderGLES3::SECOND_REFLECTION_PROBE;

drivers/gles3/shaders/scene.glsl

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -836,10 +836,11 @@ void main() {
836836
3-shadow
837837
4-lightmap textures
838838
5-shadowmask textures
839-
6-screen
840-
7-depth
841-
8-reflection probe 1
842-
9-reflection probe 2
839+
6-directional textures
840+
7-screen
841+
8-depth
842+
9-reflection probe 1
843+
10-reflection probe 2
843844
844845
*/
845846

@@ -921,7 +922,7 @@ uniform float refprobe1_blend_distance;
921922
uniform int refprobe1_ambient_mode;
922923
uniform vec4 refprobe1_ambient_color;
923924

924-
uniform samplerCube refprobe1_texture; // texunit:-8
925+
uniform samplerCube refprobe1_texture; // texunit:-9
925926

926927
#ifdef SECOND_REFLECTION_PROBE
927928

@@ -935,7 +936,7 @@ uniform float refprobe2_blend_distance;
935936
uniform int refprobe2_ambient_mode;
936937
uniform vec4 refprobe2_ambient_color;
937938

938-
uniform samplerCube refprobe2_texture; // texunit:-9
939+
uniform samplerCube refprobe2_texture; // texunit:-10
939940

940941
#endif // SECOND_REFLECTION_PROBE
941942

@@ -1210,6 +1211,7 @@ float sample_shadow(highp sampler2DShadow shadow, float shadow_pixel_size, vec4
12101211
#ifdef USE_LIGHTMAP
12111212
uniform mediump sampler2DArray lightmap_textures; //texunit:-4
12121213
uniform lowp sampler2DArray shadowmask_textures; //texunit:-5
1214+
uniform mediump sampler2DArray directional_textures; //texunit:-6
12131215
uniform lowp uint lightmap_slice;
12141216
uniform highp vec4 lightmap_uv_scale;
12151217
uniform float lightmap_exposure_normalization;
@@ -1235,17 +1237,17 @@ uniform mediump vec4[9] lightmap_captures;
12351237
#endif // !DISABLE_LIGHTMAP
12361238

12371239
#ifdef USE_MULTIVIEW
1238-
uniform highp sampler2DArray depth_buffer; // texunit:-7
1239-
uniform highp sampler2DArray color_buffer; // texunit:-6
1240+
uniform highp sampler2DArray depth_buffer; // texunit:-8
1241+
uniform highp sampler2DArray color_buffer; // texunit:-7
12401242
vec3 multiview_uv(vec2 uv) {
12411243
return vec3(uv, ViewIndex);
12421244
}
12431245
ivec3 multiview_uv(ivec2 uv) {
12441246
return ivec3(uv, int(ViewIndex));
12451247
}
12461248
#else
1247-
uniform highp sampler2D depth_buffer; // texunit:-7
1248-
uniform highp sampler2D color_buffer; // texunit:-6
1249+
uniform highp sampler2D depth_buffer; // texunit:-8
1250+
uniform highp sampler2D color_buffer; // texunit:-7
12491251
vec2 multiview_uv(vec2 uv) {
12501252
return uv;
12511253
}
@@ -2109,23 +2111,19 @@ void main() {
21092111
#else
21102112
#ifdef USE_LIGHTMAP
21112113
{
2112-
vec3 uvw;
2113-
uvw.xy = uv2 * lightmap_uv_scale.zw + lightmap_uv_scale.xy;
2114-
uvw.z = float(lightmap_slice);
2114+
vec3 uvw = vec3(uv2 * lightmap_uv_scale.zw + lightmap_uv_scale.xy, float(lightmap_slice));
21152115

21162116
#ifdef USE_SH_LIGHTMAP
2117-
uvw.z *= 4.0; // SH textures use 4 times more data.
2118-
21192117
#ifdef LIGHTMAP_BICUBIC_FILTER
2120-
vec3 lm_light_l0 = textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 0.0), lightmap_texture_size).rgb;
2121-
vec3 lm_light_l1n1 = (textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 1.0), lightmap_texture_size).rgb - vec3(0.5)) * 2.0;
2122-
vec3 lm_light_l1_0 = (textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 2.0), lightmap_texture_size).rgb - vec3(0.5)) * 2.0;
2123-
vec3 lm_light_l1p1 = (textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 3.0), lightmap_texture_size).rgb - vec3(0.5)) * 2.0;
2118+
vec3 lm_light_l0 = textureArray_bicubic(lightmap_textures, uvw, lightmap_texture_size).rgb;
2119+
vec3 lm_light_l1n1 = (textureArray_bicubic(directional_textures, vec3(uvw.xy, uvw.z * 3 + 0.0), lightmap_texture_size).rgb - vec3(0.5)) * 2.0;
2120+
vec3 lm_light_l1_0 = (textureArray_bicubic(directional_textures, vec3(uvw.xy, uvw.z * 3 + 1.0), lightmap_texture_size).rgb - vec3(0.5)) * 2.0;
2121+
vec3 lm_light_l1p1 = (textureArray_bicubic(directional_textures, vec3(uvw.xy, uvw.z * 3 + 2.0), lightmap_texture_size).rgb - vec3(0.5)) * 2.0;
21242122
#else
2125-
vec3 lm_light_l0 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb;
2126-
vec3 lm_light_l1n1 = (textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb - vec3(0.5)) * 2.0;
2127-
vec3 lm_light_l1_0 = (textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb - vec3(0.5)) * 2.0;
2128-
vec3 lm_light_l1p1 = (textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb - vec3(0.5)) * 2.0;
2123+
vec3 lm_light_l0 = textureLod(lightmap_textures, uvw, 0.0).rgb;
2124+
vec3 lm_light_l1n1 = (textureLod(directional_textures, vec3(uvw.xy, uvw.z * 3 + 0.0), 0.0).rgb - vec3(0.5)) * 2.0;
2125+
vec3 lm_light_l1_0 = (textureLod(directional_textures, vec3(uvw.xy, uvw.z * 3 + 1.0), 0.0).rgb - vec3(0.5)) * 2.0;
2126+
vec3 lm_light_l1p1 = (textureLod(directional_textures, vec3(uvw.xy, uvw.z * 3 + 2.0), 0.0).rgb - vec3(0.5)) * 2.0;
21292127
#endif
21302128

21312129
vec3 n = normalize(lightmap_normal_xform * normal);

drivers/gles3/storage/light_storage.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,20 @@ void LightStorage::lightmap_set_shadowmask_mode(RID p_lightmap, RS::ShadowmaskMo
12371237
lightmap->shadowmask_mode = p_mode;
12381238
}
12391239

1240+
void LightStorage::lightmap_set_directional_textures(RID p_lightmap, RID p_directional) {
1241+
Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);
1242+
ERR_FAIL_NULL(lightmap);
1243+
lightmap->directional_texture = p_directional;
1244+
1245+
GLuint tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(lightmap->directional_texture);
1246+
glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
1247+
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1248+
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1249+
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1250+
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1251+
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
1252+
}
1253+
12401254
/* LIGHTMAP INSTANCE */
12411255

12421256
RID LightStorage::lightmap_instance_create(RID p_lightmap) {

drivers/gles3/storage/light_storage.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ struct ReflectionProbeInstance {
176176
struct Lightmap {
177177
RID light_texture;
178178
RID shadow_texture;
179+
RID directional_texture;
179180
bool uses_spherical_harmonics = false;
180181
bool interior = false;
181182
AABB bounds = AABB(Vector3(), Vector3(1, 1, 1));
@@ -740,6 +741,8 @@ class LightStorage : public RendererLightStorage {
740741
virtual RS::ShadowmaskMode lightmap_get_shadowmask_mode(RID p_lightmap) override;
741742
virtual void lightmap_set_shadowmask_mode(RID p_lightmap, RS::ShadowmaskMode p_mode) override;
742743

744+
virtual void lightmap_set_directional_textures(RID p_lightmap, RID p_directional) override;
745+
743746
/* LIGHTMAP INSTANCE */
744747

745748
LightmapInstance *get_lightmap_instance(RID p_rid) { return lightmap_instance_owner.get_or_null(p_rid); }

modules/lightmapper_rd/lightmapper_rd.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
10681068
}
10691069
lightmap_textures.clear();
10701070
shadowmask_textures.clear();
1071+
directional_textures.clear();
10711072
int grid_size = 128;
10721073

10731074
/* STEP 1: Fetch material textures and compute the bounds */
@@ -2102,7 +2103,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
21022103
}
21032104

21042105
#ifdef DEBUG_TEXTURES
2105-
21062106
for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
21072107
Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i);
21082108
Ref<Image> img = Image::create_from_data(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
@@ -2268,7 +2268,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
22682268
}
22692269

22702270
#ifdef DEBUG_TEXTURES
2271-
22722271
for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
22732272
Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i);
22742273
Ref<Image> img = Image::create_from_data(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
@@ -2280,14 +2279,16 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
22802279
p_step_function(0.9, RTR("Retrieving textures"), p_bake_userdata, true);
22812280
}
22822281

2283-
for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
2284-
Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i);
2282+
// Retrieve lightmaps.
2283+
for (int i = 0; i < atlas_slices; i++) {
2284+
Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, p_bake_sh ? i * 4 : i);
22852285
Ref<Image> img = Image::create_from_data(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
2286-
img->convert(Image::FORMAT_RGBH); //remove alpha
2286+
img->convert(Image::FORMAT_RGBH); // Remove alpha.
22872287
lightmap_textures.push_back(img);
22882288
}
22892289

22902290
if (p_bake_shadowmask) {
2291+
// Retrieve shadowmasks.
22912292
for (int i = 0; i < atlas_slices; i++) {
22922293
Vector<uint8_t> s = rd->texture_get_data(shadowmask_tex, i);
22932294
Ref<Image> img = Image::create_from_data(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBA8, s);
@@ -2296,6 +2297,18 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
22962297
}
22972298
}
22982299

2300+
if (p_bake_sh) {
2301+
// Retrieve directional.
2302+
for (int i = 0; i < atlas_slices; i++) {
2303+
for (int j = 1; j < 4; j++) {
2304+
Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i * 4 + j);
2305+
Ref<Image> img = Image::create_from_data(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
2306+
img->convert(Image::FORMAT_RGB8);
2307+
directional_textures.push_back(img);
2308+
}
2309+
}
2310+
}
2311+
22992312
if (probe_positions.size() > 0) {
23002313
probe_values.resize(probe_positions.size() * 9);
23012314
Vector<uint8_t> probe_data = rd->buffer_get_data(light_probe_buffer);
@@ -2343,6 +2356,15 @@ Ref<Image> LightmapperRD::get_shadowmask_texture(int p_index) const {
23432356
return shadowmask_textures[p_index];
23442357
}
23452358

2359+
int LightmapperRD::get_directional_texture_count() const {
2360+
return directional_textures.size();
2361+
}
2362+
2363+
Ref<Image> LightmapperRD::get_directional_texture(int p_index) const {
2364+
ERR_FAIL_INDEX_V(p_index, directional_textures.size(), Ref<Image>());
2365+
return directional_textures[p_index];
2366+
}
2367+
23462368
int LightmapperRD::get_bake_mesh_count() const {
23472369
return mesh_instances.size();
23482370
}

modules/lightmapper_rd/lightmapper_rd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ class LightmapperRD : public Lightmapper {
257257

258258
Vector<Ref<Image>> lightmap_textures;
259259
Vector<Ref<Image>> shadowmask_textures;
260+
Vector<Ref<Image>> directional_textures;
260261
Vector<Color> probe_values;
261262

262263
struct DilateParams {
@@ -299,6 +300,9 @@ class LightmapperRD : public Lightmapper {
299300
Ref<Image> get_bake_texture(int p_index) const override;
300301
int get_shadowmask_texture_count() const override;
301302
Ref<Image> get_shadowmask_texture(int p_index) const override;
303+
int get_directional_texture_count() const override;
304+
Ref<Image> get_directional_texture(int p_index) const override;
305+
302306
int get_bake_mesh_count() const override;
303307
Variant get_bake_mesh_userdata(int p_index) const override;
304308
Rect2 get_bake_mesh_uv_scale(int p_index) const override;

0 commit comments

Comments
 (0)