Blender  V3.3
eevee_lookdev.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. */
3 
7 #include "DRW_render.h"
8 
9 #include "BKE_camera.h"
10 #include "BKE_studiolight.h"
11 
12 #include "BLI_rand.h"
13 #include "BLI_rect.h"
14 
15 #include "DNA_screen_types.h"
16 #include "DNA_world_types.h"
17 
18 #include "DEG_depsgraph_query.h"
19 
20 #include "ED_screen.h"
21 
22 #include "GPU_material.h"
23 
24 #include "UI_resources.h"
25 
26 #include "eevee_lightcache.h"
27 #include "eevee_private.h"
28 
29 #include "draw_common.h"
30 
32 {
33  EEVEE_StorageList *stl = vedata->stl;
35  EEVEE_TextureList *txl = vedata->txl;
36 
42  g_data->studiolight_index = -1;
43  g_data->studiolight_rot_z = 0.0f;
44 }
45 
47 {
48  EEVEE_PassList *psl = vedata->psl;
49  const DRWContextState *draw_ctx = DRW_context_state_get();
50  Scene *scene = draw_ctx->scene;
51  DRWShadingGroup *grp;
52 
53  const EEVEE_EffectsInfo *effects = vedata->stl->effects;
54  struct GPUBatch *sphere = DRW_cache_sphere_get(effects->sphere_lod);
55  int mat_options = VAR_MAT_MESH | VAR_MAT_LOOKDEV;
56 
59 
60  {
62  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
63  struct GPUShader *sh = GPU_material_get_shader(gpumat);
64 
67  EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, -1.0f, false, false);
69  DRW_shgroup_call(grp, sphere, NULL);
70  }
71  {
73  GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
74  struct GPUShader *sh = GPU_material_get_shader(gpumat);
75 
78  EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, -1.0f, false, false);
80  DRW_shgroup_call(grp, sphere, NULL);
81  }
82 }
83 
85 {
86  EEVEE_StorageList *stl = vedata->stl;
87  EEVEE_EffectsInfo *effects = stl->effects;
88  const DRWContextState *draw_ctx = DRW_context_state_get();
89  /* The view will be NULL when rendering previews. */
90  const View3D *v3d = draw_ctx->v3d;
91 
93  /* Viewport / Spheres size. */
94  const rcti *rect;
95  rcti fallback_rect;
97  const float *vp_size = DRW_viewport_size_get();
98  fallback_rect.xmax = vp_size[0];
99  fallback_rect.ymax = vp_size[1];
100  fallback_rect.xmin = fallback_rect.ymin = 0;
101  rect = &fallback_rect;
102  }
103  else {
104  rect = ED_region_visible_rect(draw_ctx->region);
105  }
106 
107  /* Make the viewport width scale the lookdev spheres a bit.
108  * Scale between 1000px and 2000px. */
109  const float viewport_scale = clamp_f(
110  BLI_rcti_size_x(rect) / (2000.0f * U.dpi_fac), 0.5f, 1.0f);
111  const int sphere_size = U.lookdev_sphere_size * U.dpi_fac * viewport_scale;
112 
113  if (sphere_size != effects->sphere_size || rect->xmax != effects->anchor[0] ||
114  rect->ymin != effects->anchor[1]) {
115  /* Make sphere resolution adaptive to viewport_scale, DPI and #U.lookdev_sphere_size. */
116  float res_scale = clamp_f(
117  (U.lookdev_sphere_size / 400.0f) * viewport_scale * U.dpi_fac, 0.1f, 1.0f);
118 
119  if (res_scale > 0.7f) {
120  effects->sphere_lod = DRW_LOD_HIGH;
121  }
122  else if (res_scale > 0.25f) {
123  effects->sphere_lod = DRW_LOD_MEDIUM;
124  }
125  else {
126  effects->sphere_lod = DRW_LOD_LOW;
127  }
128  /* If sphere size or anchor point moves, reset TAA to avoid ghosting issue.
129  * This needs to happen early because we are changing taa_current_sample. */
130  effects->sphere_size = sphere_size;
131  effects->anchor[0] = rect->xmax;
132  effects->anchor[1] = rect->ymin;
133  stl->g_data->valid_double_buffer = false;
135  }
136  }
137 }
138 
140  EEVEE_ViewLayerData *sldata,
141  DRWPass *pass,
142  EEVEE_LightProbesInfo *pinfo,
143  DRWShadingGroup **r_shgrp)
144 {
145  EEVEE_StorageList *stl = vedata->stl;
146  EEVEE_TextureList *txl = vedata->txl;
147  EEVEE_EffectsInfo *effects = stl->effects;
149  const DRWContextState *draw_ctx = DRW_context_state_get();
150  /* The view will be NULL when rendering previews. */
151  const View3D *v3d = draw_ctx->v3d;
152  const Scene *scene = draw_ctx->scene;
153 
154  const bool probe_render = pinfo != NULL;
155 
156  effects->lookdev_view = NULL;
157 
159  eevee_lookdev_hdri_preview_init(vedata, sldata);
160  }
161 
163  const View3DShading *shading = &v3d->shading;
166  if (sl == NULL || (sl->flag & STUDIOLIGHT_TYPE_WORLD) == 0) {
167  return;
168  }
169 
170  GPUShader *shader = probe_render ? EEVEE_shaders_studiolight_probe_sh_get() :
172 
173  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
174  int cube_res = scene_eval->eevee.gi_cubemap_resolution;
175 
176  /* If one of the component is missing we start from scratch. */
177  if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
178  (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) ||
179  (g_data->light_cache && g_data->light_cache->ref_res != cube_res)) {
181  }
182 
183  if (stl->lookdev_lightcache == NULL) {
184 #if defined(IRRADIANCE_SH_L2)
185  int grid_res = 4;
186 #elif defined(IRRADIANCE_HL2)
187  int grid_res = 4;
188 #endif
189 
191  1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1});
192 
193  /* XXX: Fix memleak. TODO: find out why. */
195 
196  /* We do this to use a special light cache for lookdev.
197  * This light-cache needs to be per viewport. But we need to
198  * have correct freeing when the viewport is closed. So we
199  * need to reference all textures to the txl and the memblocks
200  * to the stl. */
206  }
207 
208  g_data->light_cache = stl->lookdev_lightcache;
209 
210  DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
211  axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z);
212 
213  float studiolight_matrix[3][3] = {{0.0f}};
215  float view_matrix[4][4];
216  float view_rot_matrix[3][3];
217  float x_rot_matrix[3][3];
218  DRW_view_viewmat_get(NULL, view_matrix, false);
219  copy_m3_m4(view_rot_matrix, view_matrix);
220  axis_angle_to_mat3_single(x_rot_matrix, 'X', M_PI_2);
221  mul_m3_m3m3(view_rot_matrix, x_rot_matrix, view_rot_matrix);
222  mul_m3_m3m3(view_rot_matrix, g_data->studiolight_matrix, view_rot_matrix);
223  copy_m3_m3(studiolight_matrix, view_rot_matrix);
224  }
225 
226  DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix);
227 
228  if (probe_render) {
229  /* Avoid artifact with equirectangular mapping. */
231  DRW_shgroup_uniform_float_copy(grp, "studioLightIntensity", shading->studiolight_intensity);
234  /* Do not fade-out when doing probe rendering, only when drawing the background. */
235  DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
236  DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", 0.0f);
237  }
238  else {
239  float background_alpha = g_data->background_alpha * shading->studiolight_background;
240  float studiolight_blur = powf(shading->studiolight_blur, 2.5f);
241  DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha);
242  DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur);
243  DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx);
244  DRW_shgroup_uniform_float_copy(grp, "studioLightIntensity", 1.0f);
245  }
246 
247  /* Common UBOs are setup latter. */
248  *r_shgrp = grp;
249 
250  /* Do we need to recalc the lightprobes? */
251  if (g_data->studiolight_index != sl->index ||
253  !equals_m3m3(g_data->studiolight_matrix, studiolight_matrix)) ||
254  g_data->studiolight_rot_z != shading->studiolight_rot_z ||
255  g_data->studiolight_intensity != shading->studiolight_intensity ||
256  g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution ||
257  g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp ||
258  g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) {
260  g_data->studiolight_index = sl->index;
261  copy_m3_m3(g_data->studiolight_matrix, studiolight_matrix);
262  g_data->studiolight_rot_z = shading->studiolight_rot_z;
263  g_data->studiolight_intensity = shading->studiolight_intensity;
264  g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution;
265  g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp;
266  g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality;
267  }
268  }
269 }
270 
271 static void eevee_lookdev_apply_taa(const EEVEE_EffectsInfo *effects,
272  int sphere_size,
273  float winmat[4][4])
274 {
275  if (DRW_state_is_image_render() || ((effects->enabled_effects & EFFECT_TAA) != 0)) {
276  double ht_point[2];
277  double ht_offset[2] = {0.0, 0.0};
278  const uint ht_primes[2] = {2, 3};
279  float ofs[2];
280 
281  BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample, ht_point);
282  EEVEE_temporal_sampling_offset_calc(ht_point, 1.5f, ofs);
283  winmat[3][0] += ofs[0] / sphere_size;
284  winmat[3][1] += ofs[1] / sphere_size;
285  }
286 }
287 
289 {
290  EEVEE_PassList *psl = vedata->psl;
291  EEVEE_FramebufferList *fbl = vedata->fbl;
292  EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
293  EEVEE_EffectsInfo *effects = stl->effects;
295 
296  const DRWContextState *draw_ctx = DRW_context_state_get();
297 
299  /* Config renderer. */
300  EEVEE_CommonUniformBuffer *common = &sldata->common_data;
301  common->la_num_light = 0;
302  common->prb_num_planar = 0;
303  common->prb_num_render_cube = 1;
304  common->prb_num_render_grid = 1;
305  common->ao_dist = 0.0f;
306  common->ao_factor = 0.0f;
307  common->ao_settings = 0.0f;
308  GPU_uniformbuf_update(sldata->common_ubo, common);
309 
310  /* override matrices */
311  float winmat[4][4], viewmat[4][4];
312  unit_m4(winmat);
313  /* Look through the negative Z. */
314  negate_v3(winmat[2]);
315 
316  eevee_lookdev_apply_taa(effects, effects->sphere_size, winmat);
317 
318  /* "Remove" view matrix location. Leaving only rotation. */
319  DRW_view_viewmat_get(NULL, viewmat, false);
320  zero_v3(viewmat[3]);
321 
322  if (effects->lookdev_view) {
323  /* When rendering just update the view. This avoids recomputing the culling. */
324  DRW_view_update_sub(effects->lookdev_view, viewmat, winmat);
325  }
326  else {
327  /* Using default view bypasses the culling. */
328  const DRWView *default_view = DRW_view_default_get();
329  effects->lookdev_view = DRW_view_create_sub(default_view, viewmat, winmat);
330  }
331 
333 
334  /* Find the right frame-buffers to render to. */
335  GPUFrameBuffer *fb = (effects->target_buffer == fbl->effect_color_fb) ? fbl->main_fb :
336  fbl->effect_fb;
337 
338  DRW_stats_group_start("Look Dev");
339 
341 
342  const int sphere_margin = effects->sphere_size / 6.0f;
343  float offset[2] = {0.0f, sphere_margin};
344 
345  offset[0] = effects->sphere_size + sphere_margin;
347  effects->anchor[0] - offset[0],
348  effects->anchor[1] + offset[1],
349  effects->sphere_size,
350  effects->sphere_size);
351 
353 
354  offset[0] = (effects->sphere_size + sphere_margin) +
355  (sphere_margin + effects->sphere_size + sphere_margin);
357  effects->anchor[0] - offset[0],
358  effects->anchor[1] + offset[1],
359  effects->sphere_size,
360  effects->sphere_size);
361 
363 
365 
367 
369  }
370 }
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:1462
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
Definition: studiolight.c:1517
#define STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE
MINLINE float clamp_f(float value, float min, float max)
#define M_PI_2
Definition: BLI_math_base.h:23
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:71
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
void unit_m4(float m[4][4])
Definition: rct.c:1090
bool equals_m3m3(const float mat1[3][3], const float mat2[3][3])
Definition: math_matrix.c:2525
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:388
void axis_angle_to_mat3_single(float R[3][3], char axis, 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:298
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
unsigned int uint
Definition: BLI_sys_types.h:67
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ LIGHTCACHE_UPDATE_WORLD
@ V3D_SHADING_STUDIOLIGHT_VIEW_ROTATION
DRWState
Definition: DRW_render.h:298
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:302
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:303
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:316
@ DRW_STATE_DEPTH_ALWAYS
Definition: DRW_render.h:309
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:690
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:414
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:183
const rcti * ED_region_visible_rect(ARegion *region)
Definition: area.c:3763
GPUBatch
Definition: GPU_batch.h:78
struct GPUFrameBuffer GPUFrameBuffer
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
struct GPUShader * GPU_material_get_shader(GPUMaterial *material)
Definition: gpu_material.c:191
struct GPUShader GPUShader
Definition: GPU_shader.h:20
eGPUSamplerState
Definition: GPU_texture.h:25
@ GPU_SAMPLER_REPEAT_S
Definition: GPU_texture.h:29
@ GPU_SAMPLER_FILTER
Definition: GPU_texture.h:27
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
#define MEM_SAFE_FREE(v)
unsigned int U
Definition: btGjkEpa3.h:78
#define powf(x, y)
Definition: cuda/compat.h:103
Scene scene
GPUBatch * DRW_cache_sphere_get(const eDRWLevelOfDetail level_of_detail)
Definition: draw_cache.c:482
@ DRW_LOD_MEDIUM
Definition: draw_cache.h:30
@ DRW_LOD_LOW
Definition: draw_cache.h:29
@ DRW_LOD_HIGH
Definition: draw_cache.h:31
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:288
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_draw_pass(DRWPass *pass)
void DRW_view_set_active(const DRWView *view)
void DRW_stats_group_start(const char *name)
void DRW_stats_group_end(void)
static struct @318 g_data
EEVEE_ViewLayerData * EEVEE_view_layer_data_ensure(void)
Definition: eevee_data.c:259
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:84
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:46
void EEVEE_lookdev_draw(EEVEE_Data *vedata)
static void eevee_lookdev_lightcache_delete(EEVEE_Data *vedata)
Definition: eevee_lookdev.c:31
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, const float alpha_clip_threshold, bool use_ssrefraction, bool use_alpha_blend)
@ VAR_MAT_LOOKDEV
@ VAR_MAT_MESH
#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 EEVEE_temporal_sampling_offset_calc(const double ht_point[2], float filter_size, float r_offset[2])
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)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
const int state
ccl_gpu_kernel_postfix ccl_global float int int int int sh
struct Scene * scene
Definition: DRW_render.h:979
struct Depsgraph * depsgraph
Definition: DRW_render.h:987
struct View3D * v3d
Definition: DRW_render.h:976
struct ARegion * region
Definition: DRW_render.h:974
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
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:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63