Blender  V2.93
eevee_lookdev.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18 
22 #include "DRW_render.h"
23 
24 #include "BKE_camera.h"
25 #include "BKE_studiolight.h"
26 
27 #include "BLI_rand.h"
28 #include "BLI_rect.h"
29 
30 #include "DNA_screen_types.h"
31 #include "DNA_world_types.h"
32 
33 #include "DEG_depsgraph_query.h"
34 
35 #include "ED_screen.h"
36 
37 #include "GPU_material.h"
38 
39 #include "UI_resources.h"
40 
41 #include "eevee_lightcache.h"
42 #include "eevee_private.h"
43 
44 #include "draw_common.h"
45 
47 {
48  EEVEE_StorageList *stl = vedata->stl;
49  EEVEE_PrivateData *g_data = stl->g_data;
50  EEVEE_TextureList *txl = vedata->txl;
51 
57  g_data->studiolight_index = -1;
58  g_data->studiolight_rot_z = 0.0f;
59 }
60 
62 {
63  EEVEE_PassList *psl = vedata->psl;
64  const DRWContextState *draw_ctx = DRW_context_state_get();
65  Scene *scene = draw_ctx->scene;
66  DRWShadingGroup *grp;
67 
68  const EEVEE_EffectsInfo *effects = vedata->stl->effects;
69  struct GPUBatch *sphere = DRW_cache_sphere_get(effects->sphere_lod);
70  int mat_options = VAR_MAT_MESH | VAR_MAT_LOOKDEV;
71 
74 
75  {
77  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
78  struct GPUShader *sh = GPU_material_get_shader(gpumat);
79 
82  EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, false, false);
84  DRW_shgroup_call(grp, sphere, NULL);
85  }
86  {
88  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
89  struct GPUShader *sh = GPU_material_get_shader(gpumat);
90 
93  EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, false, false);
95  DRW_shgroup_call(grp, sphere, NULL);
96  }
97 }
98 
100 {
101  EEVEE_StorageList *stl = vedata->stl;
102  EEVEE_EffectsInfo *effects = stl->effects;
103  const DRWContextState *draw_ctx = DRW_context_state_get();
104  /* The view will be NULL when rendering previews. */
105  const View3D *v3d = draw_ctx->v3d;
106 
108  /* Viewport / Spheres size. */
109  const rcti *rect;
110  rcti fallback_rect;
112  const float *vp_size = DRW_viewport_size_get();
113  fallback_rect.xmax = vp_size[0];
114  fallback_rect.ymax = vp_size[1];
115  fallback_rect.xmin = fallback_rect.ymin = 0;
116  rect = &fallback_rect;
117  }
118  else {
119  rect = ED_region_visible_rect(draw_ctx->region);
120  }
121 
122  /* Make the viewport width scale the lookdev spheres a bit.
123  * Scale between 1000px and 2000px. */
124  const float viewport_scale = clamp_f(
125  BLI_rcti_size_x(rect) / (2000.0f * U.dpi_fac), 0.5f, 1.0f);
126  const int sphere_size = U.lookdev_sphere_size * U.dpi_fac * viewport_scale;
127 
128  if (sphere_size != effects->sphere_size || rect->xmax != effects->anchor[0] ||
129  rect->ymin != effects->anchor[1]) {
130  /* Make sphere resolution adaptive to viewport_scale, dpi and lookdev_sphere_size */
131  float res_scale = clamp_f(
132  (U.lookdev_sphere_size / 400.0f) * viewport_scale * U.dpi_fac, 0.1f, 1.0f);
133 
134  if (res_scale > 0.7f) {
135  effects->sphere_lod = DRW_LOD_HIGH;
136  }
137  else if (res_scale > 0.25f) {
138  effects->sphere_lod = DRW_LOD_MEDIUM;
139  }
140  else {
141  effects->sphere_lod = DRW_LOD_LOW;
142  }
143  /* If sphere size or anchor point moves, reset TAA to avoid ghosting issue.
144  * This needs to happen early because we are changing taa_current_sample. */
145  effects->sphere_size = sphere_size;
146  effects->anchor[0] = rect->xmax;
147  effects->anchor[1] = rect->ymin;
148  stl->g_data->valid_double_buffer = false;
150  }
151  }
152 }
153 
155  EEVEE_ViewLayerData *sldata,
156  DRWPass *pass,
157  EEVEE_LightProbesInfo *pinfo,
158  DRWShadingGroup **r_shgrp)
159 {
160  EEVEE_StorageList *stl = vedata->stl;
161  EEVEE_TextureList *txl = vedata->txl;
162  EEVEE_EffectsInfo *effects = stl->effects;
163  EEVEE_PrivateData *g_data = stl->g_data;
164  const DRWContextState *draw_ctx = DRW_context_state_get();
165  /* The view will be NULL when rendering previews. */
166  const View3D *v3d = draw_ctx->v3d;
167  const Scene *scene = draw_ctx->scene;
168 
169  const bool probe_render = pinfo != NULL;
170 
171  effects->lookdev_view = NULL;
172 
174  eevee_lookdev_hdri_preview_init(vedata, sldata);
175  }
176 
178  const View3DShading *shading = &v3d->shading;
181  if (sl == NULL || (sl->flag & STUDIOLIGHT_TYPE_WORLD) == 0) {
182  return;
183  }
184 
187 
188  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
189  int cube_res = scene_eval->eevee.gi_cubemap_resolution;
190 
191  /* If one of the component is missing we start from scratch. */
192  if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
193  (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) ||
194  (g_data->light_cache && g_data->light_cache->ref_res != cube_res)) {
196  }
197 
198  if (stl->lookdev_lightcache == NULL) {
199 #if defined(IRRADIANCE_SH_L2)
200  int grid_res = 4;
201 #elif defined(IRRADIANCE_HL2)
202  int grid_res = 4;
203 #endif
204 
206  1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1});
207 
208  /* XXX: Fix memleak. TODO find out why. */
210 
211  /* We do this to use a special light cache for lookdev.
212  * This light-cache needs to be per viewport. But we need to
213  * have correct freeing when the viewport is closed. So we
214  * need to reference all textures to the txl and the memblocks
215  * to the stl. */
221  }
222 
223  g_data->light_cache = stl->lookdev_lightcache;
224 
227 
228  float studiolight_matrix[3][3] = {{0.0f}};
230  float view_matrix[4][4];
231  float view_rot_matrix[3][3];
232  float x_rot_matrix[3][3];
233  DRW_view_viewmat_get(NULL, view_matrix, false);
234  copy_m3_m4(view_rot_matrix, view_matrix);
235  axis_angle_to_mat3_single(x_rot_matrix, 'X', M_PI / 2.0f);
236  mul_m3_m3m3(view_rot_matrix, x_rot_matrix, view_rot_matrix);
237  mul_m3_m3m3(view_rot_matrix, g_data->studiolight_matrix, view_rot_matrix);
238  copy_m3_m3(studiolight_matrix, view_rot_matrix);
239  }
240 
241  DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix);
242 
243  if (probe_render) {
244  /* Avoid artifact with equirectangular mapping. */
246  DRW_shgroup_uniform_float_copy(grp, "studioLightIntensity", shading->studiolight_intensity);
249  /* Do not fadeout when doing probe rendering, only when drawing the background */
250  DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
251  }
252  else {
253  float background_alpha = g_data->background_alpha * shading->studiolight_background;
254  float studiolight_blur = powf(shading->studiolight_blur, 2.5f);
255  DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha);
256  DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur);
257  DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx);
258  }
259 
260  /* Common UBOs are setup latter. */
261  *r_shgrp = grp;
262 
263  /* Do we need to recalc the lightprobes? */
264  if (g_data->studiolight_index != sl->index ||
266  !equals_m3m3(g_data->studiolight_matrix, studiolight_matrix)) ||
267  g_data->studiolight_rot_z != shading->studiolight_rot_z ||
268  g_data->studiolight_intensity != shading->studiolight_intensity ||
273  g_data->studiolight_index = sl->index;
274  copy_m3_m3(g_data->studiolight_matrix, studiolight_matrix);
275  g_data->studiolight_rot_z = shading->studiolight_rot_z;
276  g_data->studiolight_intensity = shading->studiolight_intensity;
280  }
281  }
282 }
283 
284 static void eevee_lookdev_apply_taa(const EEVEE_EffectsInfo *effects,
285  int sphere_size,
286  float winmat[4][4])
287 {
288  if (DRW_state_is_image_render() || ((effects->enabled_effects & EFFECT_TAA) != 0)) {
289  double ht_point[2];
290  double ht_offset[2] = {0.0, 0.0};
291  const uint ht_primes[2] = {2, 3};
292  float ofs[2];
293 
294  BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample, ht_point);
295  EEVEE_temporal_sampling_offset_calc(ht_point, 1.5f, ofs);
296  winmat[3][0] += ofs[0] / sphere_size;
297  winmat[3][1] += ofs[1] / sphere_size;
298  }
299 }
300 
302 {
303  EEVEE_PassList *psl = vedata->psl;
304  EEVEE_FramebufferList *fbl = vedata->fbl;
305  EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
306  EEVEE_EffectsInfo *effects = stl->effects;
308 
309  const DRWContextState *draw_ctx = DRW_context_state_get();
310 
312  /* Config renderer. */
313  EEVEE_CommonUniformBuffer *common = &sldata->common_data;
314  common->la_num_light = 0;
315  common->prb_num_planar = 0;
316  common->prb_num_render_cube = 1;
317  common->prb_num_render_grid = 1;
318  common->ao_dist = 0.0f;
319  common->ao_factor = 0.0f;
320  common->ao_settings = 0.0f;
321  GPU_uniformbuf_update(sldata->common_ubo, common);
322 
323  /* override matrices */
324  float winmat[4][4], viewmat[4][4];
325  unit_m4(winmat);
326  /* Look through the negative Z. */
327  negate_v3(winmat[2]);
328 
329  eevee_lookdev_apply_taa(effects, effects->sphere_size, winmat);
330 
331  /* "Remove" view matrix location. Leaving only rotation. */
332  DRW_view_viewmat_get(NULL, viewmat, false);
333  zero_v3(viewmat[3]);
334 
335  if (effects->lookdev_view) {
336  /* When rendering just update the view. This avoids recomputing the culling. */
337  DRW_view_update_sub(effects->lookdev_view, viewmat, winmat);
338  }
339  else {
340  /* Using default view bypasses the culling. */
341  const DRWView *default_view = DRW_view_default_get();
342  effects->lookdev_view = DRW_view_create_sub(default_view, viewmat, winmat);
343  }
344 
346 
347  /* Find the right frame-buffers to render to. */
348  GPUFrameBuffer *fb = (effects->target_buffer == fbl->effect_color_fb) ? fbl->main_fb :
349  fbl->effect_fb;
350 
351  DRW_stats_group_start("Look Dev");
352 
354 
355  const int sphere_margin = effects->sphere_size / 6.0f;
356  float offset[2] = {0.0f, sphere_margin};
357 
358  offset[0] = effects->sphere_size + sphere_margin;
360  effects->anchor[0] - offset[0],
361  effects->anchor[1] + offset[1],
362  effects->sphere_size,
363  effects->sphere_size);
364 
366 
367  offset[0] = (effects->sphere_size + sphere_margin) +
368  (sphere_margin + effects->sphere_size + sphere_margin);
370  effects->anchor[0] - offset[0],
371  effects->anchor[1] + offset[1],
372  effects->sphere_size,
373  effects->sphere_size);
374 
376 
378 
380 
382  }
383 }
Camera data-block and utility functions.
@ STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE
@ STUDIOLIGHT_TYPE_WORLD
struct StudioLight * BKE_studiolight_find(const char *name, int flag)
Definition: studiolight.c:1483
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
Definition: studiolight.c:1539
#define STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE
MINLINE float clamp_f(float value, float min, float max)
#define M_PI
Definition: BLI_math_base.h:38
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:89
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
void unit_m4(float m[4][4])
Definition: rct.c:1140
bool equals_m3m3(const float mat1[3][3], const float mat2[3][3])
Definition: math_matrix.c:2606
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
void axis_angle_to_mat3_single(float R[3][3], const char axis, const float angle)
MINLINE void negate_v3(float r[3])
MINLINE void zero_v3(float r[3])
Random number functions.
void BLI_halton_2d(const unsigned int prime[2], double offset[2], int n, double *r)
Definition: rand.cc:310
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
unsigned int uint
Definition: BLI_sys_types.h:83
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ LIGHTCACHE_UPDATE_WORLD
@ V3D_SHADING_STUDIOLIGHT_VIEW_ROTATION
DRWState
Definition: DRW_render.h:312
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:314
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:328
@ DRW_STATE_DEPTH_ALWAYS
Definition: DRW_render.h:321
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:420
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:180
const rcti * ED_region_visible_rect(ARegion *region)
Definition: area.c:3682
GPUBatch
Definition: GPU_batch.h:93
struct GPUFrameBuffer GPUFrameBuffer
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
struct GPUShader * GPU_material_get_shader(GPUMaterial *material)
Definition: gpu_material.c:212
struct GPUShader GPUShader
Definition: GPU_shader.h:33
eGPUSamplerState
Definition: GPU_texture.h:40
@ GPU_SAMPLER_REPEAT_S
Definition: GPU_texture.h:44
@ GPU_SAMPLER_FILTER
Definition: GPU_texture.h:42
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
#define MEM_SAFE_FREE(v)
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
GPUBatch * DRW_cache_sphere_get(const eDRWLevelOfDetail level_of_detail)
Definition: draw_cache.c:487
@ DRW_LOD_MEDIUM
Definition: draw_cache.h:38
@ DRW_LOD_LOW
Definition: draw_cache.h:37
@ DRW_LOD_HIGH
Definition: draw_cache.h:39
bool DRW_state_is_opengl_render(void)
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:439
bool DRW_state_is_image_render(void)
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
const DRWView * DRW_view_default_get(void)
void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float(*value)[3])
void DRW_shgroup_uniform_texture_ex(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex, eGPUSamplerState sampler_state)
DRWView * DRW_view_create_sub(const DRWView *parent_view, const float viewmat[4][4], const float winmat[4][4])
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial *material)
void DRW_view_update_sub(DRWView *view, const float viewmat[4][4], const float winmat[4][4])
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
void DRW_view_set_active(DRWView *view)
void DRW_draw_pass(DRWPass *pass)
void DRW_stats_group_start(const char *name)
void DRW_stats_group_end(void)
EEVEE_ViewLayerData * EEVEE_view_layer_data_ensure(void)
Definition: eevee_data.c:276
LightCache * EEVEE_lightcache_create(const int grid_len, const int cube_len, const int cube_size, const int vis_size, const int irr_size[3])
void EEVEE_lookdev_init(EEVEE_Data *vedata)
Definition: eevee_lookdev.c:99
static void eevee_lookdev_apply_taa(const EEVEE_EffectsInfo *effects, int sphere_size, float winmat[4][4])
static void eevee_lookdev_hdri_preview_init(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata)
Definition: eevee_lookdev.c:61
void EEVEE_lookdev_draw(EEVEE_Data *vedata)
static void eevee_lookdev_lightcache_delete(EEVEE_Data *vedata)
Definition: eevee_lookdev.c:46
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, DRWPass *pass, EEVEE_LightProbesInfo *pinfo, DRWShadingGroup **r_shgrp)
void EEVEE_material_bind_resources(DRWShadingGroup *shgrp, GPUMaterial *gpumat, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, const int *ssr_id, const float *refract_depth, bool use_ssrefraction, bool use_alpha_blend)
@ VAR_MAT_LOOKDEV
@ VAR_MAT_MESH
void EEVEE_temporal_sampling_offset_calc(const double ht_point[2], const float filter_size, float r_offset[2])
#define LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)
void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata)
struct GPUShader * EEVEE_shaders_studiolight_background_sh_get(void)
Material * EEVEE_material_default_diffuse_get(void)
Material * EEVEE_material_default_glossy_get(void)
@ EFFECT_TAA
struct GPUShader * EEVEE_shaders_studiolight_probe_sh_get(void)
struct GPUMaterial * EEVEE_material_get(EEVEE_Data *vedata, struct Scene *scene, Material *ma, World *wo, int options)
BLI_INLINE bool eevee_hdri_preview_overlay_enabled(const View3D *v3d)
void GPU_framebuffer_viewport_reset(GPUFrameBuffer *gpu_fb)
void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height)
BLI_INLINE float fb(float length, float L)
#define powf(x, y)
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
static ulong state[N]
struct Scene * scene
Definition: DRW_render.h:745
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
struct View3D * v3d
Definition: DRW_render.h:742
struct ARegion * region
Definition: DRW_render.h:740
EEVEE_TextureList * txl
EEVEE_StorageList * stl
EEVEE_PassList * psl
EEVEE_FramebufferList * fbl
struct GPUFrameBuffer * target_buffer
eDRWLevelOfDetail sphere_lod
EEVEE_EffectsFlag enabled_effects
struct DRWView * lookdev_view
struct GPUFrameBuffer * main_fb
struct GPUFrameBuffer * effect_fb
struct GPUFrameBuffer * effect_color_fb
struct DRWPass * lookdev_diffuse_pass
struct DRWPass * lookdev_glossy_pass
float studiolight_glossy_clamp
struct LightCache * light_cache
float studiolight_filter_quality
float studiolight_matrix[3][3]
LightCacheTexture * lookdev_cube_mips
EEVEE_LightProbe * lookdev_cube_data
struct EEVEE_PrivateData * g_data
struct EEVEE_EffectsInfo * effects
EEVEE_LightGrid * lookdev_grid_data
struct LightCache * lookdev_lightcache
struct GPUTexture * lookdev_cube_tx
struct GPUTexture * lookdev_grid_tx
struct EEVEE_CommonUniformBuffer common_data
struct GPUUniformBuf * common_ubo
struct GPUTexture * tex
LightGridCache * grid_data
LightProbeCache * cube_data
LightCacheTexture grid_tx
LightCacheTexture * cube_mips
LightCacheTexture cube_tx
float gi_glossy_clamp
float gi_filter_quality
int gi_cubemap_resolution
struct SceneEEVEE eevee
struct GPUTexture * equirect_radiance_gputexture
float studiolight_background
float studiolight_intensity
char lookdev_light[256]
View3DShading shading
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79