Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/eevee')
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c158
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.h2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c61
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c16
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h33
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c50
-rw-r--r--source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl130
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl22
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl18
15 files changed, 363 insertions, 153 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 2b11a608bd0..35a45cc97f4 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -42,6 +42,7 @@
#include "eevee_private.h"
#include "GPU_context.h"
+#include "GPU_extensions.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -195,6 +196,16 @@ static uint eevee_lightcache_memsize_get(LightCache *lcache)
return size;
}
+static bool eevee_lightcache_version_check(LightCache *lcache)
+{
+ switch (lcache->type) {
+ case LIGHTCACHE_TYPE_STATIC:
+ return lcache->version == LIGHTCACHE_STATIC_VERSION;
+ default:
+ return false;
+ }
+}
+
static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
{
int total_irr_samples = 0;
@@ -208,9 +219,23 @@ static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
{
- LightCache *lcache = eevee->light_cache;
+ LightCache *lcache = eevee->light_cache_data;
if (lcache != NULL) {
+ if (!eevee_lightcache_version_check(lcache)) {
+ BLI_strncpy(eevee->light_cache_info,
+ TIP_("Incompatible Light cache version, please bake again"),
+ sizeof(eevee->light_cache_info));
+ return;
+ }
+
+ if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
+ BLI_strncpy(eevee->light_cache_info,
+ TIP_("Error: Light cache is too big for your GPU to be loaded"),
+ sizeof(eevee->light_cache_info));
+ return;
+ }
+
if (lcache->flag & LIGHTCACHE_BAKING) {
BLI_strncpy(
eevee->light_cache_info, TIP_("Baking light cache"), sizeof(eevee->light_cache_info));
@@ -266,8 +291,8 @@ static bool EEVEE_lightcache_validate(const LightCache *light_cache,
(irr_size[2] == light_cache->grid_tx.tex_size[2]) && (grid_len == light_cache->grid_len)) {
int mip_len = log2_floor_u(cube_res) - MIN_CUBE_LOD_LEVEL;
if ((cube_res == light_cache->cube_tx.tex_size[0]) &&
- (cube_len == light_cache->cube_tx.tex_size[2]) && (cube_len == light_cache->cube_len) &&
- (mip_len == light_cache->mips_len)) {
+ (cube_len == light_cache->cube_tx.tex_size[2] / 6) &&
+ (cube_len == light_cache->cube_len) && (mip_len == light_cache->mips_len)) {
return true;
}
}
@@ -283,6 +308,9 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
{
LightCache *light_cache = MEM_callocN(sizeof(LightCache), "LightCache");
+ light_cache->version = LIGHTCACHE_STATIC_VERSION;
+ light_cache->type = LIGHTCACHE_TYPE_STATIC;
+
light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_len, "EEVEE_LightProbe");
light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_len, "EEVEE_LightGrid");
@@ -292,13 +320,26 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
light_cache->grid_tx.tex_size[1] = irr_size[1];
light_cache->grid_tx.tex_size[2] = irr_size[2];
- light_cache->cube_tx.tex = DRW_texture_create_2d_array(
- cube_size, cube_size, cube_len, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+ int mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL;
+
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ light_cache->cube_tx.tex = DRW_texture_create_cube_array(
+ cube_size, cube_len, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+ }
+ else {
+ light_cache->cube_tx.tex = DRW_texture_create_2d_array(cube_size,
+ cube_size,
+ cube_len * 6,
+ GPU_R11F_G11F_B10F,
+ DRW_TEX_FILTER | DRW_TEX_MIPMAP,
+ NULL);
+ }
+
light_cache->cube_tx.tex_size[0] = cube_size;
light_cache->cube_tx.tex_size[1] = cube_size;
- light_cache->cube_tx.tex_size[2] = cube_len;
+ light_cache->cube_tx.tex_size[2] = cube_len * 6;
- light_cache->mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL;
+ light_cache->mips_len = mips_len;
light_cache->vis_res = vis_size;
light_cache->ref_res = cube_size;
@@ -315,9 +356,19 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
return light_cache;
}
-void EEVEE_lightcache_load(LightCache *lcache)
+static bool eevee_lightcache_static_load(LightCache *lcache)
{
- if (lcache->grid_tx.tex == NULL && lcache->grid_tx.data) {
+ /* We use fallback if a texture is not setup and there is no data to restore it. */
+ if ((!lcache->grid_tx.tex && !lcache->grid_tx.data) ||
+ (!lcache->cube_tx.tex && !lcache->cube_tx.data)) {
+ return false;
+ }
+ /* If cache is too big for this GPU. */
+ if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
+ return false;
+ }
+
+ if (lcache->grid_tx.tex == NULL) {
lcache->grid_tx.tex = GPU_texture_create_nD(lcache->grid_tx.tex_size[0],
lcache->grid_tx.tex_size[1],
lcache->grid_tx.tex_size[2],
@@ -333,17 +384,28 @@ void EEVEE_lightcache_load(LightCache *lcache)
GPU_texture_unbind(lcache->grid_tx.tex);
}
- if (lcache->cube_tx.tex == NULL && lcache->cube_tx.data) {
- lcache->cube_tx.tex = GPU_texture_create_nD(lcache->cube_tx.tex_size[0],
- lcache->cube_tx.tex_size[1],
- lcache->cube_tx.tex_size[2],
- 2,
- lcache->cube_tx.data,
- GPU_R11F_G11F_B10F,
- GPU_DATA_10_11_11_REV,
- 0,
- false,
- NULL);
+ if (lcache->cube_tx.tex == NULL) {
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ lcache->cube_tx.tex = GPU_texture_cube_create(lcache->cube_tx.tex_size[0],
+ lcache->cube_tx.tex_size[2] / 6,
+ lcache->cube_tx.data,
+ GPU_R11F_G11F_B10F,
+ GPU_DATA_10_11_11_REV,
+ NULL);
+ }
+ else {
+ lcache->cube_tx.tex = GPU_texture_create_nD(lcache->cube_tx.tex_size[0],
+ lcache->cube_tx.tex_size[1],
+ lcache->cube_tx.tex_size[2],
+ 2,
+ lcache->cube_tx.data,
+ GPU_R11F_G11F_B10F,
+ GPU_DATA_10_11_11_REV,
+ 0,
+ false,
+ NULL);
+ }
+
GPU_texture_bind(lcache->cube_tx.tex, 0);
GPU_texture_mipmap_mode(lcache->cube_tx.tex, true, true);
for (int mip = 0; mip < lcache->mips_len; mip++) {
@@ -352,6 +414,25 @@ void EEVEE_lightcache_load(LightCache *lcache)
}
GPU_texture_unbind(lcache->cube_tx.tex);
}
+ return true;
+}
+
+bool EEVEE_lightcache_load(LightCache *lcache)
+{
+ if (lcache == NULL) {
+ return false;
+ }
+
+ if (!eevee_lightcache_version_check(lcache)) {
+ return false;
+ }
+
+ switch (lcache->type) {
+ case LIGHTCACHE_TYPE_STATIC:
+ return eevee_lightcache_static_load(lcache);
+ default:
+ return false;
+ }
}
static void eevee_lightbake_readback_irradiance(LightCache *lcache)
@@ -457,7 +538,7 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
prb->grid_resolution_z;
lbake->grid_len++;
}
- else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
+ else if (prb->type == LIGHTPROBE_TYPE_CUBE && lbake->cube_len < EEVEE_PROBE_MAX) {
lbake->cube_len++;
}
}
@@ -491,8 +572,7 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
irradiance_pool_size_get(lbake->vis_res, lbake->total_irr_samples, lbake->irr_size);
- lbake->ref_cube_res = octahedral_size_from_cubesize(lbake->rt_res);
-
+ lbake->ref_cube_res = lbake->rt_res;
lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");
@@ -506,12 +586,12 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
/* Ensure Light Cache is ready to accept new data. If not recreate one.
* WARNING: All the following must be threadsafe. It's currently protected
* by the DRW mutex. */
- lbake->lcache = eevee->light_cache;
+ lbake->lcache = eevee->light_cache_data;
/* TODO validate irradiance and reflection cache independently... */
if (!EEVEE_lightcache_validate(
lbake->lcache, lbake->cube_len, lbake->ref_cube_res, lbake->grid_len, lbake->irr_size)) {
- eevee->light_cache = lbake->lcache = NULL;
+ eevee->light_cache_data = lbake->lcache = NULL;
}
if (lbake->lcache == NULL) {
@@ -522,10 +602,10 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
lbake->lcache->vis_res = lbake->vis_res;
lbake->own_light_cache = true;
- eevee->light_cache = lbake->lcache;
+ eevee->light_cache_data = lbake->lcache;
}
- EEVEE_lightcache_load(eevee->light_cache);
+ EEVEE_lightcache_load(eevee->light_cache_data);
lbake->lcache->flag |= LIGHTCACHE_BAKING;
lbake->lcache->cube_len = 1;
@@ -804,7 +884,7 @@ static void eevee_lightbake_render_world_sample(void *ved, void *user_data)
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
float clamp = scene_eval->eevee.gi_glossy_clamp;
float filter_quality = scene_eval->eevee.gi_filter_quality;
@@ -920,7 +1000,7 @@ static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
EEVEE_LightGrid *egrid = lbake->grid;
LightProbe *prb = *lbake->probe;
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
int grid_loc[3], sample_id, sample_offset, stride;
float pos[3];
const bool is_last_bounce_sample = ((egrid->offset + lbake->grid_sample) ==
@@ -1002,7 +1082,7 @@ static void eevee_lightbake_render_probe_sample(void *ved, void *user_data)
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
EEVEE_LightProbe *eprobe = lbake->cube;
LightProbe *prb = *lbake->probe;
float clamp = scene_eval->eevee.gi_glossy_clamp;
@@ -1083,7 +1163,7 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
{
Depsgraph *depsgraph = lbake->depsgraph;
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
/* At least one for the world */
int grid_len = 1;
@@ -1106,7 +1186,7 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
EEVEE_LightGrid *egrid = &lcache->grid_data[grid_len++];
EEVEE_lightprobes_grid_data_from_object(ob, egrid, &total_irr_samples);
}
- else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
+ else if (prb->type == LIGHTPROBE_TYPE_CUBE && cube_len < EEVEE_PROBE_MAX) {
lbake->cube_prb[cube_len] = prb;
EEVEE_LightProbe *eprobe = &lcache->cube_data[cube_len++];
EEVEE_lightprobes_cube_data_from_object(ob, eprobe);
@@ -1136,11 +1216,11 @@ void EEVEE_lightbake_update(void *custom_data)
Scene *scene_orig = lbake->scene;
/* If a new lightcache was created, free the old one and reference the new. */
- if (lbake->lcache && scene_orig->eevee.light_cache != lbake->lcache) {
- if (scene_orig->eevee.light_cache != NULL) {
- EEVEE_lightcache_free(scene_orig->eevee.light_cache);
+ if (lbake->lcache && scene_orig->eevee.light_cache_data != lbake->lcache) {
+ if (scene_orig->eevee.light_cache_data != NULL) {
+ EEVEE_lightcache_free(scene_orig->eevee.light_cache_data);
}
- scene_orig->eevee.light_cache = lbake->lcache;
+ scene_orig->eevee.light_cache_data = lbake->lcache;
lbake->own_light_cache = false;
}
@@ -1182,6 +1262,12 @@ void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float
lbake->do_update = do_update;
lbake->progress = progress;
+ if (G.background) {
+ /* Make sure to init GL capabilities before counting probes. */
+ eevee_lightbake_context_enable(lbake);
+ eevee_lightbake_context_disable(lbake);
+ }
+
/* Count lightprobes */
eevee_lightbake_count_probes(lbake);
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.h b/source/blender/draw/engines/eevee/eevee_lightcache.h
index ede2de13dce..0db36ce0c2e 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.h
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.h
@@ -60,7 +60,7 @@ struct LightCache *EEVEE_lightcache_create(const int grid_len,
const int vis_size,
const int irr_size[3]);
void EEVEE_lightcache_free(struct LightCache *lcache);
-void EEVEE_lightcache_load(struct LightCache *lcache);
+bool EEVEE_lightcache_load(struct LightCache *lcache);
void EEVEE_lightcache_info_update(struct SceneEEVEE *eevee);
#endif /* __EEVEE_LIGHTCACHE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 4fbecfe3120..61ca2317572 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -37,6 +37,7 @@
#include "GPU_material.h"
#include "GPU_texture.h"
+#include "GPU_extensions.h"
#include "DEG_depsgraph_query.h"
@@ -171,32 +172,28 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
memset(stl->g_data->world_views, 0, sizeof(stl->g_data->world_views));
memset(stl->g_data->planar_views, 0, sizeof(stl->g_data->planar_views));
- /* Use fallback if we don't have gpu texture allocated an we cannot restore them. */
- bool use_fallback_lightcache = (scene_eval->eevee.light_cache == NULL) ||
- ((scene_eval->eevee.light_cache->grid_tx.tex == NULL) &&
- (scene_eval->eevee.light_cache->grid_tx.data == NULL)) ||
- ((scene_eval->eevee.light_cache->cube_tx.tex == NULL) &&
- (scene_eval->eevee.light_cache->cube_tx.data == NULL));
-
- if (use_fallback_lightcache && (sldata->fallback_lightcache == NULL)) {
+ if (EEVEE_lightcache_load(scene_eval->eevee.light_cache_data)) {
+ stl->g_data->light_cache = scene_eval->eevee.light_cache_data;
+ }
+ else {
+ if (!sldata->fallback_lightcache) {
#if defined(IRRADIANCE_SH_L2)
- int grid_res = 4;
+ int grid_res = 4;
#elif defined(IRRADIANCE_CUBEMAP)
- int grid_res = 8;
+ int grid_res = 8;
#elif defined(IRRADIANCE_HL2)
- int grid_res = 4;
+ int grid_res = 4;
#endif
- int cube_res = octahedral_size_from_cubesize(scene_eval->eevee.gi_cubemap_resolution);
- int vis_res = scene_eval->eevee.gi_visibility_resolution;
- sldata->fallback_lightcache = EEVEE_lightcache_create(
- 1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1});
+ sldata->fallback_lightcache = EEVEE_lightcache_create(
+ 1,
+ 1,
+ scene_eval->eevee.gi_cubemap_resolution,
+ scene_eval->eevee.gi_visibility_resolution,
+ (int[3]){grid_res, grid_res, 1});
+ }
+ stl->g_data->light_cache = sldata->fallback_lightcache;
}
- stl->g_data->light_cache = (use_fallback_lightcache) ? sldata->fallback_lightcache :
- scene_eval->eevee.light_cache;
-
- EEVEE_lightcache_load(stl->g_data->light_cache);
-
if (!sldata->probes) {
sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo");
sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL);
@@ -255,7 +252,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_call_instances(grp, NULL, geom, 6);
}
{
@@ -508,8 +505,8 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
EEVEE_LightProbesInfo *pinfo = sldata->probes;
LightProbe *probe = (LightProbe *)ob->data;
- if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= MAX_PROBE) ||
- (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= MAX_PROBE) ||
+ if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= EEVEE_PROBE_MAX) ||
+ (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= EEVEE_PROBE_MAX) ||
(probe->type == LIGHTPROBE_TYPE_PLANAR && pinfo->num_planar >= MAX_PLANAR)) {
printf("Too many probes in the view !!!\n");
return;
@@ -762,7 +759,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
/* For shading, save max level of the octahedron map */
- sldata->common_data.prb_lod_cube_max = (float)light_cache->mips_len - 1.0f;
+ sldata->common_data.prb_lod_cube_max = (float)light_cache->mips_len;
sldata->common_data.prb_lod_planar_max = (float)MAX_PLANAR_LOD_LEVEL;
sldata->common_data.prb_irradiance_vis_size = light_cache->vis_res;
sldata->common_data.prb_irradiance_smooth = square_f(scene_eval->eevee.gi_irradiance_smoothing);
@@ -785,15 +782,15 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
if (draw_ctx->scene->eevee.flag & SCE_EEVEE_GI_AUTOBAKE) {
Scene *scene_orig = DEG_get_input_scene(draw_ctx->depsgraph);
- if (scene_orig->eevee.light_cache != NULL) {
+ if (scene_orig->eevee.light_cache_data != NULL) {
if (pinfo->do_grid_update) {
- scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID;
+ scene_orig->eevee.light_cache_data->flag |= LIGHTCACHE_UPDATE_GRID;
}
- /* If we update grid we need to update the cube-maps too.
- * So always refresh cube-maps. */
- scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
- /* Tag the light-cache to auto update. */
- scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_AUTO;
+ /* If we update grid we need to update the cubemaps too.
+ * So always refresh cubemaps. */
+ scene_orig->eevee.light_cache_data->flag |= LIGHTCACHE_UPDATE_CUBE;
+ /* Tag the lightcache to auto update. */
+ scene_orig->eevee.light_cache_data->flag |= LIGHTCACHE_UPDATE_AUTO;
/* Use a notifier to trigger the operator after drawing. */
WM_event_add_notifier(draw_ctx->evil_C, NC_LIGHTPROBE, scene_orig);
}
@@ -1077,7 +1074,7 @@ void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata,
pinfo->texel_size = 1.0f / (float)mipsize;
pinfo->padding_size = (i == maxlevel) ? 0 : (float)(1 << (maxlevel - i - 1));
pinfo->padding_size *= pinfo->texel_size;
- pinfo->layer = probe_idx;
+ pinfo->layer = probe_idx * 6;
pinfo->roughness = i / (float)maxlevel;
pinfo->roughness *= pinfo->roughness; /* Disney Roughness */
pinfo->roughness *= pinfo->roughness; /* Distribute Roughness accros lod more evenly */
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index 7be6fc2d030..a725a3583f3 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -76,7 +76,7 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
effects->lookdev_view = NULL;
- if (LOOK_DEV_OVERLAY_ENABLED(v3d)) {
+ if (eevee_hdri_preview_overlay_enabled(v3d)) {
/* Viewport / Spheres size. */
const rcti *rect;
rcti fallback_rect;
@@ -116,7 +116,7 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_shaders_background_studiolight_sh_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- int cube_res = octahedral_size_from_cubesize(scene_eval->eevee.gi_cubemap_resolution);
+ int cube_res = scene_eval->eevee.gi_cubemap_resolution;
/* If one of the component is missing we start from scratch. */
if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
@@ -228,7 +228,7 @@ void EEVEE_lookdev_draw(EEVEE_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
- if (psl->lookdev_diffuse_pass && LOOK_DEV_OVERLAY_ENABLED(draw_ctx->v3d)) {
+ if (psl->lookdev_diffuse_pass && eevee_hdri_preview_overlay_enabled(draw_ctx->v3d)) {
/* Config renderer. */
EEVEE_CommonUniformBuffer *common = &sldata->common_data;
common->la_num_light = 0;
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index a37c063adf6..230a0725493 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -89,6 +89,7 @@ extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_lit_surface_frag_glsl[];
extern char datatoc_lit_surface_vert_glsl[];
extern char datatoc_raytrace_lib_glsl[];
@@ -618,6 +619,7 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
datatoc_raytrace_lib_glsl,
datatoc_ssr_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_ltc_lib_glsl,
@@ -641,6 +643,7 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
datatoc_bsdf_common_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_ltc_lib_glsl,
@@ -776,6 +779,7 @@ struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, Wor
wo,
engine,
options,
+ false,
e_data.vert_background_shader_str,
NULL,
e_data.frag_shader_lib,
@@ -796,6 +800,7 @@ struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, Wor
wo,
engine,
options,
+ false,
e_data.vert_background_shader_str,
NULL,
e_data.frag_shader_lib,
@@ -819,6 +824,7 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *
wo,
engine,
options,
+ true,
e_data.vert_volume_shader_str,
e_data.geom_volume_shader_str,
e_data.volume_shader_lib,
@@ -853,6 +859,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(struct Scene *scene,
ma,
engine,
options,
+ false,
e_data.vert_shader_str,
NULL,
e_data.frag_shader_lib,
@@ -880,6 +887,7 @@ struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material
ma,
engine,
options,
+ true,
e_data.vert_volume_shader_str,
e_data.geom_volume_shader_str,
e_data.volume_shader_lib,
@@ -916,6 +924,7 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene,
ma,
engine,
options,
+ false,
(is_shadow) ? e_data.vert_shadow_shader_str :
e_data.vert_shader_str,
NULL,
@@ -945,6 +954,7 @@ struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma)
ma,
engine,
options,
+ false,
e_data.vert_shader_str,
NULL,
e_data.frag_shader_lib,
@@ -1256,7 +1266,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
- if (LOOK_DEV_OVERLAY_ENABLED(draw_ctx->v3d)) {
+ if (eevee_hdri_preview_overlay_enabled(draw_ctx->v3d)) {
DRWShadingGroup *shgrp;
struct GPUBatch *sphere = DRW_cache_sphere_get();
@@ -1919,7 +1929,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
* to know if the material has a "volume nodetree".
*/
bool use_volume_material = (gpumat_array[0] &&
- GPU_material_use_domain_volume(gpumat_array[0]));
+ GPU_material_has_volume_output(gpumat_array[0]));
if ((ob->dt >= OB_SOLID) || DRW_state_is_image_render()) {
/* Get per-material split surface */
@@ -1968,7 +1978,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
/* Do not render surface if we are rendering a volume object
* and do not have a surface closure. */
if (use_volume_material &&
- (gpumat_array[i] && !GPU_material_use_domain_surface(gpumat_array[i]))) {
+ (gpumat_array[i] && !GPU_material_has_surface_output(gpumat_array[i]))) {
continue;
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 5ffea393e1f..0f084ba306b 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -78,6 +78,8 @@ extern struct DrawEngineType draw_engine_eevee_type;
SHADER_IRRADIANCE
/* clang-format on */
+#define EEVEE_PROBE_MAX min_ii(MAX_PROBE, GPU_max_texture_layers() / 6)
+
#define SWAP_DOUBLE_BUFFERS() \
{ \
if (effects->swap_double_buffer) { \
@@ -123,9 +125,21 @@ extern struct DrawEngineType draw_engine_eevee_type;
} \
((void)0)
-#define LOOK_DEV_OVERLAY_ENABLED(v3d) \
- ((v3d) && (v3d->shading.type == OB_MATERIAL) && ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && \
- (v3d->overlay.flag & V3D_OVERLAY_LOOK_DEV))
+BLI_INLINE bool eevee_hdri_preview_overlay_enabled(View3D *v3d)
+{
+ /* Only show the HDRI Preview in Shading Preview in the Viewport. */
+ if (v3d == NULL || v3d->shading.type != OB_MATERIAL) {
+ return false;
+ }
+
+ /* Only show the HDRI Preview when viewing the Combined render pass */
+ if (v3d->shading.render_pass != SCE_PASS_COMBINED) {
+ return false;
+ }
+
+ return ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (v3d->overlay.flag & V3D_OVERLAY_LOOK_DEV);
+}
+
#define USE_SCENE_LIGHT(v3d) \
((!v3d) || \
((v3d->shading.type == OB_MATERIAL) && (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)) || \
@@ -137,19 +151,6 @@ extern struct DrawEngineType draw_engine_eevee_type;
((v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER) == 0))))
#define MIN_CUBE_LOD_LEVEL 3
-
-BLI_INLINE int octahedral_size_from_cubesize(int cube_size)
-{
- int cube_pixel_count = square_i(cube_size) * 6;
- int octa_size = (int)ceilf(sqrtf(cube_pixel_count));
- int lod_count = log2_floor_u(octa_size) - MIN_CUBE_LOD_LEVEL;
- /* Find lowest lod size and grow back to avoid having non matching mipsizes that would
- * break trilinear interpolation. */
- octa_size /= 1 << lod_count;
- octa_size *= 1 << lod_count;
- return octa_size;
-}
-
#define MAX_PLANAR_LOD_LEVEL 9
/* All the renderpasses that use the GPUMaterial for accumulation */
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index d231edf1383..e875187bdbf 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -54,6 +54,7 @@ extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_effect_ssr_frag_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_raytrace_lib_glsl[];
@@ -67,6 +68,7 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
datatoc_bsdf_sampling_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_raytrace_lib_glsl,
datatoc_effect_ssr_frag_glsl);
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index 2d91e4bb4bd..50b7c5c5f97 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -88,6 +88,7 @@ extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
/* Velocity Resolve */
extern char datatoc_effect_velocity_resolve_frag_glsl[];
@@ -196,6 +197,7 @@ GPUShader *EEVEE_shaders_background_studiolight_sh_get(void)
{
if (e_data.probe_background_studiolight_sh == NULL) {
char *frag_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_lightprobe_lib_glsl,
@@ -217,6 +219,7 @@ GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void)
{
if (e_data.probe_cube_display_sh == NULL) {
char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
@@ -238,6 +241,7 @@ GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void)
{
if (e_data.probe_grid_display_sh == NULL) {
char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index 98e799acb5e..bab89a8a87b 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -41,6 +41,7 @@ extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
extern char datatoc_raytrace_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_effect_subsurface_frag_glsl[];
@@ -59,6 +60,7 @@ static void eevee_create_shader_subsurface(void)
datatoc_bsdf_sampling_lib_glsl,
datatoc_raytrace_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_lights_lib_glsl,
datatoc_effect_translucency_frag_glsl);
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index d11e93bbc3f..8c1c72a3c20 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -72,6 +72,7 @@ extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
+extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
extern char datatoc_volumetric_accum_frag_glsl[];
@@ -99,6 +100,7 @@ static void eevee_create_shader_volumes(void)
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_octahedron_lib_glsl,
+ datatoc_cubemap_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lights_lib_glsl,
datatoc_volumetric_lib_glsl);
@@ -141,10 +143,10 @@ static void eevee_create_shader_volumes(void)
e_data.volumetric_accum_sh = DRW_shader_create_fullscreen(datatoc_volumetric_accum_frag_glsl,
NULL);
- float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, color);
+ const float density[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, density);
- float flame = 0.0f;
+ const float flame = 0.0f;
e_data.dummy_flame = DRW_texture_create_3d(1, 1, 1, GPU_R8, DRW_TEX_WRAP, &flame);
}
@@ -351,7 +353,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
!LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) {
struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
- if (GPU_material_use_domain_volume(mat)) {
+ if (GPU_material_has_volume_output(mat)) {
grp = DRW_shgroup_material_create(mat, psl->volumetric_world_ps);
}
@@ -367,9 +369,11 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
/* Fix principle volumetric not working with world materials. */
- DRW_shgroup_uniform_texture(grp, "sampdensity", e_data.dummy_density);
- DRW_shgroup_uniform_texture(grp, "sampflame", e_data.dummy_flame);
- DRW_shgroup_uniform_vec2_copy(grp, "unftemperature", (float[2]){0.0f, 1.0f});
+ ListBase gpu_grids = GPU_material_volume_grids(mat);
+ for (GPUMaterialVolumeGrid *gpu_grid = gpu_grids.first; gpu_grid;
+ gpu_grid = gpu_grid->next) {
+ DRW_shgroup_uniform_texture(grp, gpu_grid->sampler_name, e_data.dummy_density);
+ }
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
@@ -445,6 +449,7 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1);
DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texcosize, 1);
+ ListBase gpu_grids = GPU_material_volume_grids(mat);
/* Smoke Simulation */
if (((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
(md = modifiers_findByType(ob, eModifierType_Fluid)) &&
@@ -476,10 +481,25 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(mmd));
}
- DRW_shgroup_uniform_texture_ref(
- grp, "sampdensity", mds->tex ? &mds->tex : &e_data.dummy_density);
- DRW_shgroup_uniform_texture_ref(
- grp, "sampflame", mds->tex_flame ? &mds->tex_flame : &e_data.dummy_flame);
+ for (GPUMaterialVolumeGrid *gpu_grid = gpu_grids.first; gpu_grid; gpu_grid = gpu_grid->next) {
+ if (STREQ(gpu_grid->name, "density")) {
+ DRW_shgroup_uniform_texture_ref(grp,
+ gpu_grid->sampler_name,
+ mds->tex_density ? &mds->tex_density :
+ &e_data.dummy_density);
+ }
+ else if (STREQ(gpu_grid->name, "color")) {
+ DRW_shgroup_uniform_texture_ref(
+ grp, gpu_grid->sampler_name, mds->tex_color ? &mds->tex_color : &e_data.dummy_density);
+ }
+ else if (STREQ(gpu_grid->name, "flame") || STREQ(gpu_grid->name, "temperature")) {
+ DRW_shgroup_uniform_texture_ref(
+ grp, gpu_grid->sampler_name, mds->tex_flame ? &mds->tex_flame : &e_data.dummy_flame);
+ }
+ else {
+ DRW_shgroup_uniform_texture_ref(grp, gpu_grid->sampler_name, &e_data.dummy_density);
+ }
+ }
/* Constant Volume color. */
bool use_constant_color = ((mds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) == 0 &&
@@ -489,13 +509,13 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
grp, "volumeColor", (use_constant_color) ? mds->active_color : white, 1);
/* Output is such that 0..1 maps to 0..1000K */
- DRW_shgroup_uniform_vec2(grp, "unftemperature", &mds->flame_ignition, 1);
+ DRW_shgroup_uniform_vec2(grp, "volumeTemperature", &mds->flame_ignition, 1);
}
else {
- DRW_shgroup_uniform_texture(grp, "sampdensity", e_data.dummy_density);
- DRW_shgroup_uniform_texture(grp, "sampflame", e_data.dummy_flame);
+ for (GPUMaterialVolumeGrid *gpu_grid = gpu_grids.first; gpu_grid; gpu_grid = gpu_grid->next) {
+ DRW_shgroup_uniform_texture(grp, gpu_grid->sampler_name, e_data.dummy_density);
+ }
DRW_shgroup_uniform_vec3(grp, "volumeColor", white, 1);
- DRW_shgroup_uniform_vec2(grp, "unftemperature", (float[2]){0.0f, 1.0f}, 1);
}
/* TODO Reduce to number of slices intersecting. */
diff --git a/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl
new file mode 100644
index 00000000000..90272400915
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl
@@ -0,0 +1,130 @@
+
+#ifdef GPU_ARB_texture_cube_map_array
+
+# define textureLod_cubemapArray(tex, co, lod) textureLod(tex, co, lod)
+
+#else
+
+/* Fallback implementation for hardware not supporting cubemap arrays. */
+# define samplerCubeArray sampler2DArray
+
+float cubemap_face_index(vec3 P)
+{
+ vec3 aP = abs(P);
+ if (all(greaterThan(aP.xx, aP.yz))) {
+ return (P.x > 0.0) ? 0.0 : 1.0;
+ }
+ else if (all(greaterThan(aP.yy, aP.xz))) {
+ return (P.y > 0.0) ? 2.0 : 3.0;
+ }
+ else {
+ return (P.z > 0.0) ? 4.0 : 5.0;
+ }
+}
+
+vec2 cubemap_face_coord(vec3 P, float face)
+{
+ if (face < 2.0) {
+ return (P.zy / P.x) * vec2(-0.5, -sign(P.x) * 0.5) + 0.5;
+ }
+ else if (face < 4.0) {
+ return (P.xz / P.y) * vec2(sign(P.y) * 0.5, 0.5) + 0.5;
+ }
+ else {
+ return (P.xy / P.z) * vec2(0.5, -sign(P.z) * 0.5) + 0.5;
+ }
+}
+
+vec3 cubemap_adj_x(float face)
+{
+ bool y_axis = (face == 2.0 || face == 3.0);
+ return y_axis ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
+}
+
+vec3 cubemap_adj_y(float face)
+{
+ bool x_axis = (face < 2.0);
+ return x_axis ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+}
+
+vec3 cubemap_adj_xy(float face)
+{
+ if (face < 2.0) {
+ return vec3(0.0, 1.0, 1.0);
+ }
+ else if (face < 4.0) {
+ return vec3(1.0, 0.0, 1.0);
+ }
+ else {
+ return vec3(1.0, 1.0, 0.0);
+ }
+}
+
+vec4 cubemap_seamless(sampler2DArray tex, vec4 cubevec, float lod)
+{
+ /* Manual Cube map Layer indexing. */
+ float face = cubemap_face_index(cubevec.xyz);
+ vec2 uv = cubemap_face_coord(cubevec.xyz, face);
+ vec3 coord = vec3(uv, cubevec.w * 6.0 + face);
+
+ vec4 col = textureLod(tex, coord, lod);
+
+ float cube_size = float(textureSize(tex, int(lod)).x);
+
+ vec2 uv_border = (abs(uv - 0.5) + (0.5 / cube_size - 0.5)) * 2.0 * cube_size;
+ bvec2 border = greaterThan(uv_border, vec2(0.0));
+ if (all(border)) {
+ /* Corners case. */
+ vec3 cubevec_adj;
+ float face_adj;
+ /* Get the other face coords. */
+ cubevec_adj = cubevec.xyz * cubemap_adj_x(face);
+ face_adj = cubemap_face_index(cubevec_adj);
+ /* Still use the original cubevec to get the outer texels or the face. */
+ uv = cubemap_face_coord(cubevec.xyz, face_adj);
+ coord = vec3(uv, cubevec.w * 6.0 + face_adj);
+ vec4 col1 = textureLod(tex, coord, lod);
+
+ /* Get the 3rd face coords. */
+ cubevec_adj = cubevec.xyz * cubemap_adj_y(face);
+ face_adj = cubemap_face_index(cubevec_adj);
+ /* Still use the original cubevec to get the outer texels or the face. */
+ uv = cubemap_face_coord(cubevec.xyz, face_adj);
+ coord = vec3(uv, cubevec.w * 6.0 + face_adj);
+ vec4 col2 = textureLod(tex, coord, lod);
+
+ /* Mix all colors to get the corner color. */
+ vec4 col3 = (col + col1 + col2) / 3.0;
+
+ vec2 mix_fac = uv_border * 0.5;
+ return mix(mix(col, col2, mix_fac.x), mix(col1, col3, mix_fac.x), mix_fac.y);
+ }
+ else if (any(border)) {
+ /* Edges case. */
+ /* Get the other face coords. */
+ vec3 cubevec_adj = cubevec.xyz * cubemap_adj_xy(face);
+ face = cubemap_face_index(cubevec_adj);
+ /* Still use the original cubevec to get the outer texels or the face. */
+ uv = cubemap_face_coord(cubevec.xyz, face);
+ coord = vec3(uv, cubevec.w * 6.0 + face);
+
+ float mix_fac = max(uv_border.x, uv_border.y) * 0.5;
+ return mix(col, textureLod(tex, coord, lod), mix_fac);
+ }
+ else {
+ return col;
+ }
+}
+
+vec4 textureLod_cubemapArray(sampler2DArray tex, vec4 cubevec, float lod)
+{
+ float lod1 = floor(lod);
+ float lod2 = ceil(lod);
+
+ vec4 col_lod1 = cubemap_seamless(tex, cubevec, lod1);
+ vec4 col_lod2 = cubemap_seamless(tex, cubevec, lod2);
+
+ return mix(col_lod1, col_lod2, lod - lod1);
+}
+
+#endif
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
index a852dd47872..96fe94fc41e 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
@@ -15,6 +15,5 @@ void main()
vec3 view_nor = vec3(quadCoord, sqrt(max(0.0, 1.0 - dist_sqr)));
vec3 world_ref = mat3(ViewMatrixInverse) * reflect(vec3(0.0, 0.0, -1.0), view_nor);
- FragColor = vec4(textureLod_octahedron(probeCubes, vec4(world_ref, pid), 0.0, prbLodCubeMax).rgb,
- 1.0);
+ FragColor = vec4(textureLod_cubemapArray(probeCubes, vec4(world_ref, pid), 0.0).rgb, 1.0);
}
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
index 06c31272ecd..00eb3c7e200 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
@@ -33,29 +33,9 @@ vec3 octahedral_to_cubemap_proj(vec2 co)
void main()
{
- vec2 uvs = gl_FragCoord.xy * texelSize;
-
- /* Add a N pixel border to ensure filtering is correct
- * for N mipmap levels. */
- uvs = (uvs - paddingSize) / (1.0 - 2.0 * paddingSize);
-
- /* edge mirroring : only mirror if directly adjacent
- * (not diagonally adjacent) */
- vec2 m = abs(uvs - 0.5) + 0.5;
- vec2 f = floor(m);
- if (f.x - f.y != 0.0) {
- uvs = 1.0 - uvs;
- }
-
- /* clamp to [0-1] */
- uvs = fract(uvs);
-
- /* get cubemap vector */
- vec3 cubevec = octahedral_to_cubemap_proj(uvs);
-
vec3 N, T, B, V;
- vec3 R = normalize(cubevec);
+ vec3 R = normalize(worldPosition);
/* Isotropic assumption */
N = V = R;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
index ab205b78274..6c6db88139b 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
@@ -1,7 +1,7 @@
/* ----------- Uniforms --------- */
uniform sampler2DArray probePlanars;
-uniform sampler2DArray probeCubes;
+uniform samplerCubeArray probeCubes;
/* ----------- Structures --------- */
@@ -172,15 +172,12 @@ vec3 probe_evaluate_cube(int pd_id, vec3 W, vec3 R, float roughness)
float fac = saturate(original_roughness * 2.0 - 1.0);
R = mix(intersection, R, fac * fac);
- return textureLod_octahedron(
- probeCubes, vec4(R, float(pd_id)), roughness * prbLodCubeMax, prbLodCubeMax)
- .rgb;
+ return textureLod_cubemapArray(probeCubes, vec4(R, float(pd_id)), roughness * prbLodCubeMax).rgb;
}
vec3 probe_evaluate_world_spec(vec3 R, float roughness)
{
- return textureLod_octahedron(probeCubes, vec4(R, 0.0), roughness * prbLodCubeMax, prbLodCubeMax)
- .rgb;
+ return textureLod_cubemapArray(probeCubes, vec4(R, 0.0), roughness * prbLodCubeMax).rgb;
}
vec3 probe_evaluate_planar(
diff --git a/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl b/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl
index bfb6bc890ec..e05cc2719fa 100644
--- a/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/octahedron_lib.glsl
@@ -18,21 +18,3 @@ vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size)
return uvs;
}
-
-vec4 textureLod_octahedron(sampler2DArray tex, vec4 cubevec, float lod, float lod_max)
-{
- vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lod_max)));
-
- vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize);
-
- return textureLod(tex, vec3(uvs, cubevec.w), lod);
-}
-
-vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec)
-{
- vec2 texelSize = 1.0 / vec2(textureSize(tex, 0));
-
- vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize);
-
- return texture(tex, vec3(uvs, cubevec.w));
-}