[Bf-blender-cvs] [253b412acef] blender2.8: Eevee: Render: Add Subsurface Pass support.

Clément Foucault noreply at git.blender.org
Thu Feb 1 20:49:01 CET 2018


Commit: 253b412acefc6abe9c221a4886e153739c4f50f4
Author: Clément Foucault
Date:   Wed Jan 31 21:17:27 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB253b412acefc6abe9c221a4886e153739c4f50f4

Eevee: Render: Add Subsurface Pass support.

===================================================================

M	release/scripts/startup/bl_ui/properties_view_layer.py
M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/eevee_render.c
M	source/blender/draw/engines/eevee/eevee_subsurface.c
M	source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
M	source/blender/draw/intern/draw_manager.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py
index 9e25a728386..e4a59f0dba7 100644
--- a/release/scripts/startup/bl_ui/properties_view_layer.py
+++ b/release/scripts/startup/bl_ui/properties_view_layer.py
@@ -469,6 +469,12 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
         col.prop(view_layer, "use_pass_z")
         col.prop(view_layer, "use_pass_normal")
 
+        col = split.column()
+        col.label(text="Subsurface:")
+        row = col.row(align=True)
+        row.prop(view_layer, "use_pass_subsurface_direct", text="Direct", toggle=True)
+        row.prop(view_layer, "use_pass_subsurface_color", text="Color", toggle=True)
+
 
 classes = (
     VIEWLAYER_UL_viewlayers,
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 84627e03137..8c0ba921419 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1056,9 +1056,16 @@ static void material_opaque(
 						DRW_shgroup_uniform_texture(*shgrp, "sssTexProfile", sss_tex_profile);
 					}
 
-					DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1);
-					EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile);
-					e_data.sss_count++;
+					/* Limit of 8 bit stencil buffer. ID 255 is refraction. */
+					if (e_data.sss_count < 254) {
+						DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1);
+						EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile);
+						e_data.sss_count++;
+					}
+					else {
+						/* TODO : display message. */
+						printf("Error: Too many different Subsurface shader in the scene.\n");
+					}
 				}
 			}
 		}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 17d41cabe66..1c35d5e7262 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -178,6 +178,7 @@ typedef struct EEVEE_PassList {
 	struct DRWPass *ssr_resolve;
 	struct DRWPass *sss_blur_ps;
 	struct DRWPass *sss_resolve_ps;
+	struct DRWPass *sss_accum_ps;
 	struct DRWPass *color_downsample_ps;
 	struct DRWPass *color_downsample_cube_ps;
 	struct DRWPass *taa_resolve;
@@ -220,6 +221,7 @@ typedef struct EEVEE_FramebufferList {
 	struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP - 1];
 	struct GPUFrameBuffer *sss_blur_fb;
 	struct GPUFrameBuffer *sss_clear_fb;
+	struct GPUFrameBuffer *sss_accum_fb;
 	struct GPUFrameBuffer *dof_down_fb;
 	struct GPUFrameBuffer *dof_scatter_far_fb;
 	struct GPUFrameBuffer *dof_scatter_near_fb;
@@ -249,6 +251,8 @@ typedef struct EEVEE_TextureList {
 	struct GPUTexture *bloom_blit; /* R16_G16_B16 */
 	struct GPUTexture *bloom_downsample[MAX_BLOOM_STEP]; /* R16_G16_B16 */
 	struct GPUTexture *bloom_upsample[MAX_BLOOM_STEP - 1]; /* R16_G16_B16 */
+	struct GPUTexture *sss_dir_accum;
+	struct GPUTexture *sss_col_accum;
 	struct GPUTexture *ssr_normal_input;
 	struct GPUTexture *ssr_specrough_input;
 	struct GPUTexture *ssr_hit_output;
@@ -820,10 +824,12 @@ void EEVEE_screen_raytrace_free(void);
 /* eevee_subsurface.c */
 int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
 void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
 void EEVEE_subsurface_add_pass(
         EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, unsigned int sss_id, struct GPUUniformBuffer *sss_profile);
 void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
 void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
 void EEVEE_subsurface_free(void);
 
 /* eevee_motion_blur.c */
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index f7ebded2408..e3d6d182053 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -160,6 +160,51 @@ static void eevee_render_result_combined(
 	DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 4, 0, rp->rect);
 }
 
+static void eevee_render_result_subsurface(
+        RenderResult *rr, const char *viewname,
+        EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
+{
+	const DRWContextState *draw_ctx = DRW_context_state_get();
+	ViewLayer *view_layer = draw_ctx->view_layer;
+
+	if ((view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) != 0) {
+		RenderLayer *rl = rr->layers.first;
+		RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_COLOR, viewname);
+
+		IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+		float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
+
+		DRW_framebuffer_bind(vedata->fbl->sss_accum_fb);
+		DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 1, rp->rect);
+
+		/* This is the accumulated color. Divide by the number of samples. */
+		for (int i = 0; i < rr->rectx * rr->recty * 3; i++) {
+			rp->rect[i] /= render_samples;
+		}
+	}
+
+	if ((view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
+		RenderLayer *rl = rr->layers.first;
+		RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_DIRECT, viewname);
+
+		IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+		float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
+
+		DRW_framebuffer_bind(vedata->fbl->sss_accum_fb);
+		DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 0, rp->rect);
+
+		/* This is the accumulated color. Divide by the number of samples. */
+		for (int i = 0; i < rr->rectx * rr->recty * 3; i++) {
+			rp->rect[i] /= render_samples;
+		}
+	}
+
+	if ((view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) != 0) {
+		/* Do nothing as all the lighting is in the direct pass.
+		 * TODO : Separate Direct from indirect lighting. */
+	}
+}
+
 static void eevee_render_result_normal(
         RenderResult *rr, const char *viewname,
         EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
@@ -253,6 +298,13 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct D
 	EEVEE_lights_cache_finish(sldata);
 	EEVEE_lightprobes_cache_finish(sldata, vedata);
 
+	if ((view_layer->passflag & (SCE_PASS_SUBSURFACE_COLOR |
+	                             SCE_PASS_SUBSURFACE_DIRECT |
+	                             SCE_PASS_SUBSURFACE_INDIRECT)) != 0)
+	{
+		EEVEE_subsurface_output_init(sldata, vedata);
+	}
+
 	/* Init render result. */
 	const char *viewname = NULL;
 	const float *render_size = DRW_viewport_size_get();
@@ -304,13 +356,12 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct D
 		/* Effects pre-transparency */
 		EEVEE_subsurface_compute(sldata, vedata);
 		EEVEE_reflection_compute(sldata, vedata);
-		EEVEE_occlusion_draw_debug(sldata, vedata);
-		DRW_draw_pass(psl->probe_display);
 		EEVEE_refraction_compute(sldata, vedata);
 		/* Opaque refraction */
 		DRW_draw_pass(psl->refract_depth_pass);
 		DRW_draw_pass(psl->refract_depth_pass_cull);
 		DRW_draw_pass(psl->refract_pass);
+		EEVEE_subsurface_output_accumulate(sldata, vedata);
 		/* Result NORMAL */
 		eevee_render_result_normal(rr, viewname, vedata, sldata);
 		/* Volumetrics Resolve Opaque */
@@ -324,8 +375,8 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct D
 		EEVEE_draw_effects(sldata, vedata);
 	}
 
-	/* Result Combined */
 	eevee_render_result_combined(rr, viewname, vedata, sldata);
+	eevee_render_result_subsurface(rr, viewname, vedata, sldata);
 
 	RE_engine_end_result(engine, rr, false, false, false);
 }
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index e93e9574acd..4ca1f0f42a1 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -33,7 +33,7 @@
 #include "GPU_texture.h"
 
 static struct {
-	struct GPUShader *sss_sh[3];
+	struct GPUShader *sss_sh[4];
 } e_data = {NULL}; /* Engine data */
 
 extern char datatoc_common_uniforms_lib_glsl[];
@@ -49,6 +49,9 @@ static void eevee_create_shader_subsurface(void)
 	e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n");
 	e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n"
 	                                                          "#define USE_SEP_ALBEDO\n");
+	e_data.sss_sh[3] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n"
+	                                                          "#define USE_SEP_ALBEDO\n"
+	                                                          "#define RESULT_ACCUM\n");
 
 	MEM_freeN(frag_str);
 }
@@ -71,6 +74,11 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
 		effects->sss_separate_albedo = BKE_collection_engine_property_value_get_bool(props, "sss_separate_albedo");
 		common_data->sss_jitter_threshold = BKE_collection_engine_property_value_get_float(props, "sss_jitter_threshold");
 
+		/* Force separate albedo for final render */
+		if (DRW_state_is_image_render()) {
+			effects->sss_separate_albedo = true;
+		}
+
 		/* Shaders */
 		if (!e_data.sss_sh[0]) {
 			eevee_create_shader_subsurface();
@@ -109,6 +117,47 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
 	return 0;
 }
 
+static void set_shgrp_stencil(void *UNUSED(userData), DRWShadingGroup *shgrp)
+{
+	DRW_shgroup_stencil_mask(shgrp, 255);
+}
+
+void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+	EEVEE_FramebufferList *fbl = vedata->fbl;
+	EEVEE_TextureList *txl = vedata->txl;
+	const float *viewport_size = DRW_viewport_size_get();
+
+	const DRWCo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list