d0f544dd3c635c393d72d59c9b3891b58ee78dc9
[blender.git] / source / blender / draw / engines / eevee / eevee_depth_of_field.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  * Depth of field post process effect.
23  */
24
25 #include "DRW_render.h"
26
27 #include "DNA_camera_types.h"
28 #include "DNA_screen_types.h"
29 #include "DNA_view3d_types.h"
30 #include "DNA_world_types.h"
31
32 #include "BKE_camera.h"
33
34 #include "DEG_depsgraph.h"
35 #include "DEG_depsgraph_query.h"
36
37 #include "eevee_private.h"
38 #include "GPU_framebuffer.h"
39 #include "GPU_texture.h"
40
41 static struct {
42   /* Depth Of Field */
43   struct GPUShader *dof_downsample_sh[2];
44   struct GPUShader *dof_scatter_sh[2];
45   struct GPUShader *dof_resolve_sh[2];
46 } e_data = {{NULL}}; /* Engine data */
47
48 extern char datatoc_effect_dof_vert_glsl[];
49 extern char datatoc_effect_dof_frag_glsl[];
50
51 static void eevee_create_shader_depth_of_field(const bool use_alpha)
52 {
53   e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen(
54       datatoc_effect_dof_frag_glsl,
55       use_alpha ? "#define USE_ALPHA_DOF\n"
56                   "#define STEP_DOWNSAMPLE\n" :
57                   "#define STEP_DOWNSAMPLE\n");
58   e_data.dof_scatter_sh[use_alpha] = DRW_shader_create(datatoc_effect_dof_vert_glsl,
59                                                        NULL,
60                                                        datatoc_effect_dof_frag_glsl,
61                                                        use_alpha ? "#define USE_ALPHA_DOF\n"
62                                                                    "#define STEP_SCATTER\n" :
63                                                                    "#define STEP_SCATTER\n");
64   e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen(datatoc_effect_dof_frag_glsl,
65                                                                   use_alpha ?
66                                                                       "#define USE_ALPHA_DOF\n"
67                                                                       "#define STEP_RESOLVE\n" :
68                                                                       "#define STEP_RESOLVE\n");
69 }
70
71 int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata),
72                               EEVEE_Data *vedata,
73                               Object *camera)
74 {
75   EEVEE_StorageList *stl = vedata->stl;
76   EEVEE_FramebufferList *fbl = vedata->fbl;
77   EEVEE_EffectsInfo *effects = stl->effects;
78
79   const DRWContextState *draw_ctx = DRW_context_state_get();
80   const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
81
82   Camera *cam = (camera != NULL) ? camera->data : NULL;
83
84   if (cam && (cam->dof.flag & CAM_DOF_ENABLED)) {
85     RegionView3D *rv3d = draw_ctx->rv3d;
86     const bool use_alpha = !DRW_state_draw_background();
87
88     if (!e_data.dof_downsample_sh[use_alpha]) {
89       eevee_create_shader_depth_of_field(use_alpha);
90     }
91
92     const float *viewport_size = DRW_viewport_size_get();
93
94     /* Retrieve Near and Far distance */
95     effects->dof_near_far[0] = -cam->clip_start;
96     effects->dof_near_far[1] = -cam->clip_end;
97
98     int buffer_size[2] = {(int)viewport_size[0] / 2, (int)viewport_size[1] / 2};
99
100     eGPUTextureFormat down_format = DRW_state_draw_background() ? GPU_R11F_G11F_B10F : GPU_RGBA16F;
101
102     effects->dof_down_near = DRW_texture_pool_query_2d(
103         buffer_size[0], buffer_size[1], down_format, &draw_engine_eevee_type);
104     effects->dof_down_far = DRW_texture_pool_query_2d(
105         buffer_size[0], buffer_size[1], down_format, &draw_engine_eevee_type);
106     effects->dof_coc = DRW_texture_pool_query_2d(
107         buffer_size[0], buffer_size[1], GPU_RG16F, &draw_engine_eevee_type);
108
109     GPU_framebuffer_ensure_config(&fbl->dof_down_fb,
110                                   {GPU_ATTACHMENT_NONE,
111                                    GPU_ATTACHMENT_TEXTURE(effects->dof_down_near),
112                                    GPU_ATTACHMENT_TEXTURE(effects->dof_down_far),
113                                    GPU_ATTACHMENT_TEXTURE(effects->dof_coc)});
114
115     /* Go full 32bits for rendering and reduce the color artifacts. */
116     eGPUTextureFormat fb_format = DRW_state_is_image_render() ? GPU_RGBA32F : GPU_RGBA16F;
117
118     effects->dof_blur = DRW_texture_pool_query_2d(
119         buffer_size[0] * 2, buffer_size[1], fb_format, &draw_engine_eevee_type);
120
121     GPU_framebuffer_ensure_config(&fbl->dof_scatter_fb,
122                                   {
123                                       GPU_ATTACHMENT_NONE,
124                                       GPU_ATTACHMENT_TEXTURE(effects->dof_blur),
125                                   });
126
127     if (!DRW_state_draw_background()) {
128       effects->dof_blur_alpha = DRW_texture_pool_query_2d(
129           buffer_size[0] * 2, buffer_size[1], GPU_R32F, &draw_engine_eevee_type);
130       GPU_framebuffer_texture_attach(fbl->dof_scatter_fb, effects->dof_blur_alpha, 1, 0);
131     }
132
133     /* Parameters */
134     /* TODO UI Options */
135     float fstop = cam->dof.aperture_fstop;
136     float blades = cam->dof.aperture_blades;
137     float rotation = cam->dof.aperture_rotation;
138     float ratio = 1.0f / cam->dof.aperture_ratio;
139     float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
140     float focus_dist = BKE_camera_object_dof_distance(camera);
141     float focal_len = cam->lens;
142
143     const float scale_camera = 0.001f;
144     /* we want radius here for the aperture number  */
145     float aperture = 0.5f * scale_camera * focal_len / fstop;
146     float focal_len_scaled = scale_camera * focal_len;
147     float sensor_scaled = scale_camera * sensor;
148
149     if (rv3d != NULL) {
150       sensor_scaled *= rv3d->viewcamtexcofac[0];
151     }
152
153     effects->dof_params[1] = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
154     effects->dof_params[1] *= viewport_size[0] / sensor_scaled;
155     effects->dof_params[0] = -focus_dist * effects->dof_params[1];
156
157     effects->dof_bokeh[0] = rotation;
158     effects->dof_bokeh[1] = ratio;
159     effects->dof_bokeh[2] = scene_eval->eevee.bokeh_max_size;
160
161     /* Precompute values to save instructions in fragment shader. */
162     effects->dof_bokeh_sides[0] = blades;
163     effects->dof_bokeh_sides[1] = blades > 0.0f ? 2.0f * M_PI / blades : 0.0f;
164     effects->dof_bokeh_sides[2] = blades / (2.0f * M_PI);
165     effects->dof_bokeh_sides[3] = blades > 0.0f ? cosf(M_PI / blades) : 0.0f;
166
167     return EFFECT_DOF | EFFECT_POST_BUFFER;
168   }
169
170   /* Cleanup to release memory */
171   GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_down_fb);
172   GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_scatter_fb);
173
174   return 0;
175 }
176
177 void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
178 {
179   EEVEE_PassList *psl = vedata->psl;
180   EEVEE_StorageList *stl = vedata->stl;
181   EEVEE_EffectsInfo *effects = stl->effects;
182   DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
183
184   if ((effects->enabled_effects & EFFECT_DOF) != 0) {
185     /**  Depth of Field algorithm
186      *
187      * Overview :
188      * - Down-sample the color buffer into 2 buffers weighted with
189      *   CoC values. Also output CoC into a texture.
190      * - Shoot quads for every pixel and expand it depending on the CoC.
191      *   Do one pass for near Dof and one pass for far Dof.
192      * - Finally composite the 2 blurred buffers with the original render.
193      */
194     DRWShadingGroup *grp;
195     struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
196     const bool use_alpha = !DRW_state_draw_background();
197
198     DRW_PASS_CREATE(psl->dof_down, DRW_STATE_WRITE_COLOR);
199
200     grp = DRW_shgroup_create(e_data.dof_downsample_sh[use_alpha], psl->dof_down);
201     DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
202     DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
203     DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
204     DRW_shgroup_uniform_vec2(grp, "dofParams", effects->dof_params, 1);
205     DRW_shgroup_call(grp, quad, NULL);
206
207     DRW_PASS_CREATE(psl->dof_scatter, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
208
209     /* This create an empty batch of N triangles to be positioned
210      * by the vertex shader 0.4ms against 6ms with instancing */
211     const float *viewport_size = DRW_viewport_size_get();
212     const int sprite_len = ((int)viewport_size[0] / 2) *
213                            ((int)viewport_size[1] / 2); /* brackets matters */
214     grp = DRW_shgroup_create(e_data.dof_scatter_sh[use_alpha], psl->dof_scatter);
215     DRW_shgroup_uniform_texture_ref(grp, "nearBuffer", &effects->dof_down_near);
216     DRW_shgroup_uniform_texture_ref(grp, "farBuffer", &effects->dof_down_far);
217     DRW_shgroup_uniform_texture_ref(grp, "cocBuffer", &effects->dof_coc);
218     DRW_shgroup_uniform_vec4(grp, "bokehParams", effects->dof_bokeh, 2);
219
220     DRW_shgroup_call_procedural_triangles(grp, NULL, sprite_len);
221
222     DRW_PASS_CREATE(psl->dof_resolve, DRW_STATE_WRITE_COLOR);
223
224     grp = DRW_shgroup_create(e_data.dof_resolve_sh[use_alpha], psl->dof_resolve);
225     DRW_shgroup_uniform_texture_ref(grp, "scatterBuffer", &effects->dof_blur);
226     DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
227     DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
228     DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
229     DRW_shgroup_uniform_vec2(grp, "dofParams", effects->dof_params, 1);
230     DRW_shgroup_call(grp, quad, NULL);
231
232     if (use_alpha) {
233       DRW_shgroup_uniform_texture_ref(grp, "scatterAlphaBuffer", &effects->dof_blur_alpha);
234       DRW_shgroup_uniform_bool_copy(grp, "unpremult", DRW_state_is_image_render());
235     }
236   }
237 }
238
239 void EEVEE_depth_of_field_draw(EEVEE_Data *vedata)
240 {
241   EEVEE_PassList *psl = vedata->psl;
242   EEVEE_TextureList *txl = vedata->txl;
243   EEVEE_FramebufferList *fbl = vedata->fbl;
244   EEVEE_StorageList *stl = vedata->stl;
245   EEVEE_EffectsInfo *effects = stl->effects;
246
247   /* Depth Of Field */
248   if ((effects->enabled_effects & EFFECT_DOF) != 0) {
249     float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
250
251     /* Downsample */
252     GPU_framebuffer_bind(fbl->dof_down_fb);
253     DRW_draw_pass(psl->dof_down);
254
255     /* Scatter */
256     GPU_framebuffer_bind(fbl->dof_scatter_fb);
257     GPU_framebuffer_clear_color(fbl->dof_scatter_fb, clear_col);
258     DRW_draw_pass(psl->dof_scatter);
259
260     /* Resolve */
261     GPU_framebuffer_bind(effects->target_buffer);
262     DRW_draw_pass(psl->dof_resolve);
263     SWAP_BUFFERS();
264   }
265 }
266
267 void EEVEE_depth_of_field_free(void)
268 {
269   for (int i = 0; i < 2; ++i) {
270     DRW_SHADER_FREE_SAFE(e_data.dof_downsample_sh[i]);
271     DRW_SHADER_FREE_SAFE(e_data.dof_scatter_sh[i]);
272     DRW_SHADER_FREE_SAFE(e_data.dof_resolve_sh[i]);
273   }
274 }