| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-01-23 11:29:18 +11:00
										 |  |  |  * Copyright 2016, Blender Foundation. | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup draw_engine | 
					
						
							| 
									
										
										
										
											2017-11-20 14:11:45 +11:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Screen space subsurface scattering technique. | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DRW_render.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-21 17:25:10 +01:00
										 |  |  | #include "BLI_string_utils.h"
 | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 19:34:24 +02:00
										 |  |  | #include "DEG_depsgraph_query.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 22:13:46 +02:00
										 |  |  | #include "GPU_extensions.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "GPU_texture.h"
 | 
					
						
							|  |  |  | #include "eevee_private.h"
 | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static struct { | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   struct GPUShader *sss_sh[3]; | 
					
						
							| 
									
										
										
										
											2018-03-16 05:08:28 +01:00
										 |  |  | } e_data = {{NULL}}; /* Engine data */ | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-10 00:00:04 +01:00
										 |  |  | extern char datatoc_common_view_lib_glsl[]; | 
					
						
							| 
									
										
										
										
											2018-01-21 17:25:10 +01:00
										 |  |  | extern char datatoc_common_uniforms_lib_glsl[]; | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  | extern char datatoc_lights_lib_glsl[]; | 
					
						
							|  |  |  | extern char datatoc_raytrace_lib_glsl[]; | 
					
						
							|  |  |  | extern char datatoc_octahedron_lib_glsl[]; | 
					
						
							| 
									
										
										
										
											2020-03-11 17:12:01 +01:00
										 |  |  | extern char datatoc_cubemap_lib_glsl[]; | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  | extern char datatoc_bsdf_sampling_lib_glsl[]; | 
					
						
							|  |  |  | extern char datatoc_bsdf_common_lib_glsl[]; | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | extern char datatoc_effect_subsurface_frag_glsl[]; | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  | extern char datatoc_effect_translucency_frag_glsl[]; | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void eevee_create_shader_subsurface(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl, | 
					
						
							|  |  |  |                                     datatoc_common_uniforms_lib_glsl, | 
					
						
							|  |  |  |                                     datatoc_effect_subsurface_frag_glsl); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |   /* TODO(fclem) remove some of these dependencies. */ | 
					
						
							|  |  |  |   char *frag_translucent_str = BLI_string_joinN(datatoc_common_view_lib_glsl, | 
					
						
							|  |  |  |                                                 datatoc_common_uniforms_lib_glsl, | 
					
						
							|  |  |  |                                                 datatoc_bsdf_common_lib_glsl, | 
					
						
							|  |  |  |                                                 datatoc_bsdf_sampling_lib_glsl, | 
					
						
							|  |  |  |                                                 datatoc_raytrace_lib_glsl, | 
					
						
							|  |  |  |                                                 datatoc_octahedron_lib_glsl, | 
					
						
							| 
									
										
										
										
											2020-03-11 17:12:01 +01:00
										 |  |  |                                                 datatoc_cubemap_lib_glsl, | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |                                                 datatoc_lights_lib_glsl, | 
					
						
							|  |  |  |                                                 datatoc_effect_translucency_frag_glsl); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   e_data.sss_sh[0] = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n"); | 
					
						
							|  |  |  |   e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n"); | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_translucent_str, | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |                                                   "#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |   MEM_freeN(frag_translucent_str); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   MEM_freeN(frag_str); | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  | void EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; | 
					
						
							|  |  |  |   EEVEE_StorageList *stl = vedata->stl; | 
					
						
							|  |  |  |   EEVEE_EffectsInfo *effects = stl->effects; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const DRWContextState *draw_ctx = DRW_context_state_get(); | 
					
						
							|  |  |  |   const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  |   effects->sss_sample_count = 1 + scene_eval->eevee.sss_samples * 2; | 
					
						
							|  |  |  |   common_data->sss_jitter_threshold = scene_eval->eevee.sss_jitter_threshold; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  | void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   EEVEE_EffectsInfo *effects = vedata->stl->effects; | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   EEVEE_StorageList *stl = vedata->stl; | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  |   EEVEE_FramebufferList *fbl = vedata->fbl; | 
					
						
							|  |  |  |   EEVEE_TextureList *txl = vedata->txl; | 
					
						
							|  |  |  |   DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | 
					
						
							|  |  |  |   const float *viewport_size = DRW_viewport_size_get(); | 
					
						
							|  |  |  |   const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  |   if (effects->enabled_effects & EFFECT_SSS) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* NOTE : we need another stencil because the stencil buffer is on the same texture
 | 
					
						
							|  |  |  |      * as the depth buffer we are sampling from. This could be avoided if the stencil is | 
					
						
							|  |  |  |      * a separate texture but that needs OpenGL 4.4 or ARB_texture_stencil8. | 
					
						
							|  |  |  |      * OR OpenGL 4.3 / ARB_ES3_compatibility if using a renderbuffer instead */ | 
					
						
							|  |  |  |     effects->sss_stencil = DRW_texture_pool_query_2d( | 
					
						
							|  |  |  |         fs_size[0], fs_size[1], GPU_DEPTH24_STENCIL8, &draw_engine_eevee_type); | 
					
						
							|  |  |  |     effects->sss_blur = DRW_texture_pool_query_2d( | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |         fs_size[0], fs_size[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type); | 
					
						
							|  |  |  |     effects->sss_irradiance = DRW_texture_pool_query_2d( | 
					
						
							|  |  |  |         fs_size[0], fs_size[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type); | 
					
						
							|  |  |  |     effects->sss_radius = DRW_texture_pool_query_2d( | 
					
						
							|  |  |  |         fs_size[0], fs_size[1], GPU_R16F, &draw_engine_eevee_type); | 
					
						
							|  |  |  |     effects->sss_albedo = DRW_texture_pool_query_2d( | 
					
						
							|  |  |  |         fs_size[0], fs_size[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     GPUTexture *stencil_tex = effects->sss_stencil; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (GPU_depth_blitting_workaround()) { | 
					
						
							|  |  |  |       /* Blitting stencil buffer does not work on macOS + Radeon Pro.
 | 
					
						
							|  |  |  |        * Blit depth instead and use sss_stencil's depth as depth texture, | 
					
						
							|  |  |  |        * and dtxl->depth as stencil mask. */ | 
					
						
							|  |  |  |       GPU_framebuffer_ensure_config( | 
					
						
							|  |  |  |           &fbl->sss_blit_fb, {GPU_ATTACHMENT_TEXTURE(effects->sss_stencil), GPU_ATTACHMENT_NONE}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       stencil_tex = dtxl->depth; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GPU_framebuffer_ensure_config( | 
					
						
							|  |  |  |         &fbl->sss_blur_fb, | 
					
						
							|  |  |  |         {GPU_ATTACHMENT_TEXTURE(stencil_tex), GPU_ATTACHMENT_TEXTURE(effects->sss_blur)}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GPU_framebuffer_ensure_config( | 
					
						
							|  |  |  |         &fbl->sss_resolve_fb, | 
					
						
							|  |  |  |         {GPU_ATTACHMENT_TEXTURE(stencil_tex), GPU_ATTACHMENT_TEXTURE(txl->color)}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GPU_framebuffer_ensure_config( | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |         &fbl->sss_translucency_fb, | 
					
						
							|  |  |  |         {GPU_ATTACHMENT_TEXTURE(stencil_tex), GPU_ATTACHMENT_TEXTURE(effects->sss_irradiance)}); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |     GPU_framebuffer_ensure_config(&fbl->sss_clear_fb, | 
					
						
							|  |  |  |                                   {GPU_ATTACHMENT_NONE, | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_TEXTURE(effects->sss_irradiance), | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_TEXTURE(effects->sss_radius)}); | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |     if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) != 0) { | 
					
						
							|  |  |  |       EEVEE_subsurface_output_init(sldata, vedata, 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb); | 
					
						
							| 
									
										
										
										
											2020-05-29 12:31:02 +02:00
										 |  |  |       DRW_TEXTURE_FREE_SAFE(txl->sss_accum); | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  |   else { | 
					
						
							|  |  |  |     /* Cleanup to release memory */ | 
					
						
							|  |  |  |     GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_blur_fb); | 
					
						
							|  |  |  |     GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_resolve_fb); | 
					
						
							|  |  |  |     GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_clear_fb); | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |     GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb); | 
					
						
							| 
									
										
										
										
											2020-05-29 12:31:02 +02:00
										 |  |  |     DRW_TEXTURE_FREE_SAFE(txl->sss_accum); | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  |     effects->sss_stencil = NULL; | 
					
						
							|  |  |  |     effects->sss_blur = NULL; | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |     effects->sss_irradiance = NULL; | 
					
						
							|  |  |  |     effects->sss_radius = NULL; | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 14:00:03 +01:00
										 |  |  | void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), | 
					
						
							|  |  |  |                                   EEVEE_Data *vedata, | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |                                   uint UNUSED(tot_samples)) | 
					
						
							| 
									
										
										
										
											2018-01-31 21:17:27 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   EEVEE_FramebufferList *fbl = vedata->fbl; | 
					
						
							|  |  |  |   EEVEE_TextureList *txl = vedata->txl; | 
					
						
							|  |  |  |   EEVEE_StorageList *stl = vedata->stl; | 
					
						
							|  |  |  |   EEVEE_EffectsInfo *effects = stl->effects; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   const eGPUTextureFormat texture_format_light = GPU_RGBA32F; | 
					
						
							|  |  |  |   const bool texture_created = txl->sss_accum == NULL; | 
					
						
							|  |  |  |   DRW_texture_ensure_fullscreen_2d(&txl->sss_accum, texture_format_light, 0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   GPUTexture *stencil_tex = effects->sss_stencil; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   if (GPU_depth_blitting_workaround()) { | 
					
						
							|  |  |  |     DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | 
					
						
							|  |  |  |     /* Blitting stencil buffer does not work on macOS + Radeon Pro.
 | 
					
						
							|  |  |  |      * Blit depth instead and use sss_stencil's depth as depth texture, | 
					
						
							|  |  |  |      * and dtxl->depth as stencil mask. */ | 
					
						
							|  |  |  |     stencil_tex = dtxl->depth; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   GPU_framebuffer_ensure_config( | 
					
						
							|  |  |  |       &fbl->sss_accum_fb, | 
					
						
							|  |  |  |       {GPU_ATTACHMENT_TEXTURE(stencil_tex), GPU_ATTACHMENT_TEXTURE(txl->sss_accum)}); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   /* Clear texture.
 | 
					
						
							|  |  |  |    * Due to the late initialization of the SSS it can happen that the `taa_current_sample` is | 
					
						
							|  |  |  |    * already higher than one. This is noticeable when loading a file that has the diffuse light | 
					
						
							|  |  |  |    * pass in look dev mode active. `texture_created` will make sure that newly created textures | 
					
						
							|  |  |  |    * are cleared. */ | 
					
						
							|  |  |  |   if (DRW_state_is_image_render() || effects->taa_current_sample == 1 || texture_created) { | 
					
						
							|  |  |  |     float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | 
					
						
							|  |  |  |     GPU_framebuffer_bind(fbl->sss_accum_fb); | 
					
						
							|  |  |  |     GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-01-31 21:17:27 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-22 10:52:39 -02:00
										 |  |  | void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   EEVEE_PassList *psl = vedata->psl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  |   /* Shaders */ | 
					
						
							|  |  |  |   if (!e_data.sss_sh[0]) { | 
					
						
							|  |  |  |     eevee_create_shader_subsurface(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-05-16 16:43:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** Screen Space SubSurface Scattering overview
 | 
					
						
							|  |  |  |    * TODO | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2019-05-17 15:02:47 +02:00
										 |  |  |   DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL; | 
					
						
							|  |  |  |   DRW_PASS_CREATE(psl->sss_blur_ps, state); | 
					
						
							| 
									
										
										
										
											2019-05-27 23:21:39 +02:00
										 |  |  |   DRW_PASS_CREATE(psl->sss_resolve_ps, state | DRW_STATE_BLEND_ADD); | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |   DRW_PASS_CREATE(psl->sss_translucency_ps, state | DRW_STATE_BLEND_ADD); | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata, | 
					
						
							|  |  |  |                                EEVEE_Data *vedata, | 
					
						
							|  |  |  |                                uint sss_id, | 
					
						
							|  |  |  |                                struct GPUUniformBuffer *sss_profile) | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | 
					
						
							|  |  |  |   EEVEE_PassList *psl = vedata->psl; | 
					
						
							|  |  |  |   EEVEE_StorageList *stl = vedata->stl; | 
					
						
							|  |  |  |   EEVEE_EffectsInfo *effects = stl->effects; | 
					
						
							|  |  |  |   struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); | 
					
						
							|  |  |  |   GPUTexture **depth_src = GPU_depth_blitting_workaround() ? &effects->sss_stencil : &dtxl->depth; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[0], psl->sss_blur_ps); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src); | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |   DRW_shgroup_uniform_texture_ref(grp, "sssIrradiance", &effects->sss_irradiance); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   DRW_shgroup_uniform_block( | 
					
						
							|  |  |  |       grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   DRW_shgroup_stencil_mask(grp, sss_id); | 
					
						
							| 
									
										
										
										
											2019-05-13 18:28:36 +02:00
										 |  |  |   DRW_shgroup_call(grp, quad, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |   grp = DRW_shgroup_create(e_data.sss_sh[1], psl->sss_resolve_ps); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src); | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |   DRW_shgroup_uniform_texture_ref(grp, "sssIrradiance", &effects->sss_blur); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   DRW_shgroup_uniform_block( | 
					
						
							|  |  |  |       grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   DRW_shgroup_stencil_mask(grp, sss_id); | 
					
						
							| 
									
										
										
										
											2019-05-13 18:28:36 +02:00
										 |  |  |   DRW_shgroup_call(grp, quad, NULL); | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  | void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata, | 
					
						
							|  |  |  |                                             EEVEE_Data *vedata, | 
					
						
							|  |  |  |                                             uint sss_id, | 
					
						
							|  |  |  |                                             struct GPUUniformBuffer *sss_profile, | 
					
						
							|  |  |  |                                             GPUTexture *sss_tex_profile) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | 
					
						
							|  |  |  |   EEVEE_PassList *psl = vedata->psl; | 
					
						
							|  |  |  |   EEVEE_StorageList *stl = vedata->stl; | 
					
						
							|  |  |  |   EEVEE_EffectsInfo *effects = stl->effects; | 
					
						
							|  |  |  |   struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); | 
					
						
							|  |  |  |   GPUTexture **depth_src = GPU_depth_blitting_workaround() ? &effects->sss_stencil : &dtxl->depth; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_translucency_ps); | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |   DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture(grp, "sssTexProfile", sss_tex_profile); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture_ref(grp, "sssShadowCubes", &sldata->shadow_cube_pool); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_texture_ref(grp, "sssShadowCascades", &sldata->shadow_cascade_pool); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); | 
					
						
							|  |  |  |   DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |   DRW_shgroup_uniform_block( | 
					
						
							|  |  |  |       grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata)); | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |   DRW_shgroup_stencil_mask(grp, sss_id); | 
					
						
							|  |  |  |   DRW_shgroup_call(grp, quad, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-22 10:52:39 -02:00
										 |  |  | void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   EEVEE_PassList *psl = vedata->psl; | 
					
						
							|  |  |  |   EEVEE_FramebufferList *fbl = vedata->fbl; | 
					
						
							|  |  |  |   EEVEE_StorageList *stl = vedata->stl; | 
					
						
							|  |  |  |   EEVEE_EffectsInfo *effects = stl->effects; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((effects->enabled_effects & EFFECT_SSS) != 0) { | 
					
						
							|  |  |  |     float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | 
					
						
							|  |  |  |     /* Clear sss_data texture only... can this be done in a more clever way? */ | 
					
						
							|  |  |  |     GPU_framebuffer_bind(fbl->sss_clear_fb); | 
					
						
							|  |  |  |     GPU_framebuffer_clear_color(fbl->sss_clear_fb, clear); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GPU_framebuffer_ensure_config(&fbl->main_fb, | 
					
						
							|  |  |  |                                   {GPU_ATTACHMENT_LEAVE, | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_LEAVE, | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_LEAVE, | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_LEAVE, | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |                                    GPU_ATTACHMENT_TEXTURE(effects->sss_irradiance), | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_TEXTURE(effects->sss_radius), | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                                    GPU_ATTACHMENT_TEXTURE(effects->sss_albedo)}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GPU_framebuffer_bind(fbl->main_fb); | 
					
						
							|  |  |  |     DRW_draw_pass(psl->sss_pass); | 
					
						
							|  |  |  |     DRW_draw_pass(psl->sss_pass_cull); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Restore */ | 
					
						
							|  |  |  |     GPU_framebuffer_ensure_config(&fbl->main_fb, | 
					
						
							|  |  |  |                                   {GPU_ATTACHMENT_LEAVE, | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_LEAVE, | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_LEAVE, | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_LEAVE, | 
					
						
							|  |  |  |                                    GPU_ATTACHMENT_NONE, | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |                                    GPU_ATTACHMENT_NONE, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                                    GPU_ATTACHMENT_NONE}); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  | void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   EEVEE_PassList *psl = vedata->psl; | 
					
						
							|  |  |  |   EEVEE_StorageList *stl = vedata->stl; | 
					
						
							|  |  |  |   EEVEE_TextureList *txl = vedata->txl; | 
					
						
							|  |  |  |   EEVEE_FramebufferList *fbl = vedata->fbl; | 
					
						
							|  |  |  |   EEVEE_EffectsInfo *effects = stl->effects; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((effects->enabled_effects & EFFECT_SSS) != 0) { | 
					
						
							|  |  |  |     float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DRW_stats_group_start("SSS"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (GPU_depth_blitting_workaround()) { | 
					
						
							|  |  |  |       /* Copy depth channel */ | 
					
						
							|  |  |  |       GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_blit_fb, 0, GPU_DEPTH_BIT); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       /* Copy stencil channel, could be avoided (see EEVEE_subsurface_init) */ | 
					
						
							|  |  |  |       GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_blur_fb, 0, GPU_STENCIL_BIT); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |     if (!DRW_pass_is_empty(psl->sss_translucency_ps)) { | 
					
						
							| 
									
										
										
										
											2019-09-19 13:18:52 +10:00
										 |  |  |       /* We sample the shadow-maps using normal sampler. We need to disable Comparison mode.
 | 
					
						
							| 
									
										
										
										
											2019-08-22 16:04:25 +02:00
										 |  |  |        * TODO(fclem) avoid this by using sampler objects.*/ | 
					
						
							|  |  |  |       GPU_texture_compare_mode(sldata->shadow_cube_pool, false); | 
					
						
							|  |  |  |       GPU_texture_compare_mode(sldata->shadow_cascade_pool, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       GPU_framebuffer_bind(fbl->sss_translucency_fb); | 
					
						
							|  |  |  |       DRW_draw_pass(psl->sss_translucency_ps); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* Reset original state. */ | 
					
						
							|  |  |  |       GPU_texture_compare_mode(sldata->shadow_cube_pool, true); | 
					
						
							|  |  |  |       GPU_texture_compare_mode(sldata->shadow_cascade_pool, true); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     /* 1. horizontal pass */ | 
					
						
							|  |  |  |     GPU_framebuffer_bind(fbl->sss_blur_fb); | 
					
						
							|  |  |  |     GPU_framebuffer_clear_color(fbl->sss_blur_fb, clear); | 
					
						
							|  |  |  |     DRW_draw_pass(psl->sss_blur_ps); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* 2. vertical pass + Resolve */ | 
					
						
							|  |  |  |     GPU_framebuffer_texture_attach(fbl->sss_resolve_fb, txl->color, 0, 0); | 
					
						
							|  |  |  |     GPU_framebuffer_bind(fbl->sss_resolve_fb); | 
					
						
							|  |  |  |     DRW_draw_pass(psl->sss_resolve_ps); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GPU_framebuffer_bind(fbl->main_fb); | 
					
						
							|  |  |  |     DRW_stats_group_end(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-31 21:17:27 +01:00
										 |  |  | void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   EEVEE_PassList *psl = vedata->psl; | 
					
						
							|  |  |  |   EEVEE_FramebufferList *fbl = vedata->fbl; | 
					
						
							|  |  |  |   EEVEE_StorageList *stl = vedata->stl; | 
					
						
							|  |  |  |   EEVEE_EffectsInfo *effects = stl->effects; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (((effects->enabled_effects & EFFECT_SSS) != 0) && (fbl->sss_accum_fb != NULL)) { | 
					
						
							|  |  |  |     /* Copy stencil channel, could be avoided (see EEVEE_subsurface_init) */ | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |     GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_accum_fb, 0, GPU_STENCIL_BIT); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Only do vertical pass + Resolve */ | 
					
						
							|  |  |  |     GPU_framebuffer_bind(fbl->sss_accum_fb); | 
					
						
							| 
									
										
										
										
											2020-02-20 14:53:53 +01:00
										 |  |  |     DRW_draw_pass(psl->sss_resolve_ps); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Restore */ | 
					
						
							|  |  |  |     GPU_framebuffer_bind(fbl->main_fb); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-01-31 21:17:27 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | void EEVEE_subsurface_free(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   DRW_SHADER_FREE_SAFE(e_data.sss_sh[0]); | 
					
						
							|  |  |  |   DRW_SHADER_FREE_SAFE(e_data.sss_sh[1]); | 
					
						
							|  |  |  |   DRW_SHADER_FREE_SAFE(e_data.sss_sh[2]); | 
					
						
							| 
									
										
										
										
											2017-11-14 00:49:54 +01:00
										 |  |  | } |