1
0
Fork 0
This commit is contained in:
Rudolph Bester 2025-02-28 01:36:38 +01:00 committed by GitHub
commit d5948d0d00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 81 additions and 77 deletions

View File

@ -812,34 +812,34 @@ LightmapperRD::BakeError LightmapperRD::_dilate(RenderingDevice *rd, Ref<RDShade
return BAKE_OK;
}
LightmapperRD::BakeError LightmapperRD::_pack_l1(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices) {
Vector<RD::Uniform> uniforms = dilate_or_denoise_common_uniforms(source_light_tex, dest_light_tex);
RID compute_shader_pack = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("pack_coeffs"));
ERR_FAIL_COND_V(compute_shader_pack.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
RID compute_shader_pack_pipeline = rd->compute_pipeline_create(compute_shader_pack);
RID dilate_uniform_set = rd->uniform_set_create(uniforms, compute_shader_pack, 1);
RD::ComputeListID compute_list = rd->compute_list_begin();
rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_pack_pipeline);
rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
rd->compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1);
push_constant.region_ofs[0] = 0;
push_constant.region_ofs[1] = 0;
Vector3i group_size(Math::division_round_up(atlas_size.x, 8), Math::division_round_up(atlas_size.y, 8), 1); //restore group size
for (int i = 0; i < atlas_slices; i++) {
push_constant.atlas_slice = i;
rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z);
//no barrier, let them run all together
}
rd->compute_list_end();
rd->free(compute_shader_pack);
return BAKE_OK;
}
// LightmapperRD::BakeError LightmapperRD::_pack_l1(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices) {
// Vector<RD::Uniform> uniforms = dilate_or_denoise_common_uniforms(source_light_tex, dest_light_tex);
//
// RID compute_shader_pack = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("pack_coeffs"));
// ERR_FAIL_COND_V(compute_shader_pack.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
// RID compute_shader_pack_pipeline = rd->compute_pipeline_create(compute_shader_pack);
//
// RID dilate_uniform_set = rd->uniform_set_create(uniforms, compute_shader_pack, 1);
//
// RD::ComputeListID compute_list = rd->compute_list_begin();
// rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_pack_pipeline);
// rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
// rd->compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1);
// push_constant.region_ofs[0] = 0;
// push_constant.region_ofs[1] = 0;
// Vector3i group_size(Math::division_round_up(atlas_size.x, 8), Math::division_round_up(atlas_size.y, 8), 1); //restore group size
//
// for (int i = 0; i < atlas_slices; i++) {
// push_constant.atlas_slice = i;
// rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
// rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z);
// //no barrier, let them run all together
// }
// rd->compute_list_end();
// rd->free(compute_shader_pack);
//
// return BAKE_OK;
// }
Error LightmapperRD::_store_pfm(RenderingDevice *p_rd, RID p_atlas_tex, int p_index, const Size2i &p_atlas_size, const String &p_name, bool p_shadowmask) {
Vector<uint8_t> data = p_rd->texture_get_data(p_atlas_tex, p_index);
@ -2259,13 +2259,13 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
}
}
if (p_bake_sh) {
SWAP(light_accum_tex, light_accum_tex2);
BakeError error = _pack_l1(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices);
if (unlikely(error != BAKE_OK)) {
return error;
}
}
// if (p_bake_sh) {
// SWAP(light_accum_tex, light_accum_tex2);
// BakeError error = _pack_l1(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices);
// if (unlikely(error != BAKE_OK)) {
// return error;
// }
// }
#ifdef DEBUG_TEXTURES

View File

@ -282,7 +282,7 @@ class LightmapperRD : public Lightmapper {
BakeError _dilate(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices);
BakeError _denoise(RenderingDevice *p_rd, Ref<RDShaderFile> &p_compute_shader, const RID &p_compute_base_uniform_set, PushConstant &p_push_constant, RID p_source_light_tex, RID p_source_normal_tex, RID p_dest_light_tex, float p_denoiser_strength, int p_denoiser_range, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, BakeStepFunc p_step_function, void *p_bake_userdata);
BakeError _pack_l1(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices);
// BakeError _pack_l1(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices);
Error _store_pfm(RenderingDevice *p_rd, RID p_atlas_tex, int p_index, const Size2i &p_atlas_size, const String &p_name, bool p_shadowmask);
Ref<Image> _read_pfm(const String &p_name, bool p_shadowmask);

View File

@ -6,7 +6,7 @@ dilate = "#define MODE_DILATE";
unocclude = "#define MODE_UNOCCLUDE";
light_probes = "#define MODE_LIGHT_PROBES";
denoise = "#define MODE_DENOISE";
pack_coeffs = "#define MODE_PACK_L1_COEFFS";
//pack_coeffs = "#define MODE_PACK_L1_COEFFS";
#[compute]
@ -66,7 +66,7 @@ layout(rgba8, set = 1, binding = 5) uniform restrict writeonly image2DArray shad
layout(set = 1, binding = 5) uniform texture2D environment;
#endif
#if defined(MODE_DILATE) || defined(MODE_DENOISE) || defined(MODE_PACK_L1_COEFFS)
#if defined(MODE_DILATE) || defined(MODE_DENOISE) // || defined(MODE_PACK_L1_COEFFS)
layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2DArray dest_light;
layout(set = 1, binding = 1) uniform texture2DArray source_light;
#endif
@ -861,15 +861,19 @@ void main() {
light_for_texture += light;
#ifdef USE_SH_LIGHTMAPS
// These coefficients include the factored out SH evaluation, diffuse convolution, and final application, as well as the BRDF 1/PI and the spherical monte carlo factor.
// LO: 1/(2*sqrtPI) * 1/(2*sqrtPI) * PI * PI * 1/PI = 0.25
// L1: sqrt(3/(4*pi)) * sqrt(3/(4*pi)) * (PI*2/3) * (2 * PI) * 1/PI = 1.0
// Note: This only works because we aren't scaling, rotating, or combing harmonics, we are just directing applying them in the shader.
// Since we don't want to double attenuate the light we need to undo attenuation based on the surface
// normal before encoding it into SH coefficients
if (dot(normal, light_dir) > 0.0) {
light /= dot(normal, light_dir);
}
// Different coefficients are used because we are directly encoding point lights.
// L0: Zero is used since the lighting should be able to attenuate to zero (at 90 degrees)
// L1: 1 is to no increase or decrease the lights intensity. This should match dynamic lighting.
float c[4] = float[](
0.25, //l0
0, //l0
light_dir.y, //l1n1
light_dir.z, //l1n0
light_dir.z, //l1n0 (Should always be positive)
light_dir.x //l1p1
);

View File

@ -204,13 +204,13 @@ bool LightmapGIData::is_using_spherical_harmonics() const {
return uses_spherical_harmonics;
}
void LightmapGIData::_set_uses_packed_directional(bool p_enable) {
_uses_packed_directional = p_enable;
}
// void LightmapGIData::_set_uses_packed_directional(bool p_enable) {
// _uses_packed_directional = p_enable;
// }
bool LightmapGIData::_is_using_packed_directional() const {
return _uses_packed_directional;
}
// bool LightmapGIData::_is_using_packed_directional() const {
// return _uses_packed_directional;
// }
void LightmapGIData::update_shadowmask_mode(ShadowmaskMode p_mode) {
RS::get_singleton()->lightmap_set_shadowmask_mode(lightmap, (RS::ShadowmaskMode)p_mode);
@ -327,8 +327,8 @@ void LightmapGIData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_uses_spherical_harmonics", "uses_spherical_harmonics"), &LightmapGIData::set_uses_spherical_harmonics);
ClassDB::bind_method(D_METHOD("is_using_spherical_harmonics"), &LightmapGIData::is_using_spherical_harmonics);
ClassDB::bind_method(D_METHOD("_set_uses_packed_directional", "_uses_packed_directional"), &LightmapGIData::_set_uses_packed_directional);
ClassDB::bind_method(D_METHOD("_is_using_packed_directional"), &LightmapGIData::_is_using_packed_directional);
// ClassDB::bind_method(D_METHOD("_set_uses_packed_directional", "_uses_packed_directional"), &LightmapGIData::_set_uses_packed_directional);
// ClassDB::bind_method(D_METHOD("_is_using_packed_directional"), &LightmapGIData::_is_using_packed_directional);
ClassDB::bind_method(D_METHOD("add_user", "path", "uv_scale", "slice_index", "sub_instance"), &LightmapGIData::add_user);
ClassDB::bind_method(D_METHOD("get_user_count"), &LightmapGIData::get_user_count);
@ -343,7 +343,7 @@ void LightmapGIData::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uses_spherical_harmonics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_uses_spherical_harmonics", "is_using_spherical_harmonics");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "user_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_user_data", "_get_user_data");
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "probe_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_probe_data", "_get_probe_data");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "_uses_packed_directional", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_uses_packed_directional", "_is_using_packed_directional");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "_uses_packed_directional", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_uses_packed_directional", "_is_using_packed_directional");
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_light_texture", "light_texture"), &LightmapGIData::set_light_texture);
@ -807,7 +807,7 @@ void LightmapGI::_gen_new_positions_from_octree(const GenProbesOctree *p_cell, f
}
}
LightmapGI::BakeError LightmapGI::_save_and_reimport_atlas_textures(const Ref<Lightmapper> p_lightmapper, const String &p_base_name, TypedArray<TextureLayered> &r_textures, bool p_is_shadowmask) const {
LightmapGI::BakeError LightmapGI::_save_and_reimport_atlas_textures(const Ref<Lightmapper> p_lightmapper, const String &p_base_name, TypedArray<TextureLayered> &r_textures, bool p_is_shadowmask, bool p_compress) const {
Vector<Ref<Image>> images;
images.resize(p_is_shadowmask ? p_lightmapper->get_shadowmask_texture_count() : p_lightmapper->get_bake_texture_count());
@ -849,7 +849,7 @@ LightmapGI::BakeError LightmapGI::_save_and_reimport_atlas_textures(const Ref<Li
config->set_value("remap", "type", "CompressedTexture2DArray");
if (!config->has_section_key("params", "compress/mode")) {
// Do not override an existing compression mode.
config->set_value("params", "compress/mode", 2);
config->set_value("params", "compress/mode", p_compress ? 2 : 3);
}
config->set_value("params", "compress/channel_pack", 1);
config->set_value("params", "mipmaps/generate", false);
@ -1289,12 +1289,12 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
const bool save_shadowmask = shadowmask_mode != LightmapGIData::SHADOWMASK_MODE_NONE && shadowmask_texture_count > 0;
// Save the lightmap atlases.
BakeError save_err = _save_and_reimport_atlas_textures(lightmapper, texture_filename, lightmap_textures, false);
BakeError save_err = _save_and_reimport_atlas_textures(lightmapper, texture_filename, lightmap_textures, false, false);
ERR_FAIL_COND_V(save_err != BAKE_ERROR_OK, save_err);
if (save_shadowmask) {
// Save the shadowmask atlases.
save_err = _save_and_reimport_atlas_textures(lightmapper, texture_filename + "_shadow", shadowmask_textures, true);
save_err = _save_and_reimport_atlas_textures(lightmapper, texture_filename + "_shadow", shadowmask_textures, true, true);
ERR_FAIL_COND_V(save_err != BAKE_ERROR_OK, save_err);
}
@ -1319,7 +1319,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
}
gi_data->set_uses_spherical_harmonics(directional);
gi_data->_set_uses_packed_directional(directional); // New SH lightmaps are packed automatically.
// gi_data->_set_uses_packed_directional(directional); // New SH lightmaps are packed automatically.
for (int i = 0; i < lightmapper->get_bake_mesh_count(); i++) {
Dictionary d = lightmapper->get_bake_mesh_userdata(i);
@ -1485,12 +1485,12 @@ void LightmapGI::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_POST_ENTER_TREE: {
if (light_data.is_valid()) {
ERR_FAIL_COND_MSG(
light_data->is_using_spherical_harmonics() && !light_data->_is_using_packed_directional(),
vformat(
"%s (%s): The directional lightmap textures are stored in a format that isn't supported anymore. Please bake lightmaps again to make lightmaps display from this node again.",
get_light_data()->get_path(), get_name()));
// ERR_FAIL_COND_MSG(
// light_data->is_using_spherical_harmonics() && !light_data->_is_using_packed_directional(),
// vformat(
// "%s (%s): The directional lightmap textures are stored in a format that isn't supported anymore. Please bake lightmaps again to make lightmaps display from this node again.",
// get_light_data()->get_path(), get_name()));
//
if (last_owner && last_owner != get_owner()) {
light_data->clear_users();
}

View File

@ -64,7 +64,7 @@ private:
bool uses_spherical_harmonics = false;
bool interior = false;
bool _uses_packed_directional = false;
// bool _uses_packed_directional = false;
RID lightmap;
AABB bounds;
@ -110,8 +110,8 @@ public:
void set_uses_spherical_harmonics(bool p_enable);
bool is_using_spherical_harmonics() const;
void _set_uses_packed_directional(bool p_enable);
bool _is_using_packed_directional() const;
// void _set_uses_packed_directional(bool p_enable);
// bool _is_using_packed_directional() const;
void update_shadowmask_mode(ShadowmaskMode p_mode);
ShadowmaskMode get_shadowmask_mode() const;
@ -273,7 +273,7 @@ private:
void _plot_triangle_into_octree(GenProbesOctree *p_cell, float p_cell_size, const Vector3 *p_triangle);
void _gen_new_positions_from_octree(const GenProbesOctree *p_cell, float p_cell_size, const Vector<Vector3> &probe_positions, LocalVector<Vector3> &new_probe_positions, HashMap<Vector3i, bool> &positions_used, const AABB &p_bounds);
BakeError _save_and_reimport_atlas_textures(const Ref<Lightmapper> p_lightmapper, const String &p_base_name, TypedArray<TextureLayered> &r_textures, bool p_is_shadowmask = false) const;
BakeError _save_and_reimport_atlas_textures(const Ref<Lightmapper> p_lightmapper, const String &p_base_name, TypedArray<TextureLayered> &r_textures, bool p_is_shadowmask = false, bool p_compress = false) const;
protected:
void _validate_property(PropertyInfo &p_property) const;

View File

@ -1690,23 +1690,23 @@ void fragment_shader(in SceneData scene_data) {
if (sc_use_lightmap_bicubic_filter()) {
lm_light_l0 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 0.0), lightmaps.data[ofs].light_texture_size).rgb;
lm_light_l1n1 = (textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 1.0), lightmaps.data[ofs].light_texture_size).rgb - vec3(0.5)) * 2.0;
lm_light_l1_0 = (textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 2.0), lightmaps.data[ofs].light_texture_size).rgb - vec3(0.5)) * 2.0;
lm_light_l1p1 = (textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 3.0), lightmaps.data[ofs].light_texture_size).rgb - vec3(0.5)) * 2.0;
lm_light_l1n1 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 1.0), lightmaps.data[ofs].light_texture_size).rgb;
lm_light_l1_0 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 2.0), lightmaps.data[ofs].light_texture_size).rgb;
lm_light_l1p1 = textureArray_bicubic(lightmap_textures[ofs], uvw + vec3(0.0, 0.0, 3.0), lightmaps.data[ofs].light_texture_size).rgb;
} else {
lm_light_l0 = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb;
lm_light_l1n1 = (textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb - vec3(0.5)) * 2.0;
lm_light_l1_0 = (textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb - vec3(0.5)) * 2.0;
lm_light_l1p1 = (textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb - vec3(0.5)) * 2.0;
lm_light_l1n1 = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb;
lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb;
lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb;
}
vec3 n = normalize(lightmaps.data[ofs].normal_xform * normal);
float en = lightmaps.data[ofs].exposure_normalization;
ambient_light += lm_light_l0 * en;
ambient_light += lm_light_l1n1 * n.y * (lm_light_l0 * en * 4.0);
ambient_light += lm_light_l1_0 * n.z * (lm_light_l0 * en * 4.0);
ambient_light += lm_light_l1p1 * n.x * (lm_light_l0 * en * 4.0);
ambient_light += lm_light_l1n1 * n.y * en;
ambient_light += lm_light_l1_0 * n.z * en;
ambient_light += lm_light_l1p1 * n.x * en;
} else {
if (sc_use_lightmap_bicubic_filter()) {