doxygen: add newline after \file
[blender.git] / source / blender / draw / engines / eevee / eevee_lookdev.c
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
19 /** \file
20  * \ingroup draw_engine
21  */
22 #include "DRW_render.h"
23
24 #include "BKE_camera.h"
25 #include "BKE_studiolight.h"
26
27 #include "DNA_screen_types.h"
28 #include "DNA_world_types.h"
29
30 #include "DEG_depsgraph_query.h"
31
32 #include "ED_screen.h"
33
34 #include "UI_resources.h"
35
36 #include "eevee_private.h"
37 #include "eevee_lightcache.h"
38
39 #include "draw_common.h"
40
41 static void eevee_lookdev_lightcache_delete(EEVEE_Data *vedata)
42 {
43         EEVEE_StorageList *stl = vedata->stl;
44         EEVEE_TextureList *txl = vedata->txl;
45
46         MEM_SAFE_FREE(stl->lookdev_lightcache);
47         MEM_SAFE_FREE(stl->lookdev_grid_data);
48         MEM_SAFE_FREE(stl->lookdev_cube_data);
49         DRW_TEXTURE_FREE_SAFE(txl->lookdev_grid_tx);
50         DRW_TEXTURE_FREE_SAFE(txl->lookdev_cube_tx);
51 }
52
53 void EEVEE_lookdev_cache_init(
54         EEVEE_Data *vedata, DRWShadingGroup **grp, DRWPass *pass,
55         World *UNUSED(world), EEVEE_LightProbesInfo *pinfo)
56 {
57         EEVEE_StorageList *stl = vedata->stl;
58         EEVEE_TextureList *txl = vedata->txl;
59         const DRWContextState *draw_ctx = DRW_context_state_get();
60         View3D *v3d = draw_ctx->v3d;
61         if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) {
62                 StudioLight *sl = BKE_studiolight_find(v3d->shading.lookdev_light, STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE);
63                 if (sl && (sl->flag & STUDIOLIGHT_TYPE_WORLD)) {
64                         GPUShader *shader = EEVEE_shaders_default_studiolight_sh_get();
65                         struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
66                         GPUTexture *tex = NULL;
67
68                         /* If one of the component is missing we start from scratch. */
69                         if ((stl->lookdev_grid_data == NULL) ||
70                             (stl->lookdev_cube_data == NULL) ||
71                             (txl->lookdev_grid_tx == NULL) ||
72                             (txl->lookdev_cube_tx == NULL))
73                         {
74                                 eevee_lookdev_lightcache_delete(vedata);
75                         }
76
77                         if (stl->lookdev_lightcache == NULL) {
78                                 const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
79 #if defined(IRRADIANCE_SH_L2)
80                                 int grid_res = 4;
81 #elif defined(IRRADIANCE_CUBEMAP)
82                                 int grid_res = 8;
83 #elif defined(IRRADIANCE_HL2)
84                                 int grid_res = 4;
85 #endif
86                                 int cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(scene_eval->eevee.gi_cubemap_resolution);
87                                 int vis_res = scene_eval->eevee.gi_visibility_resolution;
88
89                                 stl->lookdev_lightcache = EEVEE_lightcache_create(1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1});
90
91                                 /* XXX: Fix memleak. TODO find out why. */
92                                 MEM_SAFE_FREE(stl->lookdev_cube_mips);
93
94                                 /* We do this to use a special light cache for lookdev.
95                                  * This lightcache needs to be per viewport. But we need to
96                                  * have correct freeing when the viewport is closed. So we
97                                  * need to reference all textures to the txl and the memblocks
98                                  * to the stl. */
99                                 stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data;
100                                 stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data;
101                                 stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips;
102                                 txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex;
103                                 txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
104                         }
105
106                         stl->g_data->light_cache = stl->lookdev_lightcache;
107
108                         static float background_color[4];
109                         UI_GetThemeColor4fv(TH_BACK, background_color);
110                         /* XXX: Really quick conversion to avoid washed out background.
111                          * Needs to be addressed properly (color managed using ocio). */
112                         srgb_to_linearrgb_v4(background_color, background_color);
113
114                         *grp = DRW_shgroup_create(shader, pass);
115                         axis_angle_to_mat3_single(stl->g_data->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z);
116                         DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->g_data->studiolight_matrix);
117                         DRW_shgroup_uniform_float(*grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
118                         DRW_shgroup_uniform_vec3(*grp, "color", background_color, 1);
119                         DRW_shgroup_call_add(*grp, geom, NULL);
120                         if (!pinfo) {
121                                 /* Do not fadeout when doing probe rendering, only when drawing the background */
122                                 DRW_shgroup_uniform_float(*grp, "studioLightBackground", &v3d->shading.studiolight_background, 1);
123                                 BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_IRRADIANCE_GPUTEXTURE);
124                                 tex = sl->equirect_irradiance_gputexture;
125                         }
126                         else {
127                                 DRW_shgroup_uniform_float_copy(*grp, "studioLightBackground", 1.0f);
128                                 BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
129                                 tex = sl->equirect_radiance_gputexture;
130                         }
131                         DRW_shgroup_uniform_texture(*grp, "image", tex);
132
133                         /* Do we need to recalc the lightprobes? */
134                         if (pinfo &&
135                             ((pinfo->studiolight_index != sl->index) ||
136                              (pinfo->studiolight_rot_z != v3d->shading.studiolight_rot_z)))
137                         {
138                                 stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
139                                 pinfo->studiolight_index = sl->index;
140                                 pinfo->studiolight_rot_z = v3d->shading.studiolight_rot_z;
141                         }
142                 }
143         }
144 }
145
146 void EEVEE_lookdev_draw_background(EEVEE_Data *vedata)
147 {
148         EEVEE_PassList *psl = vedata->psl;
149         EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
150         EEVEE_EffectsInfo *effects = stl->effects;
151         EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
152         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
153
154         const DRWContextState *draw_ctx = DRW_context_state_get();
155
156         if (psl->lookdev_pass && LOOK_DEV_OVERLAY_ENABLED(draw_ctx->v3d)) {
157                 DRW_stats_group_start("Look Dev");
158                 CameraParams params;
159                 BKE_camera_params_init(&params);
160                 View3D *v3d = draw_ctx->v3d;
161                 RegionView3D *rv3d = draw_ctx->rv3d;
162                 ARegion *ar = draw_ctx->ar;
163
164                 const float *viewport_size = DRW_viewport_size_get();
165                 rcti rect;
166                 ED_region_visible_rect(draw_ctx->ar, &rect);
167
168                 const float viewport_size_target[2] = {
169                         viewport_size[0] / 4,
170                         viewport_size[1] / 4,
171                 };
172                 const int viewport_inset[2] = {
173                         max_ii(viewport_size_target[0], 300),
174                         max_ii(viewport_size_target[0], 300) / 2,  /* intentionally use 'x' here for 'y' value. */
175                 };
176
177                 /* minimum size for preview spheres viewport */
178                 const float aspect[2] = {
179                         viewport_inset[0] / viewport_size_target[0],
180                         viewport_inset[1] / viewport_size_target[1],
181                 };
182
183                 BKE_camera_params_from_view3d(&params, draw_ctx->depsgraph, v3d, rv3d);
184                 params.is_ortho = true;
185                 params.ortho_scale = 3.0f;
186                 params.zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
187                 params.offsetx = 0.0f;
188                 params.offsety = 0.0f;
189                 params.shiftx = 0.0f;
190                 params.shifty = 0.0f;
191                 params.clip_start = 0.001f;
192                 params.clip_end = 20.0f;
193                 BKE_camera_params_compute_viewplane(&params, ar->winx, ar->winy, aspect[0], aspect[1]);
194                 BKE_camera_params_compute_matrix(&params);
195
196                 EEVEE_CommonUniformBuffer *common = &sldata->common_data;
197                 common->la_num_light = 0;
198                 common->prb_num_planar = 0;
199                 common->prb_num_render_cube = 1;
200                 common->prb_num_render_grid = 1;
201                 common->ao_dist = 0.0f;
202                 common->ao_factor = 0.0f;
203                 common->ao_settings = 0.0f;
204                 DRW_uniformbuffer_update(sldata->common_ubo, common);
205
206                 /* override matrices */
207                 float winmat[4][4];
208                 float winmat_inv[4][4];
209                 copy_m4_m4(winmat, params.winmat);
210                 invert_m4_m4(winmat_inv, winmat);
211                 DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN);
212                 DRW_viewport_matrix_override_set(winmat_inv, DRW_MAT_WININV);
213                 float viewmat[4][4];
214                 DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
215                 float persmat[4][4];
216                 float persmat_inv[4][4];
217                 mul_m4_m4m4(persmat, winmat, viewmat);
218                 invert_m4_m4(persmat_inv, persmat);
219                 DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
220                 DRW_viewport_matrix_override_set(persmat_inv, DRW_MAT_PERSINV);
221
222                 GPUFrameBuffer *fb = effects->final_fb;
223                 GPU_framebuffer_bind(fb);
224                 GPU_framebuffer_viewport_set(fb, rect.xmax - viewport_inset[0], rect.ymin, viewport_inset[0], viewport_inset[1]);
225                 DRW_draw_pass(psl->lookdev_pass);
226
227                 fb = dfbl->depth_only_fb;
228                 GPU_framebuffer_bind(fb);
229                 GPU_framebuffer_viewport_set(fb, rect.xmax - viewport_inset[0], rect.ymin, viewport_inset[0], viewport_inset[1]);
230                 DRW_draw_pass(psl->lookdev_pass);
231
232                 DRW_viewport_matrix_override_unset_all();
233                 DRW_stats_group_end();
234         }
235 }