EEVEE: Light probe resolution

EEVEE stores light probes using octahedral mapping. Compared to the previous
cubemap storage octahedral has less pixels. The 64x64 is becoming useless
and can be removed. This PR also enables generating light probe maps upto 4k.

Some issues were found: the offset of the sphere inside the atlas
was always set to mipmap level 0 offset. This was hidden because of the texture
wrapping. Also the offset was substracted from the local texture
coordinate when calculating the direction of the pixel. Might be that due
to the incorrect offset (mipmap level 0), the latter issue was never detected.

Pull Request: https://projects.blender.org/blender/blender/pulls/123074
This commit is contained in:
Jeroen Bakker 2024-06-20 15:02:11 +02:00
parent 1fe4279bba
commit 55d75a1de3
8 changed files with 26 additions and 15 deletions

@ -4204,6 +4204,16 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 61)) {
/* LIGHT_PROBE_RESOLUTION_64 has been removed in EEVEE-Next as the tedrahedral mapping is to
* low res to be usable. */
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->eevee.gi_cubemap_resolution < 128) {
scene->eevee.gi_cubemap_resolution = 128;
}
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 403, 3)) {
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
if (BrushGpencilSettings *settings = brush->gpencil_settings) {

@ -42,7 +42,7 @@
#define SPHERE_PROBE_SH_GROUP_SIZE 256
#define SPHERE_PROBE_SH_SAMPLES_PER_GROUP 64
/* Must be power of two for correct partitioning. */
#define SPHERE_PROBE_ATLAS_MAX_SUBDIV 10
#define SPHERE_PROBE_ATLAS_MAX_SUBDIV 12
#define SPHERE_PROBE_ATLAS_RES (1 << SPHERE_PROBE_ATLAS_MAX_SUBDIV)
/* Maximum number of thread-groups dispatched for remapping a probe to octahedral mapping. */
#define SPHERE_PROBE_MAX_HARMONIC SQUARE(SPHERE_PROBE_ATLAS_RES / SPHERE_PROBE_REMAP_GROUP_SIZE)

@ -44,8 +44,6 @@ LightProbeModule::LightProbeModule(Instance &inst) : inst_(inst)
static eLightProbeResolution resolution_to_probe_resolution_enum(int resolution)
{
switch (resolution) {
case 64:
return LIGHT_PROBE_RESOLUTION_64;
case 128:
return LIGHT_PROBE_RESOLUTION_128;
case 256:
@ -54,11 +52,13 @@ static eLightProbeResolution resolution_to_probe_resolution_enum(int resolution)
return LIGHT_PROBE_RESOLUTION_512;
case 1024:
return LIGHT_PROBE_RESOLUTION_1024;
default:
/* Default to maximum resolution because the old max was 4K for Legacy-EEVEE. */
case 2048:
return LIGHT_PROBE_RESOLUTION_2048;
case 4096:
return LIGHT_PROBE_RESOLUTION_4096;
}
BLI_assert_unreachable();
return LIGHT_PROBE_RESOLUTION_2048;
}
void LightProbeModule::init()

@ -73,7 +73,7 @@ struct SphereProbeAtlasCoord {
{
SphereProbePixelArea coord;
coord.extent = area_extent(mip_lvl);
coord.offset = area_offset();
coord.offset = area_offset(mip_lvl);
coord.layer = atlas_layer;
return coord;
}
@ -220,7 +220,7 @@ class LightProbeModule {
/** True if the auto bake feature is enabled & available in this context. */
bool auto_bake_enabled_;
eLightProbeResolution sphere_object_resolution_ = LIGHT_PROBE_RESOLUTION_64;
eLightProbeResolution sphere_object_resolution_ = LIGHT_PROBE_RESOLUTION_128;
public:
LightProbeModule(Instance &inst);

@ -32,12 +32,10 @@ vec3 sphere_probe_texel_to_direction(vec2 local_texel,
SphereProbeUvArea uv_area,
out vec2 sampling_uv)
{
/* Texel in probe atlas. */
vec2 texel = local_texel + vec2(texel_area.offset);
/* UV in sampling area. No half pixel bias to texel as the octahedral map edges area lined up
* with texel center. Note that we don't use the last row & column of pixel, hence the -2 instead
* of -1. See sphere_probe_miplvl_scale_bias. */
sampling_uv = texel / vec2(texel_area.extent - 2);
sampling_uv = local_texel / vec2(texel_area.extent - 2);
/* Direction in world space. */
return octahedral_uv_to_direction(sampling_uv);
}

@ -138,10 +138,10 @@ enum {
/** #World::probe_resolution. */
typedef enum eLightProbeResolution {
LIGHT_PROBE_RESOLUTION_64 = 6,
LIGHT_PROBE_RESOLUTION_128 = 7,
LIGHT_PROBE_RESOLUTION_256 = 8,
LIGHT_PROBE_RESOLUTION_512 = 9,
LIGHT_PROBE_RESOLUTION_1024 = 10,
LIGHT_PROBE_RESOLUTION_2048 = 11,
LIGHT_PROBE_RESOLUTION_4096 = 12,
} eLightProbeResolution;

@ -7856,7 +7856,6 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
PropertyRNA *prop;
static const EnumPropertyItem eevee_shadow_size_items[] = {
{64, "64", 0, "64 px", ""},
{128, "128", 0, "128 px", ""},
{256, "256", 0, "256 px", ""},
{512, "512", 0, "512 px", ""},
@ -8511,19 +8510,23 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
# if 1
/* Deprecated since Blender 4.2. Kept for compatibility with add-ons. Needs to be removed in a
* future version. */
prop = RNA_def_property(srna, "shadow_cube_size", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, eevee_shadow_size_items);
RNA_def_property_ui_text(
prop, "Cube Shadows Resolution", "Size of point and area light shadow maps");
prop, "Cube Shadows Resolution", "Size of point and area light shadow maps (deprecated)");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
prop = RNA_def_property(srna, "shadow_cascade_size", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, eevee_shadow_size_items);
RNA_def_property_ui_text(
prop, "Directional Shadows Resolution", "Size of sun light shadow maps");
prop, "Directional Shadows Resolution", "Size of sun light shadow maps (deprecated)");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
# endif
prop = RNA_def_property(srna, "shadow_pool_size", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, eevee_pool_size_items);

@ -112,12 +112,12 @@ void rna_World_lightgroup_set(PointerRNA *ptr, const char *value)
#else
static const EnumPropertyItem world_probe_resolution_items[] = {
{LIGHT_PROBE_RESOLUTION_64, "64", 0, "64", ""},
{LIGHT_PROBE_RESOLUTION_128, "128", 0, "128", ""},
{LIGHT_PROBE_RESOLUTION_256, "256", 0, "256", ""},
{LIGHT_PROBE_RESOLUTION_512, "512", 0, "512", ""},
{LIGHT_PROBE_RESOLUTION_1024, "1024", 0, "1024", ""},
{LIGHT_PROBE_RESOLUTION_2048, "2048", 0, "2048", ""},
{LIGHT_PROBE_RESOLUTION_4096, "4096", 0, "4096", ""},
{0, nullptr, 0, nullptr, nullptr},
};