Fix: Eevee SSS not rendering as expected
[blender.git] / source / blender / draw / engines / eevee / eevee_subsurface.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 \ingroup draw_engine
20  *
21  * Screen space subsurface scattering technique.
22  */
23
24 #include "DRW_render.h"
25
26 #include "BLI_string_utils.h"
27
28 #include "DEG_depsgraph_query.h"
29
30 #include "eevee_private.h"
31 #include "GPU_texture.h"
32 #include "GPU_extensions.h"
33
34 static struct {
35         struct GPUShader *sss_sh[4];
36 } e_data = {{NULL}}; /* Engine data */
37
38 extern char datatoc_common_view_lib_glsl[];
39 extern char datatoc_common_uniforms_lib_glsl[];
40 extern char datatoc_effect_subsurface_frag_glsl[];
41
42 static void eevee_create_shader_subsurface(void)
43 {
44         char *frag_str = BLI_string_joinN(
45                 datatoc_common_view_lib_glsl,
46                 datatoc_common_uniforms_lib_glsl,
47                 datatoc_effect_subsurface_frag_glsl);
48
49         e_data.sss_sh[0] = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
50         e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n");
51         e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n"
52                                                                   "#define USE_SEP_ALBEDO\n");
53         e_data.sss_sh[3] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n"
54                                                                   "#define USE_SEP_ALBEDO\n"
55                                                                   "#define RESULT_ACCUM\n");
56
57         MEM_freeN(frag_str);
58 }
59
60 int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
61 {
62         EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
63         EEVEE_StorageList *stl = vedata->stl;
64         EEVEE_EffectsInfo *effects = stl->effects;
65         EEVEE_FramebufferList *fbl = vedata->fbl;
66         EEVEE_TextureList *txl = vedata->txl;
67         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
68         const float *viewport_size = DRW_viewport_size_get();
69         const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
70
71         const DRWContextState *draw_ctx = DRW_context_state_get();
72         const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
73
74         if (scene_eval->eevee.flag & SCE_EEVEE_SSS_ENABLED) {
75                 effects->sss_sample_count = 1 + scene_eval->eevee.sss_samples * 2;
76                 effects->sss_separate_albedo = (scene_eval->eevee.flag & SCE_EEVEE_SSS_SEPARATE_ALBEDO) != 0;
77                 common_data->sss_jitter_threshold = scene_eval->eevee.sss_jitter_threshold;
78
79                 /* Shaders */
80                 if (!e_data.sss_sh[0]) {
81                         eevee_create_shader_subsurface();
82                 }
83
84                 /* NOTE : we need another stencil because the stencil buffer is on the same texture
85                  * as the depth buffer we are sampling from. This could be avoided if the stencil is
86                  * a separate texture but that needs OpenGL 4.4 or ARB_texture_stencil8.
87                  * OR OpenGL 4.3 / ARB_ES3_compatibility if using a renderbuffer instead */
88                 effects->sss_stencil = DRW_texture_pool_query_2D(fs_size[0], fs_size[1], GPU_DEPTH24_STENCIL8,
89                                                                  &draw_engine_eevee_type);
90                 effects->sss_blur =    DRW_texture_pool_query_2D(fs_size[0], fs_size[1], GPU_RGBA16F,
91                                                                  &draw_engine_eevee_type);
92                 effects->sss_data =    DRW_texture_pool_query_2D(fs_size[0], fs_size[1], GPU_RGBA16F,
93                                                                  &draw_engine_eevee_type);
94
95                 GPUTexture *stencil_tex = effects->sss_stencil;
96
97                 if (GPU_depth_blitting_workaround()) {
98                         /* Blitting stencil buffer does not work on macOS + Radeon Pro.
99                          * Blit depth instead and use sss_stencil's depth as depth texture,
100                          * and dtxl->depth as stencil mask. */
101                         GPU_framebuffer_ensure_config(&fbl->sss_blit_fb, {
102                                 GPU_ATTACHMENT_TEXTURE(effects->sss_stencil),
103                                 GPU_ATTACHMENT_NONE
104                         });
105
106                         stencil_tex = dtxl->depth;
107                 }
108
109                 GPU_framebuffer_ensure_config(&fbl->sss_blur_fb, {
110                         GPU_ATTACHMENT_TEXTURE(stencil_tex),
111                         GPU_ATTACHMENT_TEXTURE(effects->sss_blur)
112                 });
113
114                 GPU_framebuffer_ensure_config(&fbl->sss_resolve_fb, {
115                         GPU_ATTACHMENT_TEXTURE(stencil_tex),
116                         GPU_ATTACHMENT_TEXTURE(txl->color)
117                 });
118
119                 GPU_framebuffer_ensure_config(&fbl->sss_clear_fb, {
120                         GPU_ATTACHMENT_NONE,
121                         GPU_ATTACHMENT_TEXTURE(effects->sss_data)
122                 });
123
124                 if (effects->sss_separate_albedo) {
125                         effects->sss_albedo = DRW_texture_pool_query_2D(fs_size[0], fs_size[1], GPU_R11F_G11F_B10F,
126                                                                         &draw_engine_eevee_type);
127                 }
128                 else {
129                         effects->sss_albedo = NULL;
130                 }
131                 return EFFECT_SSS;
132         }
133
134         /* Cleanup to release memory */
135         GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_blur_fb);
136         GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_resolve_fb);
137         GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_clear_fb);
138         effects->sss_stencil = NULL;
139         effects->sss_blur = NULL;
140         effects->sss_data = NULL;
141
142         return 0;
143 }
144
145 static void set_shgrp_stencil(void *UNUSED(userData), DRWShadingGroup *shgrp)
146 {
147         DRW_shgroup_stencil_mask(shgrp, 255);
148 }
149
150 void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
151 {
152         EEVEE_FramebufferList *fbl = vedata->fbl;
153         EEVEE_TextureList *txl = vedata->txl;
154         EEVEE_StorageList *stl = vedata->stl;
155         EEVEE_EffectsInfo *effects = stl->effects;
156
157         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
158         const DRWContextState *draw_ctx = DRW_context_state_get();
159         const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
160
161         if (scene_eval->eevee.flag & SCE_EEVEE_SSS_ENABLED) {
162                 DRW_texture_ensure_fullscreen_2D(&txl->sss_dir_accum, GPU_RGBA16F, 0);
163                 DRW_texture_ensure_fullscreen_2D(&txl->sss_col_accum, GPU_RGBA16F, 0);
164
165                 GPUTexture *stencil_tex = effects->sss_stencil;
166
167                 if (GPU_depth_blitting_workaround()) {
168                         /* Blitting stencil buffer does not work on macOS + Radeon Pro.
169                          * Blit depth instead and use sss_stencil's depth as depth texture,
170                          * and dtxl->depth as stencil mask. */
171                         stencil_tex = dtxl->depth;
172                 }
173
174                 GPU_framebuffer_ensure_config(&fbl->sss_accum_fb, {
175                         GPU_ATTACHMENT_TEXTURE(stencil_tex),
176                         GPU_ATTACHMENT_TEXTURE(txl->sss_dir_accum),
177                         GPU_ATTACHMENT_TEXTURE(txl->sss_col_accum)
178                 });
179
180                 /* Clear texture. */
181                 float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
182                 GPU_framebuffer_bind(fbl->sss_accum_fb);
183                 GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
184
185                 /* Make the opaque refraction pass mask the sss. */
186                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
187                                  DRW_STATE_WIRE | DRW_STATE_WRITE_STENCIL;
188                 DRW_pass_state_set(vedata->psl->refract_pass, state);
189                 DRW_pass_foreach_shgroup(vedata->psl->refract_pass, &set_shgrp_stencil, NULL);
190         }
191         else {
192                 /* Cleanup to release memory */
193                 DRW_TEXTURE_FREE_SAFE(txl->sss_dir_accum);
194                 DRW_TEXTURE_FREE_SAFE(txl->sss_col_accum);
195                 GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
196         }
197 }
198
199 void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
200 {
201         EEVEE_PassList *psl = vedata->psl;
202         EEVEE_StorageList *stl = vedata->stl;
203         EEVEE_EffectsInfo *effects = stl->effects;
204
205         if ((effects->enabled_effects & EFFECT_SSS) != 0) {
206                 /** Screen Space SubSurface Scattering overview
207                  * TODO
208                  */
209                 psl->sss_blur_ps = DRW_pass_create("Blur Horiz", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
210
211                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE | DRW_STATE_STENCIL_EQUAL;
212                 psl->sss_resolve_ps = DRW_pass_create("Blur Vert", state);
213                 psl->sss_accum_ps = DRW_pass_create("Resolve Accum", state);
214         }
215 }
216
217 void EEVEE_subsurface_add_pass(
218         EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint sss_id, struct GPUUniformBuffer *sss_profile)
219 {
220         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
221         EEVEE_PassList *psl = vedata->psl;
222         EEVEE_StorageList *stl = vedata->stl;
223         EEVEE_EffectsInfo *effects = stl->effects;
224         struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
225         GPUTexture **depth_src = GPU_depth_blitting_workaround() ? &effects->sss_stencil : &dtxl->depth;
226
227         DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[0], psl->sss_blur_ps);
228         DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
229         DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
230         DRW_shgroup_uniform_texture_ref(grp, "sssData", &effects->sss_data);
231         DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
232         DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
233         DRW_shgroup_stencil_mask(grp, sss_id);
234         DRW_shgroup_call_add(grp, quad, NULL);
235
236         struct GPUShader *sh = (effects->sss_separate_albedo) ? e_data.sss_sh[2] : e_data.sss_sh[1];
237         grp = DRW_shgroup_create(sh, psl->sss_resolve_ps);
238         DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
239         DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
240         DRW_shgroup_uniform_texture_ref(grp, "sssData", &effects->sss_blur);
241         DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
242         DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
243         DRW_shgroup_stencil_mask(grp, sss_id);
244         DRW_shgroup_call_add(grp, quad, NULL);
245
246         if (effects->sss_separate_albedo) {
247                 DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo);
248         }
249
250         if (DRW_state_is_image_render()) {
251                 grp = DRW_shgroup_create(e_data.sss_sh[3], psl->sss_accum_ps);
252                 DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
253                 DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
254                 DRW_shgroup_uniform_texture_ref(grp, "sssData", &effects->sss_blur);
255                 DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo);
256                 DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
257                 DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
258                 DRW_shgroup_stencil_mask(grp, sss_id);
259                 DRW_shgroup_call_add(grp, quad, NULL);
260         }
261 }
262
263 void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
264 {
265         EEVEE_PassList *psl = vedata->psl;
266         EEVEE_FramebufferList *fbl = vedata->fbl;
267         EEVEE_StorageList *stl = vedata->stl;
268         EEVEE_EffectsInfo *effects = stl->effects;
269
270         if ((effects->enabled_effects & EFFECT_SSS) != 0) {
271                 float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
272                 /* Clear sss_data texture only... can this be done in a more clever way? */
273                 GPU_framebuffer_bind(fbl->sss_clear_fb);
274                 GPU_framebuffer_clear_color(fbl->sss_clear_fb, clear);
275
276                 GPU_framebuffer_ensure_config(&fbl->main_fb, {
277                         GPU_ATTACHMENT_LEAVE,
278                         GPU_ATTACHMENT_LEAVE,
279                         GPU_ATTACHMENT_LEAVE,
280                         GPU_ATTACHMENT_LEAVE,
281                         GPU_ATTACHMENT_TEXTURE(effects->sss_data),
282                         GPU_ATTACHMENT_TEXTURE(effects->sss_albedo)
283                 });
284
285                 GPU_framebuffer_bind(fbl->main_fb);
286                 DRW_draw_pass(psl->sss_pass);
287
288                 /* Restore */
289                 GPU_framebuffer_ensure_config(&fbl->main_fb, {
290                         GPU_ATTACHMENT_LEAVE,
291                         GPU_ATTACHMENT_LEAVE,
292                         GPU_ATTACHMENT_LEAVE,
293                         GPU_ATTACHMENT_LEAVE,
294                         GPU_ATTACHMENT_NONE,
295                         GPU_ATTACHMENT_NONE
296                 });
297         }
298 }
299
300 void EEVEE_subsurface_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
301 {
302         EEVEE_PassList *psl = vedata->psl;
303         EEVEE_StorageList *stl = vedata->stl;
304         EEVEE_TextureList *txl = vedata->txl;
305         EEVEE_FramebufferList *fbl = vedata->fbl;
306         EEVEE_EffectsInfo *effects = stl->effects;
307
308         if ((effects->enabled_effects & EFFECT_SSS) != 0) {
309                 float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
310
311                 DRW_stats_group_start("SSS");
312
313                 if (GPU_depth_blitting_workaround()) {
314                         /* Copy depth channel */
315                         GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_blit_fb, 0, GPU_DEPTH_BIT);
316                 }
317                 else {
318                         /* Copy stencil channel, could be avoided (see EEVEE_subsurface_init) */
319                         GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_blur_fb, 0, GPU_STENCIL_BIT);
320                 }
321
322                 /* 1. horizontal pass */
323                 GPU_framebuffer_bind(fbl->sss_blur_fb);
324                 GPU_framebuffer_clear_color(fbl->sss_blur_fb, clear);
325                 DRW_draw_pass(psl->sss_blur_ps);
326
327                 /* 2. vertical pass + Resolve */
328                 GPU_framebuffer_texture_attach(fbl->sss_resolve_fb, txl->color, 0, 0);
329                 GPU_framebuffer_bind(fbl->sss_resolve_fb);
330                 DRW_draw_pass(psl->sss_resolve_ps);
331
332                 GPU_framebuffer_bind(fbl->main_fb);
333                 DRW_stats_group_end();
334         }
335 }
336
337 void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
338 {
339         EEVEE_PassList *psl = vedata->psl;
340         EEVEE_FramebufferList *fbl = vedata->fbl;
341         EEVEE_StorageList *stl = vedata->stl;
342         EEVEE_EffectsInfo *effects = stl->effects;
343
344         if (((effects->enabled_effects & EFFECT_SSS) != 0) && (fbl->sss_accum_fb != NULL)) {
345                 /* Copy stencil channel, could be avoided (see EEVEE_subsurface_init) */
346                 GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_blur_fb, 0, GPU_STENCIL_BIT);
347
348                 /* Only do vertical pass + Resolve */
349                 GPU_framebuffer_bind(fbl->sss_accum_fb);
350                 DRW_draw_pass(psl->sss_accum_ps);
351
352                 /* Restore */
353                 GPU_framebuffer_bind(fbl->main_fb);
354         }
355 }
356
357 void EEVEE_subsurface_free(void)
358 {
359         DRW_SHADER_FREE_SAFE(e_data.sss_sh[0]);
360         DRW_SHADER_FREE_SAFE(e_data.sss_sh[1]);
361         DRW_SHADER_FREE_SAFE(e_data.sss_sh[2]);
362         DRW_SHADER_FREE_SAFE(e_data.sss_sh[3]);
363 }