2017-04-18 12:50:09 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright 2016, Blender Foundation.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): Blender Institute
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2017-10-07 15:57:14 +11:00
|
|
|
/** \file eevee_lightprobes.c
|
2017-04-18 12:50:09 +02:00
|
|
|
* \ingroup DNA
|
|
|
|
|
*/
|
|
|
|
|
|
2017-11-20 14:11:45 +11:00
|
|
|
#include "DRW_render.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_utildefines.h"
|
2018-01-17 21:40:43 +11:00
|
|
|
#include "BLI_string_utils.h"
|
2017-11-20 14:11:45 +11:00
|
|
|
#include "BLI_rand.h"
|
|
|
|
|
|
2017-04-18 12:50:09 +02:00
|
|
|
#include "DNA_world_types.h"
|
|
|
|
|
#include "DNA_texture_types.h"
|
|
|
|
|
#include "DNA_image_types.h"
|
2017-06-12 20:59:54 +10:00
|
|
|
#include "DNA_lightprobe_types.h"
|
2017-06-08 21:48:50 +02:00
|
|
|
#include "DNA_view3d_types.h"
|
2017-04-18 12:50:09 +02:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#include "BKE_collection.h"
|
2017-06-09 22:30:49 +02:00
|
|
|
#include "BKE_object.h"
|
2018-02-14 18:59:15 +01:00
|
|
|
#include "MEM_guardedalloc.h"
|
2017-06-09 22:30:49 +02:00
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
#include "GPU_material.h"
|
2017-04-18 12:50:09 +02:00
|
|
|
#include "GPU_texture.h"
|
|
|
|
|
#include "GPU_glew.h"
|
|
|
|
|
|
2018-05-16 19:34:24 +02:00
|
|
|
#include "DEG_depsgraph_query.h"
|
|
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
#include "eevee_engine.h"
|
|
|
|
|
#include "eevee_private.h"
|
|
|
|
|
|
2017-11-20 14:11:45 +11:00
|
|
|
#include "ED_screen.h"
|
|
|
|
|
|
2017-12-04 17:20:20 +01:00
|
|
|
/* Rounded to nearest PowerOfTwo */
|
|
|
|
|
#if defined(IRRADIANCE_SH_L2)
|
|
|
|
|
#define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
|
|
|
|
|
#define IRRADIANCE_SAMPLE_SIZE_Y 4 /* 3 in reality */
|
|
|
|
|
#elif defined(IRRADIANCE_CUBEMAP)
|
|
|
|
|
#define IRRADIANCE_SAMPLE_SIZE_X 8
|
|
|
|
|
#define IRRADIANCE_SAMPLE_SIZE_Y 8
|
|
|
|
|
#elif defined(IRRADIANCE_HL2)
|
|
|
|
|
#define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
|
|
|
|
|
#define IRRADIANCE_SAMPLE_SIZE_Y 2
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define IRRADIANCE_MAX_POOL_LAYER 256 /* OpenGL 3.3 core requirement, can be extended but it's already very big */
|
|
|
|
|
#define IRRADIANCE_MAX_POOL_SIZE 1024
|
|
|
|
|
#define MAX_IRRADIANCE_SAMPLES \
|
|
|
|
|
(IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_X) * \
|
|
|
|
|
(IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_Y)
|
2017-12-02 14:28:29 +01:00
|
|
|
#define HAMMERSLEY_SIZE 1024
|
2017-05-29 22:03:57 +02:00
|
|
|
|
|
|
|
|
static struct {
|
2017-06-04 12:12:58 +02:00
|
|
|
struct GPUShader *probe_default_sh;
|
2018-05-25 08:06:36 +02:00
|
|
|
struct GPUShader *probe_default_studiolight_sh;
|
2017-06-13 17:39:39 +02:00
|
|
|
struct GPUShader *probe_filter_glossy_sh;
|
|
|
|
|
struct GPUShader *probe_filter_diffuse_sh;
|
2017-12-02 14:28:29 +01:00
|
|
|
struct GPUShader *probe_filter_visibility_sh;
|
2017-09-28 21:17:57 +02:00
|
|
|
struct GPUShader *probe_grid_fill_sh;
|
2017-06-14 13:45:54 +02:00
|
|
|
struct GPUShader *probe_grid_display_sh;
|
2017-06-17 01:59:01 +02:00
|
|
|
struct GPUShader *probe_planar_display_sh;
|
2017-06-26 20:37:41 +02:00
|
|
|
struct GPUShader *probe_planar_downsample_sh;
|
2017-06-15 00:10:34 +02:00
|
|
|
struct GPUShader *probe_cube_display_sh;
|
2017-05-29 22:03:57 +02:00
|
|
|
|
|
|
|
|
struct GPUTexture *hammersley;
|
2017-06-23 19:02:40 +02:00
|
|
|
struct GPUTexture *planar_pool_placeholder;
|
2017-07-21 14:27:16 +02:00
|
|
|
struct GPUTexture *depth_placeholder;
|
2017-07-23 14:03:27 +02:00
|
|
|
struct GPUTexture *depth_array_placeholder;
|
2017-06-23 21:08:53 +02:00
|
|
|
struct GPUTexture *cube_face_minmaxz;
|
2017-05-29 22:03:57 +02:00
|
|
|
|
2018-02-14 18:59:15 +01:00
|
|
|
struct Gwn_VertFormat *format_probe_display_cube;
|
|
|
|
|
struct Gwn_VertFormat *format_probe_display_planar;
|
2017-05-29 22:03:57 +02:00
|
|
|
} e_data = {NULL}; /* Engine data */
|
|
|
|
|
|
2017-06-29 17:32:13 +02:00
|
|
|
extern char datatoc_background_vert_glsl[];
|
2017-06-04 12:12:58 +02:00
|
|
|
extern char datatoc_default_world_frag_glsl[];
|
2017-06-13 17:39:39 +02:00
|
|
|
extern char datatoc_lightprobe_filter_glossy_frag_glsl[];
|
|
|
|
|
extern char datatoc_lightprobe_filter_diffuse_frag_glsl[];
|
2017-12-02 14:28:29 +01:00
|
|
|
extern char datatoc_lightprobe_filter_visibility_frag_glsl[];
|
2017-06-12 20:59:54 +10:00
|
|
|
extern char datatoc_lightprobe_geom_glsl[];
|
|
|
|
|
extern char datatoc_lightprobe_vert_glsl[];
|
2017-06-17 01:59:01 +02:00
|
|
|
extern char datatoc_lightprobe_planar_display_frag_glsl[];
|
|
|
|
|
extern char datatoc_lightprobe_planar_display_vert_glsl[];
|
2017-06-26 20:37:41 +02:00
|
|
|
extern char datatoc_lightprobe_planar_downsample_frag_glsl[];
|
|
|
|
|
extern char datatoc_lightprobe_planar_downsample_geom_glsl[];
|
|
|
|
|
extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
|
2017-06-15 00:10:34 +02:00
|
|
|
extern char datatoc_lightprobe_cube_display_frag_glsl[];
|
|
|
|
|
extern char datatoc_lightprobe_cube_display_vert_glsl[];
|
2017-06-14 13:45:54 +02:00
|
|
|
extern char datatoc_lightprobe_grid_display_frag_glsl[];
|
|
|
|
|
extern char datatoc_lightprobe_grid_display_vert_glsl[];
|
2017-09-28 21:17:57 +02:00
|
|
|
extern char datatoc_lightprobe_grid_fill_frag_glsl[];
|
2017-06-14 13:45:54 +02:00
|
|
|
extern char datatoc_irradiance_lib_glsl[];
|
2017-06-28 16:31:25 +02:00
|
|
|
extern char datatoc_lightprobe_lib_glsl[];
|
2017-06-15 00:09:49 +02:00
|
|
|
extern char datatoc_octahedron_lib_glsl[];
|
2017-05-29 22:03:57 +02:00
|
|
|
extern char datatoc_bsdf_common_lib_glsl[];
|
2018-01-21 17:25:10 +01:00
|
|
|
extern char datatoc_common_uniforms_lib_glsl[];
|
2018-03-10 00:00:04 +01:00
|
|
|
extern char datatoc_common_view_lib_glsl[];
|
2017-05-29 22:03:57 +02:00
|
|
|
extern char datatoc_bsdf_sampling_lib_glsl[];
|
2017-04-18 12:50:09 +02:00
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
extern GlobalsUboStorage ts;
|
|
|
|
|
|
2017-04-18 12:50:09 +02:00
|
|
|
/* *********** FUNCTIONS *********** */
|
|
|
|
|
|
2017-12-04 17:20:20 +01:00
|
|
|
static void irradiance_pool_size_get(int visibility_size, int total_samples, int r_size[3])
|
|
|
|
|
{
|
|
|
|
|
/* Compute how many irradiance samples we can store per visibility sample. */
|
|
|
|
|
int irr_per_vis = (visibility_size / IRRADIANCE_SAMPLE_SIZE_X) *
|
|
|
|
|
(visibility_size / IRRADIANCE_SAMPLE_SIZE_Y);
|
|
|
|
|
|
|
|
|
|
/* The irradiance itself take one layer, hence the +1 */
|
|
|
|
|
int layer_ct = MIN2(irr_per_vis + 1, IRRADIANCE_MAX_POOL_LAYER);
|
|
|
|
|
|
|
|
|
|
int texel_ct = (int)ceilf((float)total_samples / (float)(layer_ct - 1));
|
|
|
|
|
r_size[0] = visibility_size * max_ii(1, min_ii(texel_ct, (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
|
|
|
|
|
r_size[1] = visibility_size * max_ii(1, (texel_ct / (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
|
|
|
|
|
r_size[2] = layer_ct;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-29 22:03:57 +02:00
|
|
|
static struct GPUTexture *create_hammersley_sample_texture(int samples)
|
|
|
|
|
{
|
|
|
|
|
struct GPUTexture *tex;
|
|
|
|
|
float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * samples, "hammersley_tex");
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < samples; i++) {
|
2017-09-26 21:38:23 +02:00
|
|
|
double dphi;
|
|
|
|
|
BLI_hammersley_1D(i, &dphi);
|
|
|
|
|
float phi = (float)dphi * 2.0f * M_PI;
|
2017-06-04 21:45:41 +02:00
|
|
|
texels[i][0] = cosf(phi);
|
2017-05-29 22:03:57 +02:00
|
|
|
texels[i][1] = sinf(phi);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-30 16:02:24 +02:00
|
|
|
tex = DRW_texture_create_1D(samples, GPU_RG16F, DRW_TEX_WRAP, (float *)texels);
|
2017-05-29 22:03:57 +02:00
|
|
|
MEM_freeN(texels);
|
|
|
|
|
return tex;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref)
|
|
|
|
|
{
|
|
|
|
|
/* XXX TODO OPTIMISATION : This is a complete waist of texture memory.
|
|
|
|
|
* Instead of allocating each planar probe for each viewport,
|
|
|
|
|
* only alloc them once using the biggest viewport resolution. */
|
|
|
|
|
EEVEE_TextureList *txl = vedata->txl;
|
|
|
|
|
|
|
|
|
|
const float *viewport_size = DRW_viewport_size_get();
|
|
|
|
|
|
|
|
|
|
/* TODO get screen percentage from layer setting */
|
|
|
|
|
// const DRWContextState *draw_ctx = DRW_context_state_get();
|
2017-11-22 10:52:39 -02:00
|
|
|
// ViewLayer *view_layer = draw_ctx->view_layer;
|
2017-06-17 00:08:03 +02:00
|
|
|
float screen_percentage = 1.0f;
|
|
|
|
|
|
|
|
|
|
int width = (int)(viewport_size[0] * screen_percentage);
|
|
|
|
|
int height = (int)(viewport_size[1] * screen_percentage);
|
|
|
|
|
|
|
|
|
|
/* We need an Array texture so allocate it ourself */
|
2017-06-23 01:33:28 +02:00
|
|
|
if (!txl->planar_pool) {
|
|
|
|
|
if (num_planar_ref > 0) {
|
|
|
|
|
txl->planar_pool = DRW_texture_create_2D_array(width, height, max_ff(1, num_planar_ref),
|
2018-04-30 16:02:24 +02:00
|
|
|
GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
|
2017-07-23 14:03:27 +02:00
|
|
|
txl->planar_depth = DRW_texture_create_2D_array(width, height, max_ff(1, num_planar_ref),
|
2018-04-30 16:02:24 +02:00
|
|
|
GPU_DEPTH_COMPONENT24, 0, NULL);
|
2017-06-23 01:33:28 +02:00
|
|
|
}
|
|
|
|
|
else if (num_planar_ref == 0) {
|
|
|
|
|
/* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still bound to shader. */
|
2018-04-30 16:02:24 +02:00
|
|
|
txl->planar_pool = DRW_texture_create_2D_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
|
|
|
|
|
txl->planar_depth = DRW_texture_create_2D_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL);
|
2017-06-23 01:33:28 +02:00
|
|
|
}
|
2017-06-17 00:08:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-04 17:21:17 +01:00
|
|
|
static void lightprobe_shaders_init(void)
|
2017-04-18 12:50:09 +02:00
|
|
|
{
|
2017-12-04 17:21:17 +01:00
|
|
|
const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
|
2017-06-14 13:45:54 +02:00
|
|
|
#if defined(IRRADIANCE_SH_L2)
|
2017-12-04 17:21:17 +01:00
|
|
|
"#define IRRADIANCE_SH_L2\n"
|
2017-06-14 13:45:54 +02:00
|
|
|
#elif defined(IRRADIANCE_CUBEMAP)
|
2017-12-04 17:21:17 +01:00
|
|
|
"#define IRRADIANCE_CUBEMAP\n"
|
2017-06-14 13:45:54 +02:00
|
|
|
#elif defined(IRRADIANCE_HL2)
|
2017-12-04 17:21:17 +01:00
|
|
|
"#define IRRADIANCE_HL2\n"
|
2017-06-14 13:45:54 +02:00
|
|
|
#endif
|
2017-12-04 17:21:17 +01:00
|
|
|
"#define NOISE_SIZE 64\n";
|
2017-06-14 13:45:54 +02:00
|
|
|
|
2017-12-04 17:21:17 +01:00
|
|
|
char *shader_str = NULL;
|
2018-03-10 00:00:04 +01:00
|
|
|
char *vert_str = NULL;
|
2017-06-14 13:45:54 +02:00
|
|
|
|
2018-01-17 21:40:43 +11:00
|
|
|
shader_str = BLI_string_joinN(
|
2018-03-10 00:00:04 +01:00
|
|
|
datatoc_common_view_lib_glsl,
|
2018-01-21 17:25:10 +01:00
|
|
|
datatoc_common_uniforms_lib_glsl,
|
2018-01-17 21:40:43 +11:00
|
|
|
datatoc_bsdf_common_lib_glsl,
|
|
|
|
|
datatoc_bsdf_sampling_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_filter_glossy_frag_glsl);
|
2018-01-17 20:35:06 +11:00
|
|
|
|
|
|
|
|
e_data.probe_filter_glossy_sh = DRW_shader_create(
|
|
|
|
|
datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, shader_str, filter_defines);
|
|
|
|
|
|
|
|
|
|
e_data.probe_default_sh = DRW_shader_create(
|
|
|
|
|
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, NULL);
|
|
|
|
|
|
2018-05-25 08:06:36 +02:00
|
|
|
e_data.probe_default_studiolight_sh = DRW_shader_create(
|
|
|
|
|
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, "#define LOOKDEV\n");
|
|
|
|
|
|
2017-12-04 17:21:17 +01:00
|
|
|
MEM_freeN(shader_str);
|
|
|
|
|
|
2018-01-17 21:40:43 +11:00
|
|
|
shader_str = BLI_string_joinN(
|
2018-03-10 00:00:04 +01:00
|
|
|
datatoc_common_view_lib_glsl,
|
2018-01-21 17:25:10 +01:00
|
|
|
datatoc_common_uniforms_lib_glsl,
|
2018-01-17 21:40:43 +11:00
|
|
|
datatoc_bsdf_common_lib_glsl,
|
|
|
|
|
datatoc_bsdf_sampling_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_filter_diffuse_frag_glsl);
|
2017-09-28 21:17:57 +02:00
|
|
|
|
2017-12-04 17:21:17 +01:00
|
|
|
e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen(shader_str, filter_defines);
|
2018-01-17 20:35:06 +11:00
|
|
|
|
2017-12-04 17:21:17 +01:00
|
|
|
MEM_freeN(shader_str);
|
2017-06-15 00:10:34 +02:00
|
|
|
|
2018-01-17 21:40:43 +11:00
|
|
|
shader_str = BLI_string_joinN(
|
2018-03-10 00:00:04 +01:00
|
|
|
datatoc_common_view_lib_glsl,
|
2018-01-21 17:25:10 +01:00
|
|
|
datatoc_common_uniforms_lib_glsl,
|
2018-01-17 21:40:43 +11:00
|
|
|
datatoc_bsdf_common_lib_glsl,
|
|
|
|
|
datatoc_bsdf_sampling_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_filter_visibility_frag_glsl);
|
2017-06-15 00:10:34 +02:00
|
|
|
|
2017-12-04 17:21:17 +01:00
|
|
|
e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen(shader_str, filter_defines);
|
2017-06-17 01:59:01 +02:00
|
|
|
|
2017-12-04 17:21:17 +01:00
|
|
|
MEM_freeN(shader_str);
|
2017-06-26 20:37:41 +02:00
|
|
|
|
2018-01-17 21:40:43 +11:00
|
|
|
shader_str = BLI_string_joinN(
|
|
|
|
|
datatoc_octahedron_lib_glsl,
|
2018-03-10 00:00:04 +01:00
|
|
|
datatoc_common_view_lib_glsl,
|
2018-01-21 17:25:10 +01:00
|
|
|
datatoc_common_uniforms_lib_glsl,
|
2018-01-17 21:40:43 +11:00
|
|
|
datatoc_bsdf_common_lib_glsl,
|
|
|
|
|
datatoc_irradiance_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_grid_display_frag_glsl);
|
2018-01-17 20:35:06 +11:00
|
|
|
|
2018-03-10 00:00:04 +01:00
|
|
|
vert_str = BLI_string_joinN(
|
|
|
|
|
datatoc_common_view_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_grid_display_vert_glsl);
|
2018-01-17 20:35:06 +11:00
|
|
|
|
2018-03-10 00:00:04 +01:00
|
|
|
e_data.probe_grid_display_sh = DRW_shader_create(vert_str, NULL, shader_str, filter_defines);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(vert_str);
|
2017-12-04 17:21:17 +01:00
|
|
|
MEM_freeN(shader_str);
|
|
|
|
|
|
2018-01-17 20:35:06 +11:00
|
|
|
e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen(
|
|
|
|
|
datatoc_lightprobe_grid_fill_frag_glsl, filter_defines);
|
|
|
|
|
|
2018-01-17 21:40:43 +11:00
|
|
|
shader_str = BLI_string_joinN(
|
|
|
|
|
datatoc_octahedron_lib_glsl,
|
2018-03-10 00:00:04 +01:00
|
|
|
datatoc_common_view_lib_glsl,
|
2018-01-21 17:25:10 +01:00
|
|
|
datatoc_common_uniforms_lib_glsl,
|
2018-01-17 21:40:43 +11:00
|
|
|
datatoc_bsdf_common_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_cube_display_frag_glsl);
|
2017-12-04 17:21:17 +01:00
|
|
|
|
2018-03-10 00:00:04 +01:00
|
|
|
vert_str = BLI_string_joinN(
|
|
|
|
|
datatoc_common_view_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_cube_display_vert_glsl);
|
|
|
|
|
|
|
|
|
|
e_data.probe_cube_display_sh = DRW_shader_create(vert_str, NULL, shader_str, NULL);
|
2018-01-17 20:35:06 +11:00
|
|
|
|
2018-03-10 00:00:04 +01:00
|
|
|
MEM_freeN(vert_str);
|
2017-12-04 17:21:17 +01:00
|
|
|
MEM_freeN(shader_str);
|
|
|
|
|
|
2018-03-10 00:00:04 +01:00
|
|
|
vert_str = BLI_string_joinN(
|
|
|
|
|
datatoc_common_view_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_planar_display_vert_glsl);
|
|
|
|
|
|
|
|
|
|
shader_str = BLI_string_joinN(
|
|
|
|
|
datatoc_common_view_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_planar_display_frag_glsl);
|
|
|
|
|
|
|
|
|
|
e_data.probe_planar_display_sh = DRW_shader_create(vert_str, NULL, shader_str, NULL);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(vert_str);
|
|
|
|
|
MEM_freeN(shader_str);
|
2017-12-04 17:21:17 +01:00
|
|
|
|
|
|
|
|
e_data.probe_planar_downsample_sh = DRW_shader_create(
|
|
|
|
|
datatoc_lightprobe_planar_downsample_vert_glsl,
|
|
|
|
|
datatoc_lightprobe_planar_downsample_geom_glsl,
|
|
|
|
|
datatoc_lightprobe_planar_downsample_frag_glsl,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
e_data.hammersley = create_hammersley_sample_texture(HAMMERSLEY_SIZE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(vedata))
|
|
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
2017-12-04 17:21:17 +01:00
|
|
|
bool update_all = false;
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
2018-05-16 19:34:24 +02:00
|
|
|
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
|
2017-12-04 17:21:17 +01:00
|
|
|
|
|
|
|
|
/* Shaders */
|
|
|
|
|
if (!e_data.probe_filter_glossy_sh) {
|
|
|
|
|
lightprobe_shaders_init();
|
2017-05-29 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-30 22:29:20 +02:00
|
|
|
if (!sldata->probes) {
|
2017-06-12 20:59:54 +10:00
|
|
|
sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo");
|
2017-09-28 21:17:57 +02:00
|
|
|
sldata->probes->grid_initialized = false;
|
2017-06-12 20:59:54 +10:00
|
|
|
sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL);
|
2017-06-13 17:39:39 +02:00
|
|
|
sldata->grid_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightGrid) * MAX_GRID, NULL);
|
2017-06-17 00:08:03 +02:00
|
|
|
sldata->planar_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_PlanarReflection) * MAX_PLANAR, NULL);
|
2017-04-18 12:50:09 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-06 02:19:28 +01:00
|
|
|
/* Only start doing probes if all materials have finished compiling. */
|
|
|
|
|
sldata->probes->all_materials_updated = true;
|
|
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->spec_toggle = true;
|
|
|
|
|
common_data->ssr_toggle = true;
|
|
|
|
|
common_data->sss_toggle = true;
|
|
|
|
|
|
2018-05-16 19:34:24 +02:00
|
|
|
int prop_bounce_num = scene_eval->eevee.gi_diffuse_bounces;
|
2017-10-02 18:40:51 +02:00
|
|
|
if (sldata->probes->num_bounce != prop_bounce_num) {
|
2017-12-02 14:28:29 +01:00
|
|
|
sldata->probes->num_bounce = prop_bounce_num;
|
|
|
|
|
update_all = true;
|
2017-10-02 18:40:51 +02:00
|
|
|
}
|
2017-10-01 02:19:10 +02:00
|
|
|
|
2018-05-16 19:34:24 +02:00
|
|
|
int prop_cubemap_res = scene_eval->eevee.gi_cubemap_resolution;
|
2017-10-10 21:56:11 +02:00
|
|
|
if (sldata->probes->cubemap_res != prop_cubemap_res) {
|
|
|
|
|
sldata->probes->cubemap_res = prop_cubemap_res;
|
2017-12-02 14:28:29 +01:00
|
|
|
update_all = true;
|
2017-10-10 21:56:11 +02:00
|
|
|
|
|
|
|
|
sldata->probes->target_size = prop_cubemap_res >> 1;
|
|
|
|
|
|
2018-03-05 00:49:24 +01:00
|
|
|
DRW_TEXTURE_FREE_SAFE(sldata->probe_depth_rt);
|
2017-10-10 21:56:11 +02:00
|
|
|
DRW_TEXTURE_FREE_SAFE(sldata->probe_rt);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-16 19:34:24 +02:00
|
|
|
const int visibility_res = scene_eval->eevee.gi_visibility_resolution;
|
2018-01-21 17:25:10 +01:00
|
|
|
if (common_data->prb_irradiance_vis_size != visibility_res) {
|
|
|
|
|
common_data->prb_irradiance_vis_size = visibility_res;
|
2017-12-02 14:28:29 +01:00
|
|
|
update_all = true;
|
2017-06-24 01:46:07 +02:00
|
|
|
}
|
|
|
|
|
|
2017-12-02 14:28:29 +01:00
|
|
|
if (update_all) {
|
2018-03-06 02:19:28 +01:00
|
|
|
sldata->probes->update_world |= PROBE_UPDATE_ALL;
|
2017-12-02 14:28:29 +01:00
|
|
|
sldata->probes->updated_bounce = 0;
|
|
|
|
|
sldata->probes->grid_initialized = false;
|
|
|
|
|
}
|
2017-06-24 01:46:07 +02:00
|
|
|
|
2017-12-02 14:28:29 +01:00
|
|
|
/* Setup Render Target Cubemap */
|
2017-05-30 22:29:20 +02:00
|
|
|
if (!sldata->probe_rt) {
|
2018-04-30 16:02:24 +02:00
|
|
|
sldata->probe_depth_rt = DRW_texture_create_cube(sldata->probes->target_size, GPU_DEPTH_COMPONENT24, 0, NULL);
|
|
|
|
|
sldata->probe_rt = DRW_texture_create_cube(sldata->probes->target_size, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
|
2017-04-18 12:50:09 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
for (int i = 0; i < 6; ++i) {
|
|
|
|
|
GPU_framebuffer_ensure_config(&sldata->probe_face_fb[i], {
|
|
|
|
|
GPU_ATTACHMENT_TEXTURE_CUBEFACE(sldata->probe_depth_rt, i),
|
|
|
|
|
GPU_ATTACHMENT_TEXTURE_CUBEFACE(sldata->probe_rt, i)
|
|
|
|
|
});
|
|
|
|
|
}
|
2017-06-23 19:02:40 +02:00
|
|
|
|
|
|
|
|
/* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */
|
|
|
|
|
if (!e_data.planar_pool_placeholder) {
|
2018-04-30 16:02:24 +02:00
|
|
|
e_data.planar_pool_placeholder = DRW_texture_create_2D_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER, NULL);
|
2017-06-23 19:02:40 +02:00
|
|
|
}
|
2017-07-21 14:27:16 +02:00
|
|
|
|
|
|
|
|
if (!e_data.depth_placeholder) {
|
2018-04-30 16:02:24 +02:00
|
|
|
e_data.depth_placeholder = DRW_texture_create_2D(1, 1, GPU_DEPTH_COMPONENT24, 0, NULL);
|
2017-07-21 14:27:16 +02:00
|
|
|
}
|
2017-07-23 14:03:27 +02:00
|
|
|
if (!e_data.depth_array_placeholder) {
|
2018-04-30 16:02:24 +02:00
|
|
|
e_data.depth_array_placeholder = DRW_texture_create_2D_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL);
|
2017-07-23 14:03:27 +02:00
|
|
|
}
|
2017-04-18 12:50:09 +02:00
|
|
|
}
|
|
|
|
|
|
2017-11-22 10:52:39 -02:00
|
|
|
void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
2017-04-18 12:50:09 +02:00
|
|
|
{
|
2017-06-26 20:37:41 +02:00
|
|
|
EEVEE_TextureList *txl = vedata->txl;
|
|
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
|
|
|
|
EEVEE_StorageList *stl = vedata->stl;
|
2017-06-12 20:59:54 +10:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2018-04-24 12:45:59 +02:00
|
|
|
/* Make sure no aditionnal visibility check runs by default. */
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
pinfo->vis_data.collection = NULL;
|
2018-04-24 12:45:59 +02:00
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
pinfo->do_cube_update = false;
|
2017-06-04 16:50:22 +02:00
|
|
|
pinfo->num_cube = 1; /* at least one for the world */
|
2017-06-14 18:52:53 +02:00
|
|
|
pinfo->num_grid = 1;
|
2017-06-17 00:08:03 +02:00
|
|
|
pinfo->num_planar = 0;
|
2017-12-04 17:20:20 +01:00
|
|
|
pinfo->total_irradiance_samples = 1;
|
2017-06-13 17:39:39 +02:00
|
|
|
memset(pinfo->probes_cube_ref, 0, sizeof(pinfo->probes_cube_ref));
|
|
|
|
|
memset(pinfo->probes_grid_ref, 0, sizeof(pinfo->probes_grid_ref));
|
2017-06-17 00:08:03 +02:00
|
|
|
memset(pinfo->probes_planar_ref, 0, sizeof(pinfo->probes_planar_ref));
|
2017-06-04 12:12:58 +02:00
|
|
|
|
|
|
|
|
{
|
2017-07-31 15:15:42 +02:00
|
|
|
psl->probe_background = DRW_pass_create("World Probe Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2017-06-19 20:18:04 +10:00
|
|
|
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
2017-06-04 12:12:58 +02:00
|
|
|
DRWShadingGroup *grp = NULL;
|
|
|
|
|
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
|
World *wo = scene->world;
|
|
|
|
|
|
|
|
|
|
float *col = ts.colorBackground;
|
2018-05-25 08:06:36 +02:00
|
|
|
|
|
|
|
|
/* LookDev */
|
2018-05-29 12:38:19 +02:00
|
|
|
EEVEE_lookdev_cache_init(vedata, &grp, e_data.probe_default_studiolight_sh, psl->probe_background, wo, pinfo);
|
2018-05-25 08:06:36 +02:00
|
|
|
/* END */
|
|
|
|
|
if (!grp && wo) {
|
2017-06-04 12:12:58 +02:00
|
|
|
col = &wo->horr;
|
2018-03-06 02:19:28 +01:00
|
|
|
bool wo_sh_compiled = true;
|
2017-06-04 12:12:58 +02:00
|
|
|
|
|
|
|
|
if (wo->use_nodes && wo->nodetree) {
|
2018-03-06 02:19:28 +01:00
|
|
|
static float error_col[3] = {1.0f, 0.0f, 1.0f};
|
|
|
|
|
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
|
2017-06-12 20:59:54 +10:00
|
|
|
struct GPUMaterial *gpumat = EEVEE_material_world_lightprobe_get(scene, wo);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2018-03-06 02:19:28 +01:00
|
|
|
GPUMaterialStatus status = GPU_material_status(gpumat);
|
|
|
|
|
|
|
|
|
|
switch (status) {
|
|
|
|
|
case GPU_MAT_SUCCESS:
|
|
|
|
|
grp = DRW_shgroup_material_create(gpumat, psl->probe_background);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
|
|
|
|
|
DRW_shgroup_call_add(grp, geom, NULL);
|
|
|
|
|
wo_sh_compiled = true;
|
|
|
|
|
break;
|
|
|
|
|
case GPU_MAT_QUEUED:
|
|
|
|
|
pinfo->all_materials_updated = false;
|
|
|
|
|
wo_sh_compiled = false;
|
|
|
|
|
/* TODO Bypass probe compilation. */
|
|
|
|
|
col = compile_col;
|
|
|
|
|
break;
|
|
|
|
|
case GPU_MAT_FAILED:
|
|
|
|
|
default:
|
|
|
|
|
wo_sh_compiled = true;
|
|
|
|
|
col = error_col;
|
|
|
|
|
break;
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-01-17 00:23:31 +01:00
|
|
|
|
2018-03-06 02:19:28 +01:00
|
|
|
if (wo->update_flag != 0 || pinfo->prev_world != wo || pinfo->prev_wo_sh_compiled != wo_sh_compiled) {
|
|
|
|
|
pinfo->update_world |= PROBE_UPDATE_ALL;
|
2018-05-25 08:06:36 +02:00
|
|
|
pinfo->studiolight_index = 0;
|
2018-03-06 02:19:28 +01:00
|
|
|
pinfo->prev_wo_sh_compiled = wo_sh_compiled;
|
|
|
|
|
pinfo->prev_world = wo;
|
|
|
|
|
}
|
|
|
|
|
wo->update_flag = 0;
|
2018-01-17 00:23:31 +01:00
|
|
|
}
|
|
|
|
|
else if (pinfo->prev_world) {
|
2018-03-06 02:36:00 +01:00
|
|
|
pinfo->update_world |= PROBE_UPDATE_ALL;
|
2018-05-25 08:06:36 +02:00
|
|
|
pinfo->studiolight_index = 0;
|
2018-03-06 02:19:28 +01:00
|
|
|
pinfo->prev_wo_sh_compiled = false;
|
2018-01-17 00:23:31 +01:00
|
|
|
pinfo->prev_world = NULL;
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fallback if shader fails or if not using nodetree. */
|
|
|
|
|
if (grp == NULL) {
|
2017-06-29 17:32:13 +02:00
|
|
|
grp = DRW_shgroup_create(e_data.probe_default_sh, psl->probe_background);
|
2017-06-04 12:12:58 +02:00
|
|
|
DRW_shgroup_uniform_vec3(grp, "color", col, 1);
|
2017-07-06 18:28:25 +02:00
|
|
|
DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
|
2017-06-29 17:07:41 +02:00
|
|
|
DRW_shgroup_call_add(grp, geom, NULL);
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-29 22:03:57 +02:00
|
|
|
{
|
2017-06-13 17:39:39 +02:00
|
|
|
psl->probe_glossy_compute = DRW_pass_create("LightProbe Glossy Compute", DRW_STATE_WRITE_COLOR);
|
2017-05-29 22:03:57 +02:00
|
|
|
|
2018-02-14 18:59:15 +01:00
|
|
|
DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_filter_glossy_sh, psl->probe_glossy_compute);
|
2018-01-21 23:15:57 +01:00
|
|
|
DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->invsamples_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "roughnessSquared", &pinfo->roughness, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "texelSize", &pinfo->texel_size, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "paddingSize", &pinfo->padding_size, 1);
|
|
|
|
|
DRW_shgroup_uniform_int(grp, "Layer", &pinfo->layer, 1);
|
2017-05-29 22:03:57 +02:00
|
|
|
DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
|
|
|
|
|
// DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
|
2017-05-30 22:29:20 +02:00
|
|
|
DRW_shgroup_uniform_texture(grp, "probeHdr", sldata->probe_rt);
|
2018-02-14 18:59:15 +01:00
|
|
|
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
|
2017-05-29 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2017-06-13 17:39:39 +02:00
|
|
|
psl->probe_diffuse_compute = DRW_pass_create("LightProbe Diffuse Compute", DRW_STATE_WRITE_COLOR);
|
2017-05-29 22:03:57 +02:00
|
|
|
|
2017-06-13 17:39:39 +02:00
|
|
|
DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_filter_diffuse_sh, psl->probe_diffuse_compute);
|
|
|
|
|
#ifdef IRRADIANCE_SH_L2
|
2018-01-21 23:15:57 +01:00
|
|
|
DRW_shgroup_uniform_int(grp, "probeSize", &pinfo->shres, 1);
|
2017-06-13 17:39:39 +02:00
|
|
|
#else
|
2018-01-21 23:15:57 +01:00
|
|
|
DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->invsamples_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1);
|
2017-06-14 13:45:54 +02:00
|
|
|
DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
|
2017-06-13 17:39:39 +02:00
|
|
|
#endif
|
2018-01-21 23:15:57 +01:00
|
|
|
DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
|
2017-05-30 22:29:20 +02:00
|
|
|
DRW_shgroup_uniform_texture(grp, "probeHdr", sldata->probe_rt);
|
2017-05-29 22:03:57 +02:00
|
|
|
|
2017-06-19 20:18:04 +10:00
|
|
|
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
2017-05-29 22:03:57 +02:00
|
|
|
DRW_shgroup_call_add(grp, geom, NULL);
|
|
|
|
|
}
|
2017-06-14 13:45:54 +02:00
|
|
|
|
2017-12-02 14:28:29 +01:00
|
|
|
{
|
|
|
|
|
psl->probe_visibility_compute = DRW_pass_create("LightProbe Visibility Compute", DRW_STATE_WRITE_COLOR);
|
|
|
|
|
|
|
|
|
|
DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_filter_visibility_sh, psl->probe_visibility_compute);
|
2018-01-21 23:15:57 +01:00
|
|
|
DRW_shgroup_uniform_int(grp, "outputSize", &pinfo->shres, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "visibilityRange", &pinfo->visibility_range, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "visibilityBlur", &pinfo->visibility_blur, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->invsamples_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "storedTexelSize", &pinfo->texel_size, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "nearClip", &pinfo->near_clip, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "farClip", &pinfo->far_clip, 1);
|
2017-12-02 14:28:29 +01:00
|
|
|
DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
|
|
|
|
|
DRW_shgroup_uniform_texture(grp, "probeDepth", sldata->probe_depth_rt);
|
|
|
|
|
|
|
|
|
|
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
|
|
|
|
DRW_shgroup_call_add(grp, geom, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-28 21:17:57 +02:00
|
|
|
{
|
|
|
|
|
psl->probe_grid_fill = DRW_pass_create("LightProbe Grid Floodfill", DRW_STATE_WRITE_COLOR);
|
|
|
|
|
|
|
|
|
|
DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_grid_fill_sh, psl->probe_grid_fill);
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &sldata->irradiance_pool);
|
2017-09-28 21:17:57 +02:00
|
|
|
|
|
|
|
|
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
|
|
|
|
DRW_shgroup_call_add(grp, geom, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-14 13:45:54 +02:00
|
|
|
{
|
2018-05-20 19:05:13 +02:00
|
|
|
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
|
2017-06-17 01:59:01 +02:00
|
|
|
psl->probe_display = DRW_pass_create("LightProbe Display", state);
|
2017-06-15 00:10:34 +02:00
|
|
|
|
2018-02-14 18:59:15 +01:00
|
|
|
DRW_shgroup_instance_format(e_data.format_probe_display_cube, {
|
2018-02-15 18:03:55 +11:00
|
|
|
{"probe_id", DRW_ATTRIB_INT, 1},
|
2018-02-14 18:59:15 +01:00
|
|
|
{"probe_location", DRW_ATTRIB_FLOAT, 3},
|
2018-02-15 18:03:55 +11:00
|
|
|
{"sphere_size", DRW_ATTRIB_FLOAT, 1},
|
2018-02-14 18:59:15 +01:00
|
|
|
});
|
|
|
|
|
|
2018-02-15 18:03:55 +11:00
|
|
|
DRWShadingGroup *grp = DRW_shgroup_instance_create(
|
|
|
|
|
e_data.probe_cube_display_sh,
|
|
|
|
|
psl->probe_display,
|
|
|
|
|
DRW_cache_sphere_get(),
|
|
|
|
|
e_data.format_probe_display_cube);
|
2018-02-14 18:59:15 +01:00
|
|
|
stl->g_data->cube_display_shgrp = grp;
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &sldata->probe_pool);
|
2018-01-21 17:25:10 +01:00
|
|
|
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
|
2017-09-30 19:34:23 +02:00
|
|
|
|
2018-02-14 18:59:15 +01:00
|
|
|
DRW_shgroup_instance_format(e_data.format_probe_display_planar, {
|
2018-02-15 18:03:55 +11:00
|
|
|
{"probe_id", DRW_ATTRIB_INT, 1},
|
2018-02-14 18:59:15 +01:00
|
|
|
{"probe_mat", DRW_ATTRIB_FLOAT, 16},
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-15 18:03:55 +11:00
|
|
|
grp = DRW_shgroup_instance_create(
|
|
|
|
|
e_data.probe_planar_display_sh,
|
|
|
|
|
psl->probe_display,
|
|
|
|
|
DRW_cache_quad_get(),
|
|
|
|
|
e_data.format_probe_display_planar);
|
2018-02-14 18:59:15 +01:00
|
|
|
stl->g_data->planar_display_shgrp = grp;
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool);
|
2017-06-14 13:45:54 +02:00
|
|
|
}
|
2017-06-26 20:37:41 +02:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", DRW_STATE_WRITE_COLOR);
|
|
|
|
|
|
2018-03-01 19:27:38 +01:00
|
|
|
DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_planar_downsample_sh, psl->probe_planar_downsample_ps);
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(grp, "source", &txl->planar_pool);
|
2018-01-21 17:25:10 +01:00
|
|
|
DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
|
2018-05-11 07:48:52 +02:00
|
|
|
DRW_shgroup_call_instances_add(grp, DRW_cache_fullscreen_quad_get(), NULL, (uint *)&pinfo->num_planar);
|
2017-06-26 20:37:41 +02:00
|
|
|
}
|
2017-04-18 12:50:09 +02:00
|
|
|
}
|
|
|
|
|
|
2018-04-24 12:45:59 +02:00
|
|
|
bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data)
|
|
|
|
|
{
|
|
|
|
|
EEVEE_ObjectEngineData *oed = (EEVEE_ObjectEngineData *)user_data;
|
|
|
|
|
|
|
|
|
|
/* test disabled if group is NULL */
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
if (oed->test_data->collection == NULL)
|
2018-04-24 12:45:59 +02:00
|
|
|
return vis_in;
|
|
|
|
|
|
|
|
|
|
if (oed->test_data->cached == false)
|
|
|
|
|
oed->ob_vis_dirty = true;
|
|
|
|
|
|
|
|
|
|
/* early out, don't need to compute ob_vis yet. */
|
|
|
|
|
if (vis_in == false)
|
|
|
|
|
return vis_in;
|
|
|
|
|
|
|
|
|
|
if (oed->ob_vis_dirty) {
|
|
|
|
|
oed->ob_vis_dirty = false;
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
oed->ob_vis = BKE_collection_has_object_recursive(oed->test_data->collection, oed->ob);
|
2018-04-24 12:45:59 +02:00
|
|
|
oed->ob_vis = (oed->test_data->invert) ? !oed->ob_vis : oed->ob_vis;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return vis_in && oed->ob_vis;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-22 10:52:39 -02:00
|
|
|
void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
|
2017-04-18 12:50:09 +02:00
|
|
|
{
|
2017-06-12 20:59:54 +10:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2017-06-13 17:39:39 +02:00
|
|
|
LightProbe *probe = (LightProbe *)ob->data;
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2017-06-13 17:39:39 +02:00
|
|
|
if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= MAX_PROBE) ||
|
2018-03-08 17:56:30 +01:00
|
|
|
(probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= MAX_PROBE) ||
|
|
|
|
|
(probe->type == LIGHTPROBE_TYPE_PLANAR && pinfo->num_grid >= MAX_PLANAR))
|
2017-06-13 17:39:39 +02:00
|
|
|
{
|
2017-06-08 21:48:50 +02:00
|
|
|
printf("Too much probes in the scene !!!\n");
|
2017-06-13 17:39:39 +02:00
|
|
|
return;
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-08 17:56:30 +01:00
|
|
|
if (probe->type == LIGHTPROBE_TYPE_PLANAR) {
|
|
|
|
|
/* See if this planar probe is inside the view frustum. If not, no need to update it. */
|
|
|
|
|
/* NOTE: this could be bypassed if we want feedback loop mirrors for rendering. */
|
|
|
|
|
BoundBox bbox; float tmp[4][4];
|
|
|
|
|
const float min[3] = {-1.0f, -1.0f, -1.0f};
|
|
|
|
|
const float max[3] = { 1.0f, 1.0f, 1.0f};
|
|
|
|
|
BKE_boundbox_init_from_minmax(&bbox, min, max);
|
|
|
|
|
|
|
|
|
|
copy_m4_m4(tmp, ob->obmat);
|
|
|
|
|
normalize_v3(tmp[2]);
|
|
|
|
|
mul_v3_fl(tmp[2], probe->distinf);
|
|
|
|
|
|
|
|
|
|
for (int v = 0; v < 8; ++v) {
|
|
|
|
|
mul_m4_v3(tmp, bbox.vec[v]);
|
|
|
|
|
}
|
|
|
|
|
if (!DRW_culling_box_test(&bbox)) {
|
|
|
|
|
return; /* Culled */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-29 10:36:58 +01:00
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2017-06-14 18:52:53 +02:00
|
|
|
ped->num_cell = probe->grid_resolution_x * probe->grid_resolution_y * probe->grid_resolution_z;
|
|
|
|
|
|
2017-12-04 17:20:20 +01:00
|
|
|
if ((probe->type == LIGHTPROBE_TYPE_GRID) &&
|
2018-02-15 18:03:55 +11:00
|
|
|
((pinfo->total_irradiance_samples + ped->num_cell) >= MAX_IRRADIANCE_SAMPLES))
|
2017-12-04 17:20:20 +01:00
|
|
|
{
|
|
|
|
|
printf("Too much grid samples !!!\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-28 17:05:52 +01:00
|
|
|
if (ped->need_full_update) {
|
|
|
|
|
ped->need_full_update = false;
|
|
|
|
|
|
2017-06-13 17:39:39 +02:00
|
|
|
ped->need_update = true;
|
2017-06-15 00:10:34 +02:00
|
|
|
ped->probe_id = 0;
|
2017-06-15 00:23:00 +02:00
|
|
|
if (probe->type == LIGHTPROBE_TYPE_GRID) {
|
|
|
|
|
ped->updated_cells = 0;
|
2017-09-28 21:16:02 +02:00
|
|
|
ped->updated_lvl = 0;
|
2017-06-15 00:23:00 +02:00
|
|
|
pinfo->updated_bounce = 0;
|
2017-09-28 21:17:57 +02:00
|
|
|
pinfo->grid_initialized = false;
|
2017-06-15 00:23:00 +02:00
|
|
|
}
|
2017-06-13 17:39:39 +02:00
|
|
|
}
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2018-03-06 02:19:28 +01:00
|
|
|
if (pinfo->update_world) {
|
2017-06-13 17:39:39 +02:00
|
|
|
ped->need_update = true;
|
2017-06-14 18:52:53 +02:00
|
|
|
ped->updated_cells = 0;
|
2017-09-28 21:16:02 +02:00
|
|
|
ped->updated_lvl = 0;
|
2017-06-15 00:10:34 +02:00
|
|
|
ped->probe_id = 0;
|
2017-06-13 17:39:39 +02:00
|
|
|
}
|
|
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
pinfo->do_cube_update |= ped->need_update;
|
|
|
|
|
|
2018-03-08 17:56:30 +01:00
|
|
|
switch (probe->type) {
|
|
|
|
|
case LIGHTPROBE_TYPE_CUBE:
|
|
|
|
|
pinfo->probes_cube_ref[pinfo->num_cube] = ob;
|
|
|
|
|
pinfo->num_cube++;
|
|
|
|
|
break;
|
|
|
|
|
case LIGHTPROBE_TYPE_PLANAR:
|
|
|
|
|
pinfo->probes_planar_ref[pinfo->num_planar] = ob;
|
|
|
|
|
pinfo->num_planar++;
|
|
|
|
|
break;
|
|
|
|
|
case LIGHTPROBE_TYPE_GRID:
|
|
|
|
|
pinfo->probes_grid_ref[pinfo->num_grid] = ob;
|
|
|
|
|
pinfo->num_grid++;
|
|
|
|
|
pinfo->total_irradiance_samples += ped->num_cell;
|
|
|
|
|
break;
|
2017-06-13 17:39:39 +02:00
|
|
|
}
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
/* TODO find a nice name to push it to math_matrix.c */
|
|
|
|
|
static void scale_m4_v3(float R[4][4], float v[3])
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
|
|
|
mul_v3_v3(R[i], v);
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-08 01:35:16 +01:00
|
|
|
static void EEVEE_planar_reflections_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl)
|
|
|
|
|
{
|
|
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
|
|
|
|
Object *ob;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; (ob = pinfo->probes_planar_ref[i]) && (i < MAX_PLANAR); i++) {
|
|
|
|
|
LightProbe *probe = (LightProbe *)ob->data;
|
|
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
|
|
|
|
|
|
|
|
|
ped->probe_id = i;
|
|
|
|
|
|
|
|
|
|
/* Debug Display */
|
|
|
|
|
if (DRW_state_draw_support() &&
|
|
|
|
|
(probe->flag & LIGHTPROBE_FLAG_SHOW_DATA))
|
|
|
|
|
{
|
|
|
|
|
DRW_shgroup_call_dynamic_add(stl->g_data->planar_display_shgrp, &ped->probe_id, ob->obmat);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void EEVEE_planar_reflections_updates(EEVEE_ViewLayerData *sldata)
|
2017-06-17 00:08:03 +02:00
|
|
|
{
|
|
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
|
|
|
|
Object *ob;
|
|
|
|
|
float mtx[4][4], normat[4][4], imat[4][4], rangemat[4][4];
|
|
|
|
|
|
2018-03-08 01:35:16 +01:00
|
|
|
float viewmat[4][4];
|
2017-06-17 00:08:03 +02:00
|
|
|
DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
|
|
|
|
|
|
|
|
|
|
zero_m4(rangemat);
|
|
|
|
|
rangemat[0][0] = rangemat[1][1] = rangemat[2][2] = 0.5f;
|
|
|
|
|
rangemat[3][0] = rangemat[3][1] = rangemat[3][2] = 0.5f;
|
|
|
|
|
rangemat[3][3] = 1.0f;
|
|
|
|
|
|
|
|
|
|
/* PLANAR REFLECTION */
|
|
|
|
|
for (int i = 0; (ob = pinfo->probes_planar_ref[i]) && (i < MAX_PLANAR); i++) {
|
|
|
|
|
LightProbe *probe = (LightProbe *)ob->data;
|
|
|
|
|
EEVEE_PlanarReflection *eplanar = &pinfo->planar_data[i];
|
2017-11-29 10:36:58 +01:00
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
2017-06-17 00:08:03 +02:00
|
|
|
/* Computing mtx : matrix that mirror position around object's XY plane. */
|
|
|
|
|
normalize_m4_m4(normat, ob->obmat); /* object > world */
|
|
|
|
|
invert_m4_m4(imat, normat); /* world > object */
|
|
|
|
|
float reflect[3] = {1.0f, 1.0f, -1.0f}; /* XY reflection plane */
|
|
|
|
|
scale_m4_v3(imat, reflect); /* world > object > mirrored obj */
|
|
|
|
|
mul_m4_m4m4(mtx, normat, imat); /* world > object > mirrored obj > world */
|
|
|
|
|
/* Reflect Camera Matrix. */
|
2018-03-07 23:25:49 +01:00
|
|
|
mul_m4_m4m4(ped->mats.mat[DRW_MAT_VIEW], viewmat, mtx);
|
2017-06-17 00:08:03 +02:00
|
|
|
/* TODO FOV margin */
|
2018-03-08 01:35:16 +01:00
|
|
|
/* Temporal sampling jitter should be already applied to the DRW_MAT_WIN. */
|
|
|
|
|
DRW_viewport_matrix_get(ped->mats.mat[DRW_MAT_WIN], DRW_MAT_WIN);
|
|
|
|
|
/* Apply Projection Matrix. */
|
2018-03-07 23:25:49 +01:00
|
|
|
mul_m4_m4m4(ped->mats.mat[DRW_MAT_PERS], ped->mats.mat[DRW_MAT_WIN], ped->mats.mat[DRW_MAT_VIEW]);
|
2017-06-17 00:08:03 +02:00
|
|
|
/* This is the matrix used to reconstruct texture coordinates.
|
|
|
|
|
* We use the original view matrix because it does not create
|
|
|
|
|
* visual artifacts if receiver is not perfectly aligned with
|
|
|
|
|
* the planar reflection probe. */
|
2018-03-07 23:25:49 +01:00
|
|
|
mul_m4_m4m4(eplanar->reflectionmat, ped->mats.mat[DRW_MAT_WIN], viewmat); /* TODO FOV margin */
|
2017-06-17 00:08:03 +02:00
|
|
|
/* Convert from [-1, 1] to [0, 1] (NDC to Texture coord). */
|
|
|
|
|
mul_m4_m4m4(eplanar->reflectionmat, rangemat, eplanar->reflectionmat);
|
|
|
|
|
|
|
|
|
|
/* Compute clip plane equation / normal. */
|
|
|
|
|
float refpoint[3];
|
|
|
|
|
copy_v3_v3(eplanar->plane_equation, ob->obmat[2]);
|
|
|
|
|
normalize_v3(eplanar->plane_equation); /* plane normal */
|
2017-06-17 01:56:45 +02:00
|
|
|
eplanar->plane_equation[3] = -dot_v3v3(eplanar->plane_equation, ob->obmat[3]);
|
|
|
|
|
|
|
|
|
|
/* Compute offset plane equation (fix missing texels near reflection plane). */
|
|
|
|
|
copy_v3_v3(ped->planer_eq_offset, eplanar->plane_equation);
|
2017-06-17 00:08:03 +02:00
|
|
|
mul_v3_v3fl(refpoint, eplanar->plane_equation, -probe->clipsta);
|
|
|
|
|
add_v3_v3(refpoint, ob->obmat[3]);
|
2017-06-17 01:56:45 +02:00
|
|
|
ped->planer_eq_offset[3] = -dot_v3v3(eplanar->plane_equation, refpoint);
|
2017-06-17 00:08:03 +02:00
|
|
|
|
|
|
|
|
/* Compute XY clip planes. */
|
|
|
|
|
normalize_v3_v3(eplanar->clip_vec_x, ob->obmat[0]);
|
|
|
|
|
normalize_v3_v3(eplanar->clip_vec_y, ob->obmat[1]);
|
|
|
|
|
|
|
|
|
|
float vec[3] = {0.0f, 0.0f, 0.0f};
|
|
|
|
|
vec[0] = 1.0f; vec[1] = 0.0f; vec[2] = 0.0f;
|
|
|
|
|
mul_m4_v3(ob->obmat, vec); /* Point on the edge */
|
|
|
|
|
eplanar->clip_edge_x_pos = dot_v3v3(eplanar->clip_vec_x, vec);
|
|
|
|
|
|
|
|
|
|
vec[0] = 0.0f; vec[1] = 1.0f; vec[2] = 0.0f;
|
|
|
|
|
mul_m4_v3(ob->obmat, vec); /* Point on the edge */
|
|
|
|
|
eplanar->clip_edge_y_pos = dot_v3v3(eplanar->clip_vec_y, vec);
|
|
|
|
|
|
|
|
|
|
vec[0] = -1.0f; vec[1] = 0.0f; vec[2] = 0.0f;
|
|
|
|
|
mul_m4_v3(ob->obmat, vec); /* Point on the edge */
|
|
|
|
|
eplanar->clip_edge_x_neg = dot_v3v3(eplanar->clip_vec_x, vec);
|
|
|
|
|
|
|
|
|
|
vec[0] = 0.0f; vec[1] = -1.0f; vec[2] = 0.0f;
|
|
|
|
|
mul_m4_v3(ob->obmat, vec); /* Point on the edge */
|
|
|
|
|
eplanar->clip_edge_y_neg = dot_v3v3(eplanar->clip_vec_y, vec);
|
|
|
|
|
|
|
|
|
|
/* Facing factors */
|
|
|
|
|
float max_angle = max_ff(1e-2f, probe->falloff) * M_PI * 0.5f;
|
|
|
|
|
float min_angle = 0.0f;
|
|
|
|
|
eplanar->facing_scale = 1.0f / max_ff(1e-8f, cosf(min_angle) - cosf(max_angle));
|
|
|
|
|
eplanar->facing_bias = -min_ff(1.0f - 1e-8f, cosf(max_angle)) * eplanar->facing_scale;
|
|
|
|
|
|
|
|
|
|
/* Distance factors */
|
|
|
|
|
float max_dist = probe->distinf;
|
|
|
|
|
float min_dist = min_ff(1.0f - 1e-8f, 1.0f - probe->falloff) * probe->distinf;
|
|
|
|
|
eplanar->attenuation_scale = -1.0f / max_ff(1e-8f, max_dist - min_dist);
|
|
|
|
|
eplanar->attenuation_bias = max_dist * -eplanar->attenuation_scale;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-22 10:52:39 -02:00
|
|
|
static void EEVEE_lightprobes_updates(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, EEVEE_StorageList *stl)
|
2017-06-08 21:48:50 +02:00
|
|
|
{
|
2017-06-12 20:59:54 +10:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2017-06-08 21:48:50 +02:00
|
|
|
Object *ob;
|
|
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
/* CUBE REFLECTION */
|
2017-06-13 17:39:39 +02:00
|
|
|
for (int i = 1; (ob = pinfo->probes_cube_ref[i]) && (i < MAX_PROBE); i++) {
|
2017-06-12 20:59:54 +10:00
|
|
|
LightProbe *probe = (LightProbe *)ob->data;
|
|
|
|
|
EEVEE_LightProbe *eprobe = &pinfo->probe_data[i];
|
2017-11-29 10:36:58 +01:00
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2017-06-13 17:39:39 +02:00
|
|
|
/* Update transforms */
|
|
|
|
|
copy_v3_v3(eprobe->position, ob->obmat[3]);
|
|
|
|
|
|
2017-06-09 22:30:49 +02:00
|
|
|
/* Attenuation */
|
|
|
|
|
eprobe->attenuation_type = probe->attenuation_type;
|
|
|
|
|
eprobe->attenuation_fac = 1.0f / max_ff(1e-8f, probe->falloff);
|
|
|
|
|
|
|
|
|
|
unit_m4(eprobe->attenuationmat);
|
2017-06-09 23:21:23 +02:00
|
|
|
scale_m4_fl(eprobe->attenuationmat, probe->distinf);
|
|
|
|
|
mul_m4_m4m4(eprobe->attenuationmat, ob->obmat, eprobe->attenuationmat);
|
2017-06-09 22:30:49 +02:00
|
|
|
invert_m4(eprobe->attenuationmat);
|
|
|
|
|
|
|
|
|
|
/* Parallax */
|
|
|
|
|
float dist;
|
2017-06-12 20:59:54 +10:00
|
|
|
if ((probe->flag & LIGHTPROBE_FLAG_CUSTOM_PARALLAX) != 0) {
|
2017-06-09 22:30:49 +02:00
|
|
|
eprobe->parallax_type = probe->parallax_type;
|
|
|
|
|
dist = probe->distpar;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
eprobe->parallax_type = probe->attenuation_type;
|
|
|
|
|
dist = probe->distinf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unit_m4(eprobe->parallaxmat);
|
2017-06-09 23:21:23 +02:00
|
|
|
scale_m4_fl(eprobe->parallaxmat, dist);
|
|
|
|
|
mul_m4_m4m4(eprobe->parallaxmat, ob->obmat, eprobe->parallaxmat);
|
2017-06-09 22:30:49 +02:00
|
|
|
invert_m4(eprobe->parallaxmat);
|
2017-06-15 00:10:34 +02:00
|
|
|
|
|
|
|
|
/* Debug Display */
|
2017-12-14 11:46:49 -02:00
|
|
|
if (DRW_state_draw_support() &&
|
2017-09-21 12:55:14 +02:00
|
|
|
(probe->flag & LIGHTPROBE_FLAG_SHOW_DATA))
|
|
|
|
|
{
|
2017-09-30 19:34:23 +02:00
|
|
|
ped->probe_size = probe->data_draw_size * 0.1f;
|
2017-09-21 12:55:14 +02:00
|
|
|
DRW_shgroup_call_dynamic_add(
|
2017-09-30 19:34:23 +02:00
|
|
|
stl->g_data->cube_display_shgrp, &ped->probe_id, ob->obmat[3], &ped->probe_size);
|
2017-06-15 00:10:34 +02:00
|
|
|
}
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
2017-06-13 17:39:39 +02:00
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
/* IRRADIANCE GRID */
|
2017-06-13 17:39:39 +02:00
|
|
|
int offset = 1; /* to account for the world probe */
|
2017-06-14 18:52:53 +02:00
|
|
|
for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_GRID); i++) {
|
2017-06-13 17:39:39 +02:00
|
|
|
LightProbe *probe = (LightProbe *)ob->data;
|
|
|
|
|
EEVEE_LightGrid *egrid = &pinfo->grid_data[i];
|
2017-11-29 10:36:58 +01:00
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
2017-06-13 17:39:39 +02:00
|
|
|
|
2017-12-02 00:59:58 +01:00
|
|
|
/* If one grid has move we need to recompute all the lighting. */
|
|
|
|
|
if (!pinfo->grid_initialized) {
|
|
|
|
|
ped->updated_cells = 0;
|
|
|
|
|
ped->updated_lvl = 0;
|
|
|
|
|
ped->need_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-28 21:16:02 +02:00
|
|
|
/* Add one for level 0 */
|
|
|
|
|
ped->max_lvl = 1.0f + floorf(log2f((float)MAX3(probe->grid_resolution_x,
|
|
|
|
|
probe->grid_resolution_y,
|
|
|
|
|
probe->grid_resolution_z)));
|
|
|
|
|
|
2017-06-13 17:39:39 +02:00
|
|
|
egrid->offset = offset;
|
2017-06-14 22:45:20 +02:00
|
|
|
float fac = 1.0f / max_ff(1e-8f, probe->falloff);
|
|
|
|
|
egrid->attenuation_scale = fac / max_ff(1e-8f, probe->distinf);
|
|
|
|
|
egrid->attenuation_bias = fac;
|
2017-06-13 17:39:39 +02:00
|
|
|
|
|
|
|
|
/* Set offset for the next grid */
|
2017-06-14 18:52:53 +02:00
|
|
|
offset += ped->num_cell;
|
2017-06-13 17:39:39 +02:00
|
|
|
|
|
|
|
|
/* Update transforms */
|
2017-06-14 18:52:53 +02:00
|
|
|
float cell_dim[3], half_cell_dim[3];
|
|
|
|
|
cell_dim[0] = 2.0f / (float)(probe->grid_resolution_x);
|
|
|
|
|
cell_dim[1] = 2.0f / (float)(probe->grid_resolution_y);
|
|
|
|
|
cell_dim[2] = 2.0f / (float)(probe->grid_resolution_z);
|
|
|
|
|
|
|
|
|
|
mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f);
|
2017-06-13 17:39:39 +02:00
|
|
|
|
2017-06-14 22:45:20 +02:00
|
|
|
/* Matrix converting world space to cell ranges. */
|
|
|
|
|
invert_m4_m4(egrid->mat, ob->obmat);
|
|
|
|
|
|
2017-06-13 17:39:39 +02:00
|
|
|
/* First cell. */
|
2017-06-14 18:52:53 +02:00
|
|
|
copy_v3_fl(egrid->corner, -1.0f);
|
|
|
|
|
add_v3_v3(egrid->corner, half_cell_dim);
|
2017-06-13 17:39:39 +02:00
|
|
|
mul_m4_v3(ob->obmat, egrid->corner);
|
|
|
|
|
|
|
|
|
|
/* Opposite neighbor cell. */
|
2017-06-14 18:52:53 +02:00
|
|
|
copy_v3_fl3(egrid->increment_x, cell_dim[0], 0.0f, 0.0f);
|
|
|
|
|
add_v3_v3(egrid->increment_x, half_cell_dim);
|
2017-06-13 17:39:39 +02:00
|
|
|
add_v3_fl(egrid->increment_x, -1.0f);
|
|
|
|
|
mul_m4_v3(ob->obmat, egrid->increment_x);
|
|
|
|
|
sub_v3_v3(egrid->increment_x, egrid->corner);
|
|
|
|
|
|
2017-06-14 18:52:53 +02:00
|
|
|
copy_v3_fl3(egrid->increment_y, 0.0f, cell_dim[1], 0.0f);
|
|
|
|
|
add_v3_v3(egrid->increment_y, half_cell_dim);
|
2017-06-13 17:39:39 +02:00
|
|
|
add_v3_fl(egrid->increment_y, -1.0f);
|
|
|
|
|
mul_m4_v3(ob->obmat, egrid->increment_y);
|
|
|
|
|
sub_v3_v3(egrid->increment_y, egrid->corner);
|
|
|
|
|
|
2017-06-14 18:52:53 +02:00
|
|
|
copy_v3_fl3(egrid->increment_z, 0.0f, 0.0f, cell_dim[2]);
|
|
|
|
|
add_v3_v3(egrid->increment_z, half_cell_dim);
|
2017-06-13 17:39:39 +02:00
|
|
|
add_v3_fl(egrid->increment_z, -1.0f);
|
|
|
|
|
mul_m4_v3(ob->obmat, egrid->increment_z);
|
|
|
|
|
sub_v3_v3(egrid->increment_z, egrid->corner);
|
|
|
|
|
|
|
|
|
|
copy_v3_v3_int(egrid->resolution, &probe->grid_resolution_x);
|
2017-06-14 13:45:54 +02:00
|
|
|
|
2017-12-02 14:28:29 +01:00
|
|
|
/* Visibility bias */
|
|
|
|
|
egrid->visibility_bias = 0.05f * probe->vis_bias;
|
|
|
|
|
egrid->visibility_bleed = probe->vis_bleedbias;
|
2018-02-15 21:38:24 +11:00
|
|
|
egrid->visibility_range = (
|
|
|
|
|
sqrtf(max_fff(len_squared_v3(egrid->increment_x),
|
|
|
|
|
len_squared_v3(egrid->increment_y),
|
|
|
|
|
len_squared_v3(egrid->increment_z))) + 1.0f);
|
2017-12-02 14:28:29 +01:00
|
|
|
|
2017-06-14 13:45:54 +02:00
|
|
|
/* Debug Display */
|
2017-12-14 11:46:49 -02:00
|
|
|
if (DRW_state_draw_support() &&
|
2017-09-21 12:55:14 +02:00
|
|
|
(probe->flag & LIGHTPROBE_FLAG_SHOW_DATA))
|
|
|
|
|
{
|
2018-03-01 19:27:38 +01:00
|
|
|
DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_grid_display_sh, psl->probe_display);
|
2017-06-14 13:45:54 +02:00
|
|
|
DRW_shgroup_uniform_int(grp, "offset", &egrid->offset, 1);
|
|
|
|
|
DRW_shgroup_uniform_ivec3(grp, "grid_resolution", egrid->resolution, 1);
|
|
|
|
|
DRW_shgroup_uniform_vec3(grp, "corner", egrid->corner, 1);
|
|
|
|
|
DRW_shgroup_uniform_vec3(grp, "increment_x", egrid->increment_x, 1);
|
|
|
|
|
DRW_shgroup_uniform_vec3(grp, "increment_y", egrid->increment_y, 1);
|
|
|
|
|
DRW_shgroup_uniform_vec3(grp, "increment_z", egrid->increment_z, 1);
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &sldata->irradiance_pool);
|
2017-06-15 00:10:34 +02:00
|
|
|
DRW_shgroup_uniform_float(grp, "sphere_size", &probe->data_draw_size, 1);
|
2018-05-11 07:48:52 +02:00
|
|
|
DRW_shgroup_call_instances_add(grp, DRW_cache_sphere_get(), NULL, (uint *)&ped->num_cell);
|
2017-06-14 13:45:54 +02:00
|
|
|
}
|
2017-06-13 17:39:39 +02:00
|
|
|
}
|
2017-04-18 12:50:09 +02:00
|
|
|
}
|
|
|
|
|
|
2017-11-22 10:52:39 -02:00
|
|
|
void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
2017-04-18 12:50:09 +02:00
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
2017-06-12 20:59:54 +10:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2017-06-08 21:48:50 +02:00
|
|
|
Object *ob;
|
2017-04-18 12:50:09 +02:00
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
/* Setup enough layers. */
|
|
|
|
|
/* Free textures if number mismatch. */
|
|
|
|
|
if (pinfo->num_cube != pinfo->cache_num_cube) {
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
|
2018-03-06 02:36:00 +01:00
|
|
|
pinfo->cache_num_cube = pinfo->num_cube;
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
if (pinfo->num_planar != pinfo->cache_num_planar) {
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_pool);
|
2017-07-23 14:03:27 +02:00
|
|
|
DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_depth);
|
2017-06-17 00:08:03 +02:00
|
|
|
pinfo->cache_num_planar = pinfo->num_planar;
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-04 17:20:20 +01:00
|
|
|
int irr_size[3];
|
2018-01-21 17:25:10 +01:00
|
|
|
irradiance_pool_size_get(common_data->prb_irradiance_vis_size, pinfo->total_irradiance_samples, irr_size);
|
2017-12-04 17:20:20 +01:00
|
|
|
|
|
|
|
|
if ((irr_size[0] != pinfo->cache_irradiance_size[0]) ||
|
|
|
|
|
(irr_size[1] != pinfo->cache_irradiance_size[1]) ||
|
|
|
|
|
(irr_size[2] != pinfo->cache_irradiance_size[2]))
|
|
|
|
|
{
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(sldata->irradiance_pool);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(sldata->irradiance_rt);
|
|
|
|
|
copy_v3_v3_int(pinfo->cache_irradiance_size, irr_size);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
/* XXX this should be run each frame as it ensure planar_depth is set */
|
|
|
|
|
planar_pool_ensure_alloc(vedata, pinfo->num_planar);
|
|
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
if (!sldata->probe_pool) {
|
2017-10-10 21:56:11 +02:00
|
|
|
sldata->probe_pool = DRW_texture_create_2D_array(pinfo->cubemap_res, pinfo->cubemap_res, max_ff(1, pinfo->num_cube),
|
2018-04-30 16:02:24 +02:00
|
|
|
GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
|
2017-06-08 21:48:50 +02:00
|
|
|
if (sldata->probe_filter_fb) {
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
|
|
|
|
/* Tag probes to refresh */
|
2018-03-06 02:19:28 +01:00
|
|
|
pinfo->update_world |= PROBE_UPDATE_CUBE;
|
2018-03-06 02:36:00 +01:00
|
|
|
}
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2018-03-06 02:36:00 +01:00
|
|
|
if ((pinfo->update_world & PROBE_UPDATE_CUBE) != 0) {
|
|
|
|
|
common_data->prb_num_render_cube = 0;
|
2017-06-13 17:39:39 +02:00
|
|
|
for (int i = 1; (ob = pinfo->probes_cube_ref[i]) && (i < MAX_PROBE); i++) {
|
2017-11-29 10:36:58 +01:00
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
2017-06-08 21:48:50 +02:00
|
|
|
ped->need_update = true;
|
|
|
|
|
ped->ready_to_shade = false;
|
2017-06-15 00:10:34 +02:00
|
|
|
ped->probe_id = 0;
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-14 18:52:53 +02:00
|
|
|
#ifdef IRRADIANCE_SH_L2
|
|
|
|
|
/* we need a signed format for Spherical Harmonics */
|
2018-04-30 16:02:24 +02:00
|
|
|
int irradiance_format = GPU_RGBA16F;
|
2017-06-14 18:52:53 +02:00
|
|
|
#else
|
2018-04-30 16:02:24 +02:00
|
|
|
int irradiance_format = GPU_RGBA8;
|
2017-06-14 18:52:53 +02:00
|
|
|
#endif
|
|
|
|
|
|
2017-10-02 18:40:51 +02:00
|
|
|
if (!sldata->irradiance_pool || !sldata->irradiance_rt) {
|
|
|
|
|
if (!sldata->irradiance_pool) {
|
2017-12-04 17:20:20 +01:00
|
|
|
sldata->irradiance_pool = DRW_texture_create_2D_array(irr_size[0], irr_size[1], irr_size[2],
|
2017-12-02 14:28:29 +01:00
|
|
|
irradiance_format, DRW_TEX_FILTER, NULL);
|
2017-10-02 18:40:51 +02:00
|
|
|
}
|
|
|
|
|
if (!sldata->irradiance_rt) {
|
2017-12-04 17:20:20 +01:00
|
|
|
sldata->irradiance_rt = DRW_texture_create_2D_array(irr_size[0], irr_size[1], irr_size[2],
|
2017-12-02 14:28:29 +01:00
|
|
|
irradiance_format, DRW_TEX_FILTER, NULL);
|
2017-06-14 22:46:48 +02:00
|
|
|
}
|
2018-03-06 02:36:00 +01:00
|
|
|
/* Tag probes to refresh */
|
2018-03-06 02:19:28 +01:00
|
|
|
pinfo->update_world |= PROBE_UPDATE_GRID;
|
2018-03-06 02:36:00 +01:00
|
|
|
pinfo->grid_initialized = false;
|
|
|
|
|
}
|
2017-06-14 22:46:48 +02:00
|
|
|
|
2018-03-06 02:36:00 +01:00
|
|
|
if ((pinfo->update_world & PROBE_UPDATE_GRID) != 0) {
|
|
|
|
|
common_data->prb_num_render_grid = 0;
|
|
|
|
|
pinfo->updated_bounce = 0;
|
2017-06-14 22:46:48 +02:00
|
|
|
for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_PROBE); i++) {
|
2017-11-29 10:36:58 +01:00
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
2017-06-14 22:46:48 +02:00
|
|
|
ped->need_update = true;
|
|
|
|
|
ped->updated_cells = 0;
|
|
|
|
|
}
|
2017-06-14 18:52:53 +02:00
|
|
|
}
|
|
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
if (common_data->prb_num_render_grid > pinfo->num_grid) {
|
2017-10-10 19:21:32 +02:00
|
|
|
/* This can happen when deleting a probe. */
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_num_render_grid = pinfo->num_grid;
|
2017-10-10 19:21:32 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-08 01:35:16 +01:00
|
|
|
EEVEE_planar_reflections_cache_finish(sldata, vedata->stl);
|
|
|
|
|
|
2017-06-15 00:10:34 +02:00
|
|
|
EEVEE_lightprobes_updates(sldata, vedata->psl, vedata->stl);
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2017-06-04 16:50:22 +02:00
|
|
|
DRW_uniformbuffer_update(sldata->probe_ubo, &sldata->probes->probe_data);
|
2017-06-13 17:39:39 +02:00
|
|
|
DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
|
2017-04-18 12:50:09 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-26 20:37:41 +02:00
|
|
|
static void downsample_planar(void *vedata, int level)
|
|
|
|
|
{
|
|
|
|
|
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
|
|
|
|
|
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
|
|
|
|
|
|
|
|
|
const float *size = DRW_viewport_size_get();
|
2018-01-21 17:25:10 +01:00
|
|
|
copy_v2_v2(stl->g_data->planar_texel_size, size);
|
2017-06-26 20:37:41 +02:00
|
|
|
for (int i = 0; i < level - 1; ++i) {
|
2018-01-21 17:25:10 +01:00
|
|
|
stl->g_data->planar_texel_size[0] /= 2.0f;
|
|
|
|
|
stl->g_data->planar_texel_size[1] /= 2.0f;
|
|
|
|
|
min_ff(floorf(stl->g_data->planar_texel_size[0]), 1.0f);
|
|
|
|
|
min_ff(floorf(stl->g_data->planar_texel_size[1]), 1.0f);
|
2017-06-26 20:37:41 +02:00
|
|
|
}
|
2018-01-21 17:25:10 +01:00
|
|
|
invert_v2(stl->g_data->planar_texel_size);
|
2017-06-26 20:37:41 +02:00
|
|
|
|
|
|
|
|
DRW_draw_pass(psl->probe_planar_downsample_ps);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-13 17:39:39 +02:00
|
|
|
/* Glossy filter probe_rt to probe_pool at index probe_idx */
|
2018-01-21 23:15:57 +01:00
|
|
|
static void glossy_filter_probe(
|
|
|
|
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl, int probe_idx, float intensity)
|
2017-04-18 12:50:09 +02:00
|
|
|
{
|
2017-06-12 20:59:54 +10:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2018-01-21 23:15:57 +01:00
|
|
|
pinfo->intensity_fac = intensity;
|
|
|
|
|
|
2017-08-18 22:31:06 +02:00
|
|
|
/* Max lod used from the render target probe */
|
2017-10-10 21:56:11 +02:00
|
|
|
pinfo->lod_rt_max = floorf(log2f(pinfo->target_size)) - 2.0f;
|
2017-08-18 22:31:06 +02:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
/* Start fresh */
|
|
|
|
|
GPU_framebuffer_ensure_config(&sldata->probe_filter_fb, {
|
|
|
|
|
GPU_ATTACHMENT_NONE,
|
|
|
|
|
GPU_ATTACHMENT_NONE
|
|
|
|
|
});
|
|
|
|
|
|
2017-04-18 12:50:09 +02:00
|
|
|
/* 2 - Let gpu create Mipmaps for Filtered Importance Sampling. */
|
2017-05-29 22:03:57 +02:00
|
|
|
/* Bind next framebuffer to be able to gen. mips for probe_rt. */
|
2018-03-25 17:46:48 +02:00
|
|
|
EEVEE_downsample_cube_buffer(vedata, sldata->probe_rt, (int)(pinfo->lod_rt_max));
|
2017-04-18 12:50:09 +02:00
|
|
|
|
|
|
|
|
/* 3 - Render to probe array to the specified layer, do prefiltering. */
|
2017-10-10 21:56:11 +02:00
|
|
|
float mipsize = pinfo->cubemap_res;
|
|
|
|
|
const int maxlevel = (int)floorf(log2f(pinfo->cubemap_res));
|
2017-05-29 22:03:57 +02:00
|
|
|
const int min_lod_level = 3;
|
|
|
|
|
for (int i = 0; i < maxlevel - min_lod_level; i++) {
|
2017-08-18 22:31:06 +02:00
|
|
|
float bias = (i == 0) ? -1.0f : 1.0f;
|
2017-05-29 22:03:57 +02:00
|
|
|
pinfo->texel_size = 1.0f / mipsize;
|
|
|
|
|
pinfo->padding_size = powf(2.0f, (float)(maxlevel - min_lod_level - 1 - i));
|
|
|
|
|
/* XXX : WHY THE HECK DO WE NEED THIS ??? */
|
|
|
|
|
/* padding is incorrect without this! float precision issue? */
|
|
|
|
|
if (pinfo->padding_size > 32) {
|
|
|
|
|
pinfo->padding_size += 5;
|
|
|
|
|
}
|
|
|
|
|
if (pinfo->padding_size > 16) {
|
|
|
|
|
pinfo->padding_size += 4;
|
|
|
|
|
}
|
|
|
|
|
else if (pinfo->padding_size > 8) {
|
|
|
|
|
pinfo->padding_size += 2;
|
|
|
|
|
}
|
|
|
|
|
else if (pinfo->padding_size > 4) {
|
|
|
|
|
pinfo->padding_size += 1;
|
|
|
|
|
}
|
2017-06-04 16:50:22 +02:00
|
|
|
pinfo->layer = probe_idx;
|
2017-05-29 22:03:57 +02:00
|
|
|
pinfo->roughness = (float)i / ((float)maxlevel - 4.0f);
|
2017-04-18 12:50:09 +02:00
|
|
|
pinfo->roughness *= pinfo->roughness; /* Disney Roughness */
|
|
|
|
|
pinfo->roughness *= pinfo->roughness; /* Distribute Roughness accros lod more evenly */
|
|
|
|
|
CLAMP(pinfo->roughness, 1e-8f, 0.99999f); /* Avoid artifacts */
|
|
|
|
|
|
|
|
|
|
#if 1 /* Variable Sample count (fast) */
|
|
|
|
|
switch (i) {
|
|
|
|
|
case 0: pinfo->samples_ct = 1.0f; break;
|
|
|
|
|
case 1: pinfo->samples_ct = 16.0f; break;
|
|
|
|
|
case 2: pinfo->samples_ct = 32.0f; break;
|
|
|
|
|
case 3: pinfo->samples_ct = 64.0f; break;
|
|
|
|
|
default: pinfo->samples_ct = 128.0f; break;
|
|
|
|
|
}
|
|
|
|
|
#else /* Constant Sample count (slow) */
|
|
|
|
|
pinfo->samples_ct = 1024.0f;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
|
2017-10-10 21:56:11 +02:00
|
|
|
pinfo->lodfactor = bias + 0.5f * log((float)(pinfo->target_size * pinfo->target_size) * pinfo->invsamples_ct) / log(2);
|
2017-04-18 12:50:09 +02:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_ensure_config(&sldata->probe_filter_fb, {
|
|
|
|
|
GPU_ATTACHMENT_NONE,
|
|
|
|
|
GPU_ATTACHMENT_TEXTURE_MIP(sldata->probe_pool, i)
|
|
|
|
|
});
|
|
|
|
|
GPU_framebuffer_bind(sldata->probe_filter_fb);
|
|
|
|
|
GPU_framebuffer_viewport_set(sldata->probe_filter_fb, 0, 0, mipsize, mipsize);
|
2017-06-13 17:39:39 +02:00
|
|
|
DRW_draw_pass(psl->probe_glossy_compute);
|
2017-05-29 22:03:57 +02:00
|
|
|
|
|
|
|
|
mipsize /= 2;
|
|
|
|
|
CLAMP_MIN(mipsize, 1);
|
2017-04-18 12:50:09 +02:00
|
|
|
}
|
2017-05-29 22:03:57 +02:00
|
|
|
/* For shading, save max level of the octahedron map */
|
2018-01-21 17:25:10 +01:00
|
|
|
sldata->common_data.prb_lod_cube_max = (float)(maxlevel - min_lod_level) - 1.0f;
|
2017-06-13 17:39:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Diffuse filter probe_rt to irradiance_pool at index probe_idx */
|
2017-12-02 14:28:29 +01:00
|
|
|
static void diffuse_filter_probe(
|
|
|
|
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl, int offset,
|
2018-01-21 23:15:57 +01:00
|
|
|
float clipsta, float clipend, float vis_range, float vis_blur, float intensity)
|
2017-06-13 17:39:39 +02:00
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
2017-06-13 17:39:39 +02:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
|
|
|
|
|
2018-01-21 23:15:57 +01:00
|
|
|
pinfo->intensity_fac = intensity;
|
|
|
|
|
|
2017-12-04 17:20:20 +01:00
|
|
|
int pool_size[3];
|
2018-01-21 17:25:10 +01:00
|
|
|
irradiance_pool_size_get(common_data->prb_irradiance_vis_size, pinfo->total_irradiance_samples, pool_size);
|
2017-12-04 17:20:20 +01:00
|
|
|
|
2017-06-13 17:39:39 +02:00
|
|
|
/* find cell position on the virtual 3D texture */
|
|
|
|
|
/* NOTE : Keep in sync with load_irradiance_cell() */
|
|
|
|
|
#if defined(IRRADIANCE_SH_L2)
|
|
|
|
|
int size[2] = {3, 3};
|
|
|
|
|
#elif defined(IRRADIANCE_CUBEMAP)
|
|
|
|
|
int size[2] = {8, 8};
|
|
|
|
|
pinfo->samples_ct = 1024.0f;
|
|
|
|
|
#elif defined(IRRADIANCE_HL2)
|
|
|
|
|
int size[2] = {3, 2};
|
|
|
|
|
pinfo->samples_ct = 1024.0f;
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-12-04 17:20:20 +01:00
|
|
|
int cell_per_row = pool_size[0] / size[0];
|
2017-06-14 18:52:53 +02:00
|
|
|
int x = size[0] * (offset % cell_per_row);
|
|
|
|
|
int y = size[1] * (offset / cell_per_row);
|
2017-06-13 17:39:39 +02:00
|
|
|
|
|
|
|
|
#ifndef IRRADIANCE_SH_L2
|
2017-08-18 22:31:06 +02:00
|
|
|
/* Tweaking parameters to balance perf. vs precision */
|
2017-06-13 17:39:39 +02:00
|
|
|
const float bias = 0.0f;
|
|
|
|
|
pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
|
2017-10-10 21:56:11 +02:00
|
|
|
pinfo->lodfactor = bias + 0.5f * log((float)(pinfo->target_size * pinfo->target_size) * pinfo->invsamples_ct) / log(2);
|
|
|
|
|
pinfo->lod_rt_max = floorf(log2f(pinfo->target_size)) - 2.0f;
|
2017-06-13 17:39:39 +02:00
|
|
|
#else
|
|
|
|
|
pinfo->shres = 32; /* Less texture fetches & reduce branches */
|
2017-06-28 16:31:25 +02:00
|
|
|
pinfo->lod_rt_max = 2.0f; /* Improve cache reuse */
|
2017-06-13 17:39:39 +02:00
|
|
|
#endif
|
|
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
/* Start fresh */
|
|
|
|
|
GPU_framebuffer_ensure_config(&sldata->probe_filter_fb, {
|
|
|
|
|
GPU_ATTACHMENT_NONE,
|
|
|
|
|
GPU_ATTACHMENT_NONE
|
|
|
|
|
});
|
2017-08-18 22:31:06 +02:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
/* 4 - Compute spherical harmonics */
|
|
|
|
|
EEVEE_downsample_cube_buffer(vedata, sldata->probe_rt, (int)(pinfo->lod_rt_max));
|
|
|
|
|
|
|
|
|
|
GPU_framebuffer_ensure_config(&sldata->probe_filter_fb, {
|
|
|
|
|
GPU_ATTACHMENT_NONE,
|
|
|
|
|
GPU_ATTACHMENT_TEXTURE_LAYER(sldata->irradiance_rt, 0)
|
|
|
|
|
});
|
|
|
|
|
GPU_framebuffer_bind(sldata->probe_filter_fb);
|
|
|
|
|
GPU_framebuffer_viewport_set(sldata->probe_filter_fb, x, y, size[0], size[1]);
|
2017-06-13 17:39:39 +02:00
|
|
|
DRW_draw_pass(psl->probe_diffuse_compute);
|
2017-06-04 16:50:22 +02:00
|
|
|
|
2017-12-04 17:20:20 +01:00
|
|
|
/* World irradiance have no visibility */
|
|
|
|
|
if (offset > 0) {
|
|
|
|
|
/* Compute visibility */
|
|
|
|
|
pinfo->samples_ct = 512.0f; /* TODO refine */
|
|
|
|
|
pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
|
2018-01-21 17:25:10 +01:00
|
|
|
pinfo->shres = common_data->prb_irradiance_vis_size;
|
2017-12-04 17:20:20 +01:00
|
|
|
pinfo->visibility_range = vis_range;
|
|
|
|
|
pinfo->visibility_blur = vis_blur;
|
|
|
|
|
pinfo->near_clip = -clipsta;
|
|
|
|
|
pinfo->far_clip = -clipend;
|
2018-01-21 17:25:10 +01:00
|
|
|
pinfo->texel_size = 1.0f / (float)common_data->prb_irradiance_vis_size;
|
2017-12-04 17:20:20 +01:00
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
int cell_per_col = pool_size[1] / common_data->prb_irradiance_vis_size;
|
|
|
|
|
cell_per_row = pool_size[0] / common_data->prb_irradiance_vis_size;
|
|
|
|
|
x = common_data->prb_irradiance_vis_size * (offset % cell_per_row);
|
|
|
|
|
y = common_data->prb_irradiance_vis_size * ((offset / cell_per_row) % cell_per_col);
|
2017-12-04 17:20:20 +01:00
|
|
|
int layer = 1 + ((offset / cell_per_row) / cell_per_col);
|
2018-03-25 17:46:48 +02:00
|
|
|
const int vis_size = common_data->prb_irradiance_vis_size;
|
2017-12-04 17:20:20 +01:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_ensure_config(&sldata->probe_filter_fb, {
|
|
|
|
|
GPU_ATTACHMENT_NONE,
|
|
|
|
|
GPU_ATTACHMENT_TEXTURE_LAYER(sldata->irradiance_rt, layer)
|
|
|
|
|
});
|
|
|
|
|
GPU_framebuffer_bind(sldata->probe_filter_fb);
|
|
|
|
|
GPU_framebuffer_viewport_set(sldata->probe_filter_fb, x, y, vis_size, vis_size);
|
2017-12-04 17:20:20 +01:00
|
|
|
DRW_draw_pass(psl->probe_visibility_compute);
|
|
|
|
|
}
|
2017-04-18 12:50:09 +02:00
|
|
|
}
|
2017-05-29 22:03:57 +02:00
|
|
|
|
2017-06-13 17:39:39 +02:00
|
|
|
/* Render the scene to the probe_rt texture. */
|
|
|
|
|
static void render_scene_to_probe(
|
2017-11-22 10:52:39 -02:00
|
|
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
|
2017-06-13 17:39:39 +02:00
|
|
|
const float pos[3], float clipsta, float clipend)
|
2017-06-08 21:48:50 +02:00
|
|
|
{
|
2017-06-23 21:08:53 +02:00
|
|
|
EEVEE_TextureList *txl = vedata->txl;
|
|
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
2017-06-12 20:59:54 +10:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2018-03-03 01:48:16 +01:00
|
|
|
DRWMatrixState matstate;
|
|
|
|
|
float (*viewmat)[4] = matstate.mat[DRW_MAT_VIEW];
|
|
|
|
|
float (*viewinv)[4] = matstate.mat[DRW_MAT_VIEWINV];
|
|
|
|
|
float (*persmat)[4] = matstate.mat[DRW_MAT_PERS];
|
|
|
|
|
float (*persinv)[4] = matstate.mat[DRW_MAT_PERSINV];
|
|
|
|
|
float (*winmat)[4] = matstate.mat[DRW_MAT_WIN];
|
|
|
|
|
float (*wininv)[4] = matstate.mat[DRW_MAT_WININV];
|
|
|
|
|
|
|
|
|
|
float posmat[4][4];
|
2017-06-08 21:48:50 +02:00
|
|
|
unit_m4(posmat);
|
|
|
|
|
|
|
|
|
|
/* Move to capture position */
|
2017-06-13 17:39:39 +02:00
|
|
|
negate_v3_v3(posmat[3], pos);
|
2017-06-08 21:48:50 +02:00
|
|
|
|
|
|
|
|
/* 1 - Render to each cubeface individually.
|
|
|
|
|
* We do this instead of using geometry shader because a) it's faster,
|
|
|
|
|
* b) it's easier than fixing the nodetree shaders (for view dependant effects). */
|
|
|
|
|
pinfo->layer = 0;
|
2017-06-13 17:39:39 +02:00
|
|
|
perspective_m4(winmat, -clipsta, clipsta, -clipsta, clipsta, clipsta, clipend);
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2017-06-23 21:08:53 +02:00
|
|
|
/* Avoid using the texture attached to framebuffer when rendering. */
|
|
|
|
|
/* XXX */
|
|
|
|
|
GPUTexture *tmp_planar_pool = txl->planar_pool;
|
2017-07-21 14:27:16 +02:00
|
|
|
GPUTexture *tmp_maxz = txl->maxzbuffer;
|
2017-06-23 21:08:53 +02:00
|
|
|
txl->planar_pool = e_data.planar_pool_placeholder;
|
2017-07-21 14:27:16 +02:00
|
|
|
txl->maxzbuffer = e_data.depth_placeholder;
|
2017-06-23 21:08:53 +02:00
|
|
|
|
2018-04-24 13:01:04 +02:00
|
|
|
DRW_stats_group_start("Cubemap Render");
|
|
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
/* Update common uniforms */
|
|
|
|
|
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
|
|
|
|
|
|
2017-06-08 21:48:50 +02:00
|
|
|
for (int i = 0; i < 6; ++i) {
|
2018-04-24 12:45:59 +02:00
|
|
|
/* Recompute only on 1st drawloop. */
|
|
|
|
|
pinfo->vis_data.cached = (i != 0);
|
|
|
|
|
|
2018-04-24 13:01:04 +02:00
|
|
|
DRW_stats_group_start("Cubemap Face");
|
|
|
|
|
|
2017-06-08 21:48:50 +02:00
|
|
|
/* Setup custom matrices */
|
|
|
|
|
mul_m4_m4m4(viewmat, cubefacemat[i], posmat);
|
|
|
|
|
mul_m4_m4m4(persmat, winmat, viewmat);
|
|
|
|
|
invert_m4_m4(persinv, persmat);
|
|
|
|
|
invert_m4_m4(viewinv, viewmat);
|
2017-09-25 20:14:07 +02:00
|
|
|
invert_m4_m4(wininv, winmat);
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2018-03-03 01:48:16 +01:00
|
|
|
DRW_viewport_matrix_override_set_all(&matstate);
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2017-09-10 03:07:55 +02:00
|
|
|
/* Be sure that cascaded shadow maps are updated. */
|
|
|
|
|
EEVEE_draw_shadows(sldata, psl);
|
|
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_bind(sldata->probe_face_fb[i]);
|
|
|
|
|
GPU_framebuffer_clear_depth(sldata->probe_face_fb[i], 1.0);
|
2017-09-10 03:07:55 +02:00
|
|
|
|
2017-06-08 21:48:50 +02:00
|
|
|
/* Depth prepass */
|
|
|
|
|
DRW_draw_pass(psl->depth_pass);
|
|
|
|
|
DRW_draw_pass(psl->depth_pass_cull);
|
|
|
|
|
|
2017-07-31 15:15:42 +02:00
|
|
|
DRW_draw_pass(psl->probe_background);
|
|
|
|
|
|
2017-12-02 14:28:29 +01:00
|
|
|
// EEVEE_create_minmax_buffer(vedata, sldata->probe_depth_rt);
|
2017-06-23 21:08:53 +02:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
/* Rebind Target FB */
|
|
|
|
|
GPU_framebuffer_bind(sldata->probe_face_fb[i]);
|
2017-06-23 21:08:53 +02:00
|
|
|
|
2017-06-08 21:48:50 +02:00
|
|
|
/* Shading pass */
|
2017-06-22 02:41:17 +02:00
|
|
|
EEVEE_draw_default_passes(psl);
|
2017-06-08 21:48:50 +02:00
|
|
|
DRW_draw_pass(psl->material_pass);
|
2017-11-14 21:13:38 +01:00
|
|
|
DRW_draw_pass(psl->sss_pass); /* Only output standard pass */
|
2018-04-24 13:01:04 +02:00
|
|
|
|
|
|
|
|
DRW_stats_group_end();
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
2018-04-24 13:01:04 +02:00
|
|
|
DRW_stats_group_end();
|
|
|
|
|
|
2018-04-24 12:45:59 +02:00
|
|
|
/* Make sure no aditionnal visibility check runs after this. */
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
pinfo->vis_data.collection = NULL;
|
2018-04-24 12:45:59 +02:00
|
|
|
|
2017-06-14 10:35:28 +02:00
|
|
|
/* Restore */
|
2017-06-23 21:08:53 +02:00
|
|
|
txl->planar_pool = tmp_planar_pool;
|
2017-07-21 14:27:16 +02:00
|
|
|
txl->maxzbuffer = tmp_maxz;
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
static void render_scene_to_planar(
|
2017-11-22 10:52:39 -02:00
|
|
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, int layer,
|
2018-03-07 23:25:49 +01:00
|
|
|
EEVEE_LightProbeEngineData *ped)
|
2017-06-17 00:08:03 +02:00
|
|
|
{
|
2018-04-24 12:45:59 +02:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2017-06-17 00:08:03 +02:00
|
|
|
EEVEE_FramebufferList *fbl = vedata->fbl;
|
|
|
|
|
EEVEE_TextureList *txl = vedata->txl;
|
|
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
|
|
|
|
|
2018-03-07 23:25:49 +01:00
|
|
|
float (*viewmat)[4] = ped->mats.mat[DRW_MAT_VIEW];
|
|
|
|
|
float (*viewinv)[4] = ped->mats.mat[DRW_MAT_VIEWINV];
|
|
|
|
|
float (*persmat)[4] = ped->mats.mat[DRW_MAT_PERS];
|
|
|
|
|
float (*persinv)[4] = ped->mats.mat[DRW_MAT_PERSINV];
|
|
|
|
|
float (*winmat)[4] = ped->mats.mat[DRW_MAT_WIN];
|
|
|
|
|
float (*wininv)[4] = ped->mats.mat[DRW_MAT_WININV];
|
2017-06-17 00:08:03 +02:00
|
|
|
|
|
|
|
|
invert_m4_m4(viewinv, viewmat);
|
|
|
|
|
invert_m4_m4(persinv, persmat);
|
2018-03-07 23:25:49 +01:00
|
|
|
invert_m4_m4(wininv, winmat);
|
2017-06-17 00:08:03 +02:00
|
|
|
|
2018-04-24 13:01:04 +02:00
|
|
|
DRW_stats_group_start("Planar Reflection");
|
|
|
|
|
|
2018-03-07 23:25:49 +01:00
|
|
|
DRW_viewport_matrix_override_set_all(&ped->mats);
|
2017-09-10 03:07:55 +02:00
|
|
|
|
2018-04-24 12:45:59 +02:00
|
|
|
/* Don't reuse previous visibility. */
|
|
|
|
|
pinfo->vis_data.cached = false;
|
|
|
|
|
|
2018-03-02 18:35:25 +01:00
|
|
|
/* Be sure that cascaded shadow maps are updated. */
|
|
|
|
|
EEVEE_draw_shadows(sldata, psl);
|
|
|
|
|
|
2017-09-10 03:07:55 +02:00
|
|
|
/* Since we are rendering with an inverted view matrix, we need
|
|
|
|
|
* to invert the facing for backface culling to be the same. */
|
|
|
|
|
DRW_state_invert_facing();
|
2018-03-10 00:02:01 +01:00
|
|
|
/* Set clipping plan */
|
|
|
|
|
copy_v4_v4(sldata->clip_data.clip_planes[0], ped->planer_eq_offset);
|
|
|
|
|
DRW_uniformbuffer_update(sldata->clip_ubo, &sldata->clip_data);
|
2018-03-09 23:49:08 +01:00
|
|
|
DRW_state_clip_planes_count_set(1);
|
2017-09-10 03:07:55 +02:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_ensure_config(&fbl->planarref_fb, {
|
|
|
|
|
GPU_ATTACHMENT_TEXTURE_LAYER(txl->planar_depth, layer),
|
|
|
|
|
GPU_ATTACHMENT_TEXTURE_LAYER(txl->planar_pool, layer)
|
|
|
|
|
});
|
2017-06-17 00:08:03 +02:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_bind(fbl->planarref_fb);
|
|
|
|
|
GPU_framebuffer_clear_depth(fbl->planarref_fb, 1.0);
|
2017-06-17 00:08:03 +02:00
|
|
|
|
|
|
|
|
/* Avoid using the texture attached to framebuffer when rendering. */
|
2017-06-23 21:08:53 +02:00
|
|
|
/* XXX */
|
2017-06-17 00:08:03 +02:00
|
|
|
GPUTexture *tmp_planar_pool = txl->planar_pool;
|
2017-07-23 14:03:27 +02:00
|
|
|
GPUTexture *tmp_planar_depth = txl->planar_depth;
|
2017-06-23 19:02:40 +02:00
|
|
|
txl->planar_pool = e_data.planar_pool_placeholder;
|
2017-07-23 14:03:27 +02:00
|
|
|
txl->planar_depth = e_data.depth_array_placeholder;
|
2017-06-23 19:02:40 +02:00
|
|
|
|
2018-03-10 00:03:25 +01:00
|
|
|
/* Slight modification: we handle refraction as normal
|
|
|
|
|
* shading and don't do SSRefraction. */
|
|
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
/* Depth prepass */
|
|
|
|
|
DRW_draw_pass(psl->depth_pass_clip);
|
|
|
|
|
DRW_draw_pass(psl->depth_pass_clip_cull);
|
2018-03-10 00:03:25 +01:00
|
|
|
DRW_draw_pass(psl->refract_depth_pass);
|
|
|
|
|
DRW_draw_pass(psl->refract_depth_pass_cull);
|
2017-06-17 00:08:03 +02:00
|
|
|
|
2017-07-31 15:15:42 +02:00
|
|
|
/* Background */
|
|
|
|
|
DRW_draw_pass(psl->probe_background);
|
|
|
|
|
|
2017-07-23 20:33:29 +02:00
|
|
|
EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer);
|
2017-06-23 21:08:53 +02:00
|
|
|
|
2017-08-18 15:06:51 +02:00
|
|
|
/* Compute GTAO Horizons */
|
2018-01-09 19:01:24 +01:00
|
|
|
EEVEE_occlusion_compute(sldata, vedata, tmp_planar_depth, layer);
|
2017-08-18 15:06:51 +02:00
|
|
|
|
2017-06-23 21:08:53 +02:00
|
|
|
/* Rebind Planar FB */
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_bind(fbl->planarref_fb);
|
2017-06-23 21:08:53 +02:00
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
/* Shading pass */
|
2017-06-22 02:41:17 +02:00
|
|
|
EEVEE_draw_default_passes(psl);
|
2017-06-17 00:08:03 +02:00
|
|
|
DRW_draw_pass(psl->material_pass);
|
2017-11-14 21:13:38 +01:00
|
|
|
DRW_draw_pass(psl->sss_pass); /* Only output standard pass */
|
2018-03-10 00:03:25 +01:00
|
|
|
DRW_draw_pass(psl->refract_pass);
|
2017-06-17 00:08:03 +02:00
|
|
|
|
2018-03-08 01:36:49 +01:00
|
|
|
/* Transparent */
|
|
|
|
|
if (DRW_state_is_image_render()) {
|
|
|
|
|
/* Do the reordering only for offline because it can be costly. */
|
|
|
|
|
DRW_pass_sort_shgroup_z(psl->transparent_pass);
|
|
|
|
|
}
|
|
|
|
|
DRW_draw_pass(psl->transparent_pass);
|
|
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
DRW_state_invert_facing();
|
|
|
|
|
DRW_state_clip_planes_reset();
|
|
|
|
|
|
2018-04-24 13:01:04 +02:00
|
|
|
DRW_stats_group_end();
|
|
|
|
|
|
2018-04-24 12:45:59 +02:00
|
|
|
/* Make sure no aditionnal visibility check runs after this. */
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
pinfo->vis_data.collection = NULL;
|
2018-04-24 12:45:59 +02:00
|
|
|
|
2017-06-17 00:08:03 +02:00
|
|
|
/* Restore */
|
|
|
|
|
txl->planar_pool = tmp_planar_pool;
|
2017-07-23 14:03:27 +02:00
|
|
|
txl->planar_depth = tmp_planar_depth;
|
2017-06-17 00:08:03 +02:00
|
|
|
}
|
|
|
|
|
|
2017-11-22 10:52:39 -02:00
|
|
|
static void render_world_to_probe(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
|
2017-06-08 21:48:50 +02:00
|
|
|
{
|
2017-06-12 20:59:54 +10:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2018-03-07 23:25:49 +01:00
|
|
|
DRWMatrixState matstate;
|
|
|
|
|
float (*viewmat)[4] = matstate.mat[DRW_MAT_VIEW];
|
|
|
|
|
float (*viewinv)[4] = matstate.mat[DRW_MAT_VIEWINV];
|
|
|
|
|
float (*persmat)[4] = matstate.mat[DRW_MAT_PERS];
|
|
|
|
|
float (*persinv)[4] = matstate.mat[DRW_MAT_PERSINV];
|
|
|
|
|
float (*winmat)[4] = matstate.mat[DRW_MAT_WIN];
|
|
|
|
|
float (*wininv)[4] = matstate.mat[DRW_MAT_WININV];
|
2017-06-08 21:48:50 +02:00
|
|
|
|
|
|
|
|
/* For world probe, we don't need to clear since we render the background directly. */
|
|
|
|
|
pinfo->layer = 0;
|
|
|
|
|
|
2017-06-29 17:07:41 +02:00
|
|
|
perspective_m4(winmat, -0.1f, 0.1f, -0.1f, 0.1f, 0.1f, 1.0f);
|
2017-09-26 21:43:14 +02:00
|
|
|
invert_m4_m4(wininv, winmat);
|
2017-06-29 17:07:41 +02:00
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; ++i) {
|
|
|
|
|
/* Setup custom matrices */
|
|
|
|
|
copy_m4_m4(viewmat, cubefacemat[i]);
|
|
|
|
|
mul_m4_m4m4(persmat, winmat, viewmat);
|
|
|
|
|
invert_m4_m4(persinv, persmat);
|
|
|
|
|
invert_m4_m4(viewinv, viewmat);
|
2018-03-07 23:25:49 +01:00
|
|
|
DRW_viewport_matrix_override_set_all(&matstate);
|
2017-06-29 17:07:41 +02:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_bind(sldata->probe_face_fb[i]);
|
|
|
|
|
GPU_framebuffer_clear_depth(sldata->probe_face_fb[i], 1.0f);
|
2017-06-29 17:07:41 +02:00
|
|
|
DRW_draw_pass(psl->probe_background);
|
|
|
|
|
}
|
2017-06-13 17:39:39 +02:00
|
|
|
}
|
|
|
|
|
|
2017-09-28 21:16:02 +02:00
|
|
|
static void lightprobe_cell_grid_location_get(EEVEE_LightGrid *egrid, int cell_idx, float r_local_cell[3])
|
2017-06-13 17:39:39 +02:00
|
|
|
{
|
2017-06-14 18:52:53 +02:00
|
|
|
/* Keep in sync with lightprobe_grid_display_vert */
|
2017-09-28 21:16:02 +02:00
|
|
|
r_local_cell[2] = (float)(cell_idx % egrid->resolution[2]);
|
|
|
|
|
r_local_cell[1] = (float)((cell_idx / egrid->resolution[2]) % egrid->resolution[1]);
|
|
|
|
|
r_local_cell[0] = (float)(cell_idx / (egrid->resolution[2] * egrid->resolution[1]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lightprobe_cell_world_location_get(EEVEE_LightGrid *egrid, float local_cell[3], float r_pos[3])
|
|
|
|
|
{
|
|
|
|
|
float tmp[3];
|
2017-06-14 18:52:53 +02:00
|
|
|
|
|
|
|
|
copy_v3_v3(r_pos, egrid->corner);
|
|
|
|
|
mul_v3_v3fl(tmp, egrid->increment_x, local_cell[0]);
|
|
|
|
|
add_v3_v3(r_pos, tmp);
|
|
|
|
|
mul_v3_v3fl(tmp, egrid->increment_y, local_cell[1]);
|
|
|
|
|
add_v3_v3(r_pos, tmp);
|
|
|
|
|
mul_v3_v3fl(tmp, egrid->increment_z, local_cell[2]);
|
|
|
|
|
add_v3_v3(r_pos, tmp);
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
static void lightprobes_refresh_world(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
2018-03-06 02:19:28 +01:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2017-06-17 00:08:03 +02:00
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
2018-03-13 01:35:16 +01:00
|
|
|
EEVEE_StorageList *stl = vedata->stl;
|
2018-03-07 23:25:49 +01:00
|
|
|
DRWMatrixState saved_mats;
|
|
|
|
|
|
|
|
|
|
/* We need to save the Matrices before overidding them */
|
|
|
|
|
DRW_viewport_matrix_get_all(&saved_mats);
|
2018-01-21 17:25:10 +01:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
render_world_to_probe(sldata, psl);
|
2018-03-06 02:19:28 +01:00
|
|
|
if (pinfo->update_world & PROBE_UPDATE_CUBE) {
|
2018-01-21 23:15:57 +01:00
|
|
|
glossy_filter_probe(sldata, vedata, psl, 0, 1.0);
|
2018-01-21 22:57:12 +01:00
|
|
|
common_data->prb_num_render_cube = 1;
|
2017-11-29 12:15:22 +01:00
|
|
|
}
|
2018-03-06 02:19:28 +01:00
|
|
|
if (pinfo->update_world & PROBE_UPDATE_GRID) {
|
2018-01-21 23:15:57 +01:00
|
|
|
diffuse_filter_probe(sldata, vedata, psl, 0, 0.0, 0.0, 0.0, 0.0, 1.0);
|
2018-03-25 17:46:48 +02:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
|
2018-03-25 17:46:48 +02:00
|
|
|
|
|
|
|
|
GPU_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
|
|
|
|
|
GPU_framebuffer_bind(sldata->probe_filter_fb);
|
2017-11-29 12:15:22 +01:00
|
|
|
DRW_draw_pass(psl->probe_grid_fill);
|
2018-03-25 17:46:48 +02:00
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_num_render_grid = 1;
|
2018-03-13 01:35:16 +01:00
|
|
|
/* Reset volume history. */
|
|
|
|
|
stl->effects->volume_current_sample = -1;
|
|
|
|
|
common_data->vol_history_alpha = 0.0f;
|
2017-11-29 12:15:22 +01:00
|
|
|
}
|
2018-03-06 02:19:28 +01:00
|
|
|
pinfo->update_world = 0;
|
2017-11-29 12:15:22 +01:00
|
|
|
DRW_viewport_request_redraw();
|
2018-03-13 01:35:16 +01:00
|
|
|
/* Do not let this frame accumulate. */
|
|
|
|
|
stl->effects->taa_current_sample = 1;
|
2018-03-07 23:25:49 +01:00
|
|
|
|
|
|
|
|
DRW_viewport_matrix_override_set_all(&saved_mats);
|
2017-11-29 12:15:22 +01:00
|
|
|
}
|
2017-06-08 21:48:50 +02:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
static void lightprobes_refresh_initialize_grid(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|
|
|
|
{
|
|
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
|
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
|
|
|
|
if (pinfo->grid_initialized) {
|
2017-12-02 00:47:42 +01:00
|
|
|
/* Grid is already initialized, nothing to do. */
|
2017-11-29 12:15:22 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* Flood fill with world irradiance. */
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
|
|
|
|
|
GPU_framebuffer_bind(sldata->probe_filter_fb);
|
2017-11-29 12:15:22 +01:00
|
|
|
DRW_draw_pass(psl->probe_grid_fill);
|
2017-12-02 00:47:42 +01:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
|
2018-03-25 17:46:48 +02:00
|
|
|
|
|
|
|
|
GPU_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
|
|
|
|
|
GPU_framebuffer_bind(sldata->probe_filter_fb);
|
2017-11-29 12:15:22 +01:00
|
|
|
DRW_draw_pass(psl->probe_grid_fill);
|
2017-12-02 00:47:42 +01:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
|
2018-03-25 17:46:48 +02:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
pinfo->grid_initialized = true;
|
|
|
|
|
}
|
2017-06-13 17:39:39 +02:00
|
|
|
|
2018-02-03 01:50:38 +01:00
|
|
|
void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
2017-11-29 12:15:22 +01:00
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
2018-03-25 17:46:48 +02:00
|
|
|
EEVEE_FramebufferList *fbl = vedata->fbl;
|
2017-11-29 12:15:22 +01:00
|
|
|
EEVEE_TextureList *txl = vedata->txl;
|
|
|
|
|
Object *ob;
|
|
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2018-03-07 23:25:49 +01:00
|
|
|
DRWMatrixState saved_mats;
|
2018-01-21 17:25:10 +01:00
|
|
|
|
|
|
|
|
if (pinfo->num_planar == 0) {
|
2018-02-03 02:33:35 +01:00
|
|
|
/* Disable SSR if we cannot read previous frame */
|
|
|
|
|
common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer;
|
2018-03-08 18:02:42 +01:00
|
|
|
common_data->prb_num_planar = 0;
|
2018-01-21 17:25:10 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-08 01:35:16 +01:00
|
|
|
EEVEE_planar_reflections_updates(sldata);
|
|
|
|
|
DRW_uniformbuffer_update(sldata->planar_ubo, &sldata->probes->planar_data);
|
|
|
|
|
|
2018-03-07 23:25:49 +01:00
|
|
|
/* We need to save the Matrices before overidding them */
|
|
|
|
|
DRW_viewport_matrix_get_all(&saved_mats);
|
|
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
/* Temporary Remove all planar reflections (avoid lag effect). */
|
|
|
|
|
common_data->prb_num_planar = 0;
|
|
|
|
|
/* Turn off ssr to avoid black specular */
|
|
|
|
|
common_data->ssr_toggle = false;
|
|
|
|
|
common_data->sss_toggle = false;
|
|
|
|
|
|
|
|
|
|
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
|
|
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
for (int i = 0; (ob = pinfo->probes_planar_ref[i]) && (i < MAX_PLANAR); i++) {
|
|
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
2018-04-24 12:45:59 +02:00
|
|
|
LightProbe *prb = (LightProbe *)ob->data;
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
pinfo->vis_data.collection = prb->visibility_grp;
|
2018-04-24 12:45:59 +02:00
|
|
|
pinfo->vis_data.invert = prb->flag & LIGHTPROBE_FLAG_INVERT_GROUP;
|
2018-03-07 23:25:49 +01:00
|
|
|
render_scene_to_planar(sldata, vedata, i, ped);
|
2017-11-29 12:15:22 +01:00
|
|
|
}
|
2018-01-21 17:25:10 +01:00
|
|
|
|
|
|
|
|
/* Restore */
|
|
|
|
|
common_data->prb_num_planar = pinfo->num_planar;
|
|
|
|
|
common_data->ssr_toggle = true;
|
|
|
|
|
common_data->sss_toggle = true;
|
|
|
|
|
|
2018-03-08 01:36:49 +01:00
|
|
|
/* Prefilter for SSR */
|
|
|
|
|
if ((vedata->stl->effects->enabled_effects & EFFECT_SSR) != 0) {
|
2017-11-29 12:15:22 +01:00
|
|
|
const int max_lod = 9;
|
|
|
|
|
DRW_stats_group_start("Planar Probe Downsample");
|
2018-03-25 17:46:48 +02:00
|
|
|
|
|
|
|
|
GPU_framebuffer_ensure_config(&fbl->planar_downsample_fb, {
|
|
|
|
|
GPU_ATTACHMENT_NONE,
|
|
|
|
|
GPU_ATTACHMENT_TEXTURE(txl->planar_pool)
|
|
|
|
|
});
|
|
|
|
|
GPU_framebuffer_recursive_downsample(fbl->planar_downsample_fb, max_lod, &downsample_planar, vedata);
|
2017-11-29 12:15:22 +01:00
|
|
|
/* For shading, save max level of the planar map */
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_lod_planar_max = (float)(max_lod);
|
2017-11-29 12:15:22 +01:00
|
|
|
DRW_stats_group_end();
|
|
|
|
|
}
|
2018-02-03 01:50:38 +01:00
|
|
|
|
2018-03-07 23:25:49 +01:00
|
|
|
DRW_viewport_matrix_override_set_all(&saved_mats);
|
|
|
|
|
|
2018-03-08 01:36:49 +01:00
|
|
|
if (DRW_state_is_image_render()) {
|
|
|
|
|
/* Sort transparents because planar reflections could have re-sorted them. */
|
|
|
|
|
DRW_pass_sort_shgroup_z(vedata->psl->transparent_pass);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-03 01:50:38 +01:00
|
|
|
/* Disable SSR if we cannot read previous frame */
|
|
|
|
|
common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer;
|
2017-11-29 12:15:22 +01:00
|
|
|
}
|
2017-09-28 21:17:57 +02:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
static void lightprobes_refresh_cube(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
2017-11-29 12:15:22 +01:00
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
|
|
|
|
EEVEE_StorageList *stl = vedata->stl;
|
|
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
|
|
|
|
Object *ob;
|
|
|
|
|
for (int i = 1; (ob = pinfo->probes_cube_ref[i]) && (i < MAX_PROBE); i++) {
|
|
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
|
|
|
|
if (!ped->need_update) {
|
|
|
|
|
continue;
|
2017-10-02 18:40:51 +02:00
|
|
|
}
|
2017-11-29 12:15:22 +01:00
|
|
|
LightProbe *prb = (LightProbe *)ob->data;
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
pinfo->vis_data.collection = prb->visibility_grp;
|
2018-04-24 12:45:59 +02:00
|
|
|
pinfo->vis_data.invert = prb->flag & LIGHTPROBE_FLAG_INVERT_GROUP;
|
2017-11-29 12:15:22 +01:00
|
|
|
render_scene_to_probe(sldata, vedata, ob->obmat[3], prb->clipsta, prb->clipend);
|
2018-01-21 23:15:57 +01:00
|
|
|
glossy_filter_probe(sldata, vedata, psl, i, prb->intensity);
|
2017-11-29 12:15:22 +01:00
|
|
|
ped->need_update = false;
|
|
|
|
|
ped->probe_id = i;
|
|
|
|
|
if (!ped->ready_to_shade) {
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_num_render_cube++;
|
2017-11-29 12:15:22 +01:00
|
|
|
ped->ready_to_shade = true;
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
2017-11-29 12:15:22 +01:00
|
|
|
#if 0
|
|
|
|
|
printf("Update Cubemap %d\n", i);
|
|
|
|
|
#endif
|
2017-06-08 21:48:50 +02:00
|
|
|
DRW_viewport_request_redraw();
|
2017-11-29 12:15:22 +01:00
|
|
|
/* Do not let this frame accumulate. */
|
|
|
|
|
stl->effects->taa_current_sample = 1;
|
|
|
|
|
/* Only do one probe per frame */
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-02-03 01:50:38 +01:00
|
|
|
|
|
|
|
|
pinfo->do_cube_update = false;
|
2017-11-29 12:15:22 +01:00
|
|
|
}
|
2017-09-28 21:17:57 +02:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
2017-11-29 12:15:22 +01:00
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
|
|
|
|
EEVEE_StorageList *stl = vedata->stl;
|
|
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
|
|
|
|
Object *ob;
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
RegionView3D *rv3d = draw_ctx->rv3d;
|
2017-09-28 21:17:57 +02:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
if (draw_ctx->evil_C != NULL) {
|
|
|
|
|
/* Only compute probes if not navigating or in playback */
|
|
|
|
|
struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
|
|
|
|
|
if (((rv3d->rflag & RV3D_NAVIGATING) != 0) || ED_screen_animation_no_scrub(wm) != NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-03-07 23:25:49 +01:00
|
|
|
/* We need to save the Matrices before overidding them */
|
|
|
|
|
DRWMatrixState saved_mats;
|
|
|
|
|
DRW_viewport_matrix_get_all(&saved_mats);
|
2017-11-29 12:15:22 +01:00
|
|
|
/* Make sure grid is initialized. */
|
|
|
|
|
lightprobes_refresh_initialize_grid(sldata, vedata);
|
|
|
|
|
/* Reflection probes depend on diffuse lighting thus on irradiance grid,
|
|
|
|
|
* so update them first. */
|
|
|
|
|
while (pinfo->updated_bounce < pinfo->num_bounce) {
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_num_render_grid = pinfo->num_grid;
|
2017-11-29 12:19:57 +01:00
|
|
|
/* TODO(sergey): This logic can be split into smaller functions. */
|
2017-11-29 12:15:22 +01:00
|
|
|
for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_GRID); i++) {
|
|
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
|
|
|
|
if (!ped->need_update) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
EEVEE_LightGrid *egrid = &pinfo->grid_data[i];
|
|
|
|
|
LightProbe *prb = (LightProbe *)ob->data;
|
|
|
|
|
/* Find the next cell corresponding to the current level. */
|
|
|
|
|
bool valid_cell = false;
|
|
|
|
|
int cell_id = ped->updated_cells;
|
|
|
|
|
float pos[3], grid_loc[3];
|
|
|
|
|
/* Other levels */
|
|
|
|
|
int current_stride = 1 << max_ii(0, ped->max_lvl - ped->updated_lvl);
|
|
|
|
|
int prev_stride = current_stride << 1;
|
2017-11-29 12:19:57 +01:00
|
|
|
bool do_rendering = true;
|
2017-11-29 12:15:22 +01:00
|
|
|
while (!valid_cell) {
|
|
|
|
|
cell_id = ped->updated_cells;
|
|
|
|
|
lightprobe_cell_grid_location_get(egrid, cell_id, grid_loc);
|
|
|
|
|
if (ped->updated_lvl == 0 && cell_id == 0) {
|
|
|
|
|
valid_cell = true;
|
|
|
|
|
ped->updated_cells = ped->num_cell;
|
2017-11-29 11:59:15 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2017-11-29 12:15:22 +01:00
|
|
|
else if (((((int)grid_loc[0] % current_stride) == 0) &&
|
|
|
|
|
(((int)grid_loc[1] % current_stride) == 0) &&
|
|
|
|
|
(((int)grid_loc[2] % current_stride) == 0)) &&
|
|
|
|
|
!((((int)grid_loc[0] % prev_stride) == 0) &&
|
|
|
|
|
(((int)grid_loc[1] % prev_stride) == 0) &&
|
|
|
|
|
(((int)grid_loc[2] % prev_stride) == 0)))
|
|
|
|
|
{
|
|
|
|
|
valid_cell = true;
|
2017-11-29 11:59:15 +01:00
|
|
|
}
|
2017-11-29 12:15:22 +01:00
|
|
|
ped->updated_cells++;
|
|
|
|
|
if (ped->updated_cells > ped->num_cell) {
|
2017-11-29 12:19:57 +01:00
|
|
|
do_rendering = false;
|
|
|
|
|
break;
|
2017-11-29 11:59:15 +01:00
|
|
|
}
|
2017-06-14 18:52:53 +02:00
|
|
|
}
|
2017-11-29 12:19:57 +01:00
|
|
|
if (do_rendering) {
|
|
|
|
|
lightprobe_cell_world_location_get(egrid, grid_loc, pos);
|
|
|
|
|
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
|
|
|
|
|
/* Temporary Remove all probes. */
|
2018-01-21 17:25:10 +01:00
|
|
|
int tmp_num_render_grid = common_data->prb_num_render_grid;
|
|
|
|
|
int tmp_num_render_cube = common_data->prb_num_render_cube;
|
|
|
|
|
int tmp_num_planar = common_data->prb_num_planar;
|
2017-12-02 00:47:42 +01:00
|
|
|
float tmp_level_bias = egrid->level_bias;
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_num_render_cube = 0;
|
|
|
|
|
common_data->prb_num_planar = 0;
|
2017-11-29 12:19:57 +01:00
|
|
|
/* Use light from previous bounce when capturing radiance. */
|
|
|
|
|
if (pinfo->updated_bounce == 0) {
|
2017-12-02 00:47:42 +01:00
|
|
|
/* But not on first bounce. */
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_num_render_grid = 0;
|
2017-11-29 12:19:57 +01:00
|
|
|
}
|
2017-12-02 00:47:42 +01:00
|
|
|
else {
|
|
|
|
|
/* Remove bias */
|
|
|
|
|
egrid->level_bias = (float)(1 << 0);
|
|
|
|
|
DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
pinfo->vis_data.collection = prb->visibility_grp;
|
2018-04-24 12:45:59 +02:00
|
|
|
pinfo->vis_data.invert = prb->flag & LIGHTPROBE_FLAG_INVERT_GROUP;
|
2017-11-29 12:19:57 +01:00
|
|
|
render_scene_to_probe(sldata, vedata, pos, prb->clipsta, prb->clipend);
|
2017-12-02 14:28:29 +01:00
|
|
|
diffuse_filter_probe(sldata, vedata, psl, egrid->offset + cell_id,
|
2018-01-21 23:15:57 +01:00
|
|
|
prb->clipsta, prb->clipend, egrid->visibility_range, prb->vis_blur,
|
|
|
|
|
prb->intensity);
|
2017-11-29 12:19:57 +01:00
|
|
|
/* To see what is going on. */
|
|
|
|
|
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
|
|
|
|
|
/* Restore */
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_num_render_cube = tmp_num_render_cube;
|
2017-11-29 12:19:57 +01:00
|
|
|
pinfo->num_planar = tmp_num_planar;
|
2017-12-02 00:47:42 +01:00
|
|
|
if (pinfo->updated_bounce == 0) {
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_num_render_grid = tmp_num_render_grid;
|
2017-12-02 00:47:42 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
egrid->level_bias = tmp_level_bias;
|
|
|
|
|
DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
|
|
|
|
|
}
|
|
|
|
|
#if 0
|
|
|
|
|
printf("Updated Grid %d : cell %d / %d, bounce %d / %d\n",
|
|
|
|
|
i, cell_id + 1, ped->num_cell, pinfo->updated_bounce + 1, pinfo->num_bounce);
|
|
|
|
|
#endif
|
2017-06-13 17:39:39 +02:00
|
|
|
}
|
2017-11-29 12:15:22 +01:00
|
|
|
if (ped->updated_cells >= ped->num_cell) {
|
|
|
|
|
ped->updated_lvl++;
|
|
|
|
|
ped->updated_cells = 0;
|
|
|
|
|
if (ped->updated_lvl > ped->max_lvl) {
|
|
|
|
|
ped->need_update = false;
|
|
|
|
|
}
|
|
|
|
|
egrid->level_bias = (float)(1 << max_ii(0, ped->max_lvl - ped->updated_lvl + 1));
|
|
|
|
|
DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
|
2017-11-29 11:59:15 +01:00
|
|
|
}
|
2017-11-29 12:15:22 +01:00
|
|
|
/* Only do one probe per frame */
|
2017-11-29 11:59:15 +01:00
|
|
|
DRW_viewport_request_redraw();
|
|
|
|
|
/* Do not let this frame accumulate. */
|
|
|
|
|
stl->effects->taa_current_sample = 1;
|
2018-03-13 01:35:16 +01:00
|
|
|
/* Reset volume history. */
|
|
|
|
|
stl->effects->volume_current_sample = -1;
|
|
|
|
|
common_data->vol_history_alpha = 0.0f;
|
2018-03-07 23:25:49 +01:00
|
|
|
/* Restore matrices */
|
|
|
|
|
DRW_viewport_matrix_override_set_all(&saved_mats);
|
2017-11-29 12:15:22 +01:00
|
|
|
return;
|
2017-06-08 21:48:50 +02:00
|
|
|
}
|
2017-06-17 00:08:03 +02:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
pinfo->updated_bounce++;
|
2018-01-21 17:25:10 +01:00
|
|
|
common_data->prb_num_render_grid = pinfo->num_grid;
|
2017-06-17 00:08:03 +02:00
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
if (pinfo->updated_bounce < pinfo->num_bounce) {
|
|
|
|
|
/* Retag all grids to update for next bounce */
|
|
|
|
|
for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_GRID); i++) {
|
|
|
|
|
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
|
|
|
|
|
ped->need_update = true;
|
|
|
|
|
ped->updated_cells = 0;
|
|
|
|
|
ped->updated_lvl = 0;
|
|
|
|
|
}
|
|
|
|
|
/* Reset the next buffer so we can see the progress. */
|
2017-12-02 00:47:42 +01:00
|
|
|
/* irradiance_rt is already the next rt because of the previous SWAP */
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
|
|
|
|
|
GPU_framebuffer_bind(sldata->probe_filter_fb);
|
2017-11-29 12:15:22 +01:00
|
|
|
DRW_draw_pass(psl->probe_grid_fill);
|
2018-03-25 17:46:48 +02:00
|
|
|
|
|
|
|
|
GPU_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
|
2017-12-02 00:47:42 +01:00
|
|
|
/* Swap AFTER */
|
|
|
|
|
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
|
2017-11-29 12:15:22 +01:00
|
|
|
}
|
2017-06-17 00:08:03 +02:00
|
|
|
}
|
2017-11-29 12:15:22 +01:00
|
|
|
/* Refresh cube probe when needed. */
|
|
|
|
|
lightprobes_refresh_cube(sldata, vedata);
|
2018-03-07 23:25:49 +01:00
|
|
|
/* Restore matrices */
|
|
|
|
|
DRW_viewport_matrix_override_set_all(&saved_mats);
|
2017-11-29 12:15:22 +01:00
|
|
|
}
|
2017-06-26 20:37:41 +02:00
|
|
|
|
2018-02-03 01:50:38 +01:00
|
|
|
bool EEVEE_lightprobes_all_probes_ready(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(vedata))
|
2017-11-29 12:15:22 +01:00
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
|
|
|
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
|
|
|
|
|
2018-02-03 01:50:38 +01:00
|
|
|
return ((pinfo->do_cube_update == false) &&
|
|
|
|
|
(pinfo->updated_bounce == pinfo->num_bounce) &&
|
|
|
|
|
(common_data->prb_num_render_cube == pinfo->num_cube));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|
|
|
|
{
|
|
|
|
|
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
|
2018-03-06 02:19:28 +01:00
|
|
|
EEVEE_LightProbesInfo *pinfo = sldata->probes;
|
2018-02-03 01:50:38 +01:00
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
/* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
|
|
|
|
|
common_data->spec_toggle = false;
|
|
|
|
|
common_data->ssr_toggle = false;
|
|
|
|
|
common_data->sss_toggle = false;
|
|
|
|
|
|
|
|
|
|
/* Disable AO until we find a way to hide really bad discontinuities between cubefaces. */
|
|
|
|
|
float tmp_ao_dist = common_data->ao_dist;
|
|
|
|
|
float tmp_ao_settings = common_data->ao_settings;
|
|
|
|
|
common_data->ao_settings = 0.0f;
|
|
|
|
|
common_data->ao_dist = 0.0f;
|
|
|
|
|
|
2017-11-29 12:15:22 +01:00
|
|
|
/* Render world in priority */
|
2018-03-06 02:19:28 +01:00
|
|
|
if (pinfo->update_world) {
|
2017-11-29 12:15:22 +01:00
|
|
|
lightprobes_refresh_world(sldata, vedata);
|
|
|
|
|
}
|
2018-03-06 02:19:28 +01:00
|
|
|
else if (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false && pinfo->all_materials_updated) {
|
2017-11-29 12:15:22 +01:00
|
|
|
lightprobes_refresh_all_no_world(sldata, vedata);
|
2017-06-26 20:37:41 +02:00
|
|
|
}
|
2018-01-03 20:41:14 +01:00
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
/* Restore */
|
|
|
|
|
common_data->spec_toggle = true;
|
|
|
|
|
common_data->ssr_toggle = true;
|
|
|
|
|
common_data->sss_toggle = true;
|
|
|
|
|
common_data->ao_dist = tmp_ao_dist;
|
|
|
|
|
common_data->ao_settings = tmp_ao_settings;
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-12 20:59:54 +10:00
|
|
|
void EEVEE_lightprobes_free(void)
|
2017-05-29 22:03:57 +02:00
|
|
|
{
|
2018-02-14 18:59:15 +01:00
|
|
|
MEM_SAFE_FREE(e_data.format_probe_display_cube);
|
|
|
|
|
MEM_SAFE_FREE(e_data.format_probe_display_planar);
|
2017-06-04 12:12:58 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_default_sh);
|
2018-05-25 08:06:36 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_default_studiolight_sh);
|
2017-06-13 17:39:39 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
|
|
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
|
2017-12-02 14:28:29 +01:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_filter_visibility_sh);
|
2017-09-28 21:17:57 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_grid_fill_sh);
|
2017-06-14 13:45:54 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_grid_display_sh);
|
2017-06-17 01:59:01 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_planar_display_sh);
|
2017-06-26 20:37:41 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_planar_downsample_sh);
|
2017-06-15 00:10:34 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.probe_cube_display_sh);
|
2017-05-29 22:03:57 +02:00
|
|
|
DRW_TEXTURE_FREE_SAFE(e_data.hammersley);
|
2017-06-23 19:02:40 +02:00
|
|
|
DRW_TEXTURE_FREE_SAFE(e_data.planar_pool_placeholder);
|
2017-07-21 14:27:16 +02:00
|
|
|
DRW_TEXTURE_FREE_SAFE(e_data.depth_placeholder);
|
2017-07-23 14:03:27 +02:00
|
|
|
DRW_TEXTURE_FREE_SAFE(e_data.depth_array_placeholder);
|
2017-05-30 22:29:20 +02:00
|
|
|
}
|