[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