Eevee: Remove the Subsurface Render checkbox

This is to simplify the usage of SSS.

Now it automatically detect if there is any SSS material in the view and
allocate the needed buffer if any.
This commit is contained in:
Clément Foucault 2019-05-16 16:43:41 +02:00
parent b23af112d2
commit b526221315
12 changed files with 70 additions and 91 deletions

View File

@ -316,11 +316,6 @@ class RENDER_PT_eevee_subsurface_scattering(RenderButtonsPanel, Panel):
def poll(cls, context):
return (context.engine in cls.COMPAT_ENGINES)
def draw_header(self, context):
scene = context.scene
props = scene.eevee
self.layout.prop(props, "use_sss", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
@ -328,8 +323,6 @@ class RENDER_PT_eevee_subsurface_scattering(RenderButtonsPanel, Panel):
scene = context.scene
props = scene.eevee
layout.active = props.use_sss
col = layout.column()
col.prop(props, "sss_samples")
col.prop(props, "sss_jitter_threshold")

View File

@ -1684,7 +1684,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
EEVEE_GET_BOOL(props, motion_blur_enable, SCE_EEVEE_MOTION_BLUR_ENABLED);
EEVEE_GET_BOOL(props, shadow_high_bitdepth, SCE_EEVEE_SHADOW_HIGH_BITDEPTH);
EEVEE_GET_BOOL(props, taa_reprojection, SCE_EEVEE_TAA_REPROJECTION);
EEVEE_GET_BOOL(props, sss_enable, SCE_EEVEE_SSS_ENABLED);
// EEVEE_GET_BOOL(props, sss_enable, SCE_EEVEE_SSS_ENABLED);
EEVEE_GET_BOOL(props, sss_separate_albedo, SCE_EEVEE_SSS_SEPARATE_ALBEDO);
EEVEE_GET_BOOL(props, ssr_enable, SCE_EEVEE_SSR_ENABLED);
EEVEE_GET_BOOL(props, ssr_refraction, SCE_EEVEE_SSR_REFRACTION);

View File

@ -159,10 +159,11 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
effects->enabled_effects |= EEVEE_depth_of_field_init(sldata, vedata, camera);
effects->enabled_effects |= EEVEE_temporal_sampling_init(sldata, vedata);
effects->enabled_effects |= EEVEE_occlusion_init(sldata, vedata);
effects->enabled_effects |= EEVEE_subsurface_init(sldata, vedata);
effects->enabled_effects |= EEVEE_screen_raytrace_init(sldata, vedata);
effects->enabled_effects |= EEVEE_volumes_init(sldata, vedata);
EEVEE_subsurface_init(sldata, vedata);
/* Force normal buffer creation. */
if (DRW_state_is_image_render() && !minimal && (view_layer->passflag & SCE_PASS_NORMAL) != 0) {
effects->enabled_effects |= EFFECT_NORMAL_BUFFER;

View File

@ -154,7 +154,7 @@ static void eevee_cache_finish(void *vedata)
{
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
EEVEE_materials_cache_finish(vedata);
EEVEE_materials_cache_finish(sldata, vedata);
EEVEE_lights_cache_finish(sldata, vedata);
EEVEE_lightprobes_cache_finish(sldata, vedata);
}
@ -249,8 +249,8 @@ static void eevee_draw_background(void *vedata)
GPU_framebuffer_bind(fbl->main_fb);
eGPUFrameBufferBits clear_bits = GPU_DEPTH_BIT;
clear_bits |= (DRW_state_draw_background()) ? 0 : GPU_COLOR_BIT;
clear_bits |= ((stl->effects->enabled_effects & EFFECT_SSS) != 0) ? GPU_STENCIL_BIT : 0;
SET_FLAG_FROM_TEST(clear_bits, !DRW_state_draw_background(), GPU_COLOR_BIT);
SET_FLAG_FROM_TEST(clear_bits, (stl->effects->enabled_effects & EFFECT_SSS), GPU_STENCIL_BIT);
GPU_framebuffer_clear(fbl->main_fb, clear_bits, clear_col, clear_depth, clear_stencil);
/* Depth prepass */

View File

@ -757,7 +757,7 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
}
DRW_render_object_iter(vedata, NULL, lbake->depsgraph, EEVEE_render_cache);
EEVEE_materials_cache_finish(vedata);
EEVEE_materials_cache_finish(sldata, vedata);
EEVEE_lights_cache_finish(sldata, vedata);
EEVEE_lightprobes_cache_finish(sldata, vedata);

View File

@ -315,9 +315,6 @@ static char *eevee_get_defines(int options)
if ((options & VAR_MAT_REFRACT) != 0) {
BLI_dynstr_append(ds, "#define USE_REFRACTION\n");
}
if ((options & VAR_MAT_SSS) != 0) {
BLI_dynstr_append(ds, "#define USE_SSS\n");
}
if ((options & VAR_MAT_SSSALBED) != 0) {
BLI_dynstr_append(ds, "#define USE_SSS_ALBEDO\n");
}
@ -743,7 +740,6 @@ struct GPUMaterial *EEVEE_material_mesh_get(struct Scene *scene,
bool use_blend,
bool use_multiply,
bool use_refract,
bool use_sss,
bool use_translucency,
int shadow_method)
{
@ -754,8 +750,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(struct Scene *scene,
SET_FLAG_FROM_TEST(options, use_blend, VAR_MAT_BLEND);
SET_FLAG_FROM_TEST(options, use_multiply, VAR_MAT_MULT);
SET_FLAG_FROM_TEST(options, use_refract, VAR_MAT_REFRACT);
SET_FLAG_FROM_TEST(options, use_sss, VAR_MAT_SSS);
SET_FLAG_FROM_TEST(options, use_sss && effects->sss_separate_albedo, VAR_MAT_SSSALBED);
SET_FLAG_FROM_TEST(options, effects->sss_separate_albedo, VAR_MAT_SSSALBED);
SET_FLAG_FROM_TEST(options, use_translucency, VAR_MAT_TRANSLUC);
SET_FLAG_FROM_TEST(
options, ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_blend, VAR_MAT_VOLUME);
@ -1204,8 +1199,7 @@ static void material_opaque(Material *ma,
const bool use_gpumat = (ma->use_nodes && ma->nodetree);
const bool use_ssrefract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
((effects->enabled_effects & EFFECT_REFRACT) != 0);
bool use_sss = ((effects->enabled_effects & EFFECT_SSS) != 0);
const bool use_translucency = use_sss && ((ma->blend_flag & MA_BL_TRANSLUCENCY) != 0);
const bool use_translucency = ((ma->blend_flag & MA_BL_TRANSLUCENCY) != 0);
EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma);
@ -1221,7 +1215,6 @@ static void material_opaque(Material *ma,
false,
false,
use_ssrefract,
use_sss,
use_translucency,
linfo->shadow_method) :
NULL;
@ -1237,15 +1230,8 @@ static void material_opaque(Material *ma,
static float half = 0.5f;
/* Shading */
*gpumat = EEVEE_material_mesh_get(scene,
ma,
vedata,
false,
false,
use_ssrefract,
use_sss,
use_translucency,
linfo->shadow_method);
*gpumat = EEVEE_material_mesh_get(
scene, ma, vedata, false, false, use_ssrefract, use_translucency, linfo->shadow_method);
eGPUMaterialStatus status_mat_surface = GPU_material_status(*gpumat);
@ -1323,10 +1309,10 @@ static void material_opaque(Material *ma,
int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_ssrefract) ?
&first_ssr :
&no_ssr;
const bool use_sss = GPU_material_flag_get(*gpumat, GPU_MATFLAG_SSS);
use_diffuse = GPU_material_flag_get(*gpumat, GPU_MATFLAG_DIFFUSE);
use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY);
use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT);
use_sss = use_sss && GPU_material_flag_get(*gpumat, GPU_MATFLAG_SSS);
*shgrp = DRW_shgroup_material_create(
*gpumat,
@ -1464,7 +1450,6 @@ static void material_transparent(Material *ma,
(ma->blend_method == MA_BM_MULTIPLY),
use_ssrefract,
false,
false,
linfo->shadow_method);
switch (GPU_material_status(*gpumat)) {
@ -1854,11 +1839,16 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
}
}
void EEVEE_materials_cache_finish(EEVEE_Data *vedata)
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
BLI_ghash_free(stl->g_data->material_hash, NULL, MEM_freeN);
SET_FLAG_FROM_TEST(stl->effects->enabled_effects, e_data.sss_count > 0, EFFECT_SSS);
/* TODO(fclem) this is not really clean. Init should not be done in cache finish. */
EEVEE_subsurface_draw_init(sldata, vedata);
}
void EEVEE_materials_free(void)

View File

@ -163,7 +163,6 @@ enum {
VAR_MAT_MULT = (1 << 11),
VAR_MAT_SHADOW = (1 << 12),
VAR_MAT_REFRACT = (1 << 13),
VAR_MAT_SSS = (1 << 14),
VAR_MAT_TRANSLUC = (1 << 15),
VAR_MAT_SSSALBED = (1 << 16),
};
@ -878,7 +877,7 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
bool *cast_shadow);
void EEVEE_materials_cache_finish(EEVEE_Data *vedata);
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, struct World *wo);
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, struct World *wo);
struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, struct World *wo);
@ -888,7 +887,6 @@ struct GPUMaterial *EEVEE_material_mesh_get(struct Scene *scene,
bool use_blend,
bool use_multiply,
bool use_refract,
bool use_sss,
bool use_translucency,
int shadow_method);
struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material *ma);
@ -1025,7 +1023,8 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_screen_raytrace_free(void);
/* eevee_subsurface.c */
int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_draw_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,

View File

@ -486,7 +486,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
EEVEE_PrivateData *g_data = stl->g_data;
/* FINISH CACHE */
EEVEE_materials_cache_finish(vedata);
EEVEE_materials_cache_finish(sldata, vedata);
EEVEE_lights_cache_finish(sldata, vedata);
EEVEE_lightprobes_cache_finish(sldata, vedata);

View File

@ -59,30 +59,30 @@ static void eevee_create_shader_subsurface(void)
MEM_freeN(frag_str);
}
int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
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);
effects->sss_sample_count = 1 + scene_eval->eevee.sss_samples * 2;
effects->sss_separate_albedo = (scene_eval->eevee.flag & SCE_EEVEE_SSS_SEPARATE_ALBEDO) != 0;
common_data->sss_jitter_threshold = scene_eval->eevee.sss_jitter_threshold;
}
void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
{
EEVEE_EffectsInfo *effects = vedata->stl->effects;
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]};
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (scene_eval->eevee.flag & SCE_EEVEE_SSS_ENABLED) {
effects->sss_sample_count = 1 + scene_eval->eevee.sss_samples * 2;
effects->sss_separate_albedo = (scene_eval->eevee.flag & SCE_EEVEE_SSS_SEPARATE_ALBEDO) != 0;
common_data->sss_jitter_threshold = scene_eval->eevee.sss_jitter_threshold;
/* Shaders */
if (!e_data.sss_sh[0]) {
eevee_create_shader_subsurface();
}
if (effects->enabled_effects & EFFECT_SSS) {
/* 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.
@ -124,18 +124,16 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
else {
effects->sss_albedo = NULL;
}
return EFFECT_SSS;
}
/* 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);
effects->sss_stencil = NULL;
effects->sss_blur = NULL;
effects->sss_data = NULL;
return 0;
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);
effects->sss_stencil = NULL;
effects->sss_blur = NULL;
effects->sss_data = NULL;
}
}
static void set_shgrp_stencil(void *UNUSED(userData), DRWShadingGroup *shgrp)
@ -150,17 +148,14 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (scene_eval->eevee.flag & SCE_EEVEE_SSS_ENABLED) {
if (effects->enabled_effects & EFFECT_SSS) {
DRW_texture_ensure_fullscreen_2d(&txl->sss_dir_accum, GPU_RGBA16F, 0);
DRW_texture_ensure_fullscreen_2d(&txl->sss_col_accum, GPU_RGBA16F, 0);
GPUTexture *stencil_tex = effects->sss_stencil;
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. */
@ -194,20 +189,21 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
if ((effects->enabled_effects & EFFECT_SSS) != 0) {
/** Screen Space SubSurface Scattering overview
* TODO
*/
psl->sss_blur_ps = DRW_pass_create("Blur Horiz",
DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE | DRW_STATE_STENCIL_EQUAL;
psl->sss_resolve_ps = DRW_pass_create("Blur Vert", state);
psl->sss_accum_ps = DRW_pass_create("Resolve Accum", state);
/* Shaders */
if (!e_data.sss_sh[0]) {
eevee_create_shader_subsurface();
}
/** Screen Space SubSurface Scattering overview
* TODO
*/
psl->sss_blur_ps = DRW_pass_create("Blur Horiz",
DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE | DRW_STATE_STENCIL_EQUAL;
psl->sss_resolve_ps = DRW_pass_create("Blur Vert", state);
psl->sss_accum_ps = DRW_pass_create("Resolve Accum", state);
}
void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,

View File

@ -36,6 +36,7 @@
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
#include "BKE_main.h"
#include "BKE_node.h"
@ -125,7 +126,6 @@ struct GPUMaterial {
enum {
GPU_DOMAIN_SURFACE = (1 << 0),
GPU_DOMAIN_VOLUME = (1 << 1),
GPU_DOMAIN_SSS = (1 << 2),
};
/* Functions */
@ -682,6 +682,10 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
SET_FLAG_FROM_TEST(mat->domain, has_volume_output, GPU_DOMAIN_VOLUME);
if (mat->outlink) {
/* HACK: this is only for eevee. We add the define here after the nodetree evaluation. */
if (GPU_material_flag_get(mat, GPU_MATFLAG_SSS)) {
defines = BLI_string_joinN(defines, "#define USE_SSS\n");
}
/* Prune the unused nodes and extract attributes before compiling so the
* generated VBOs are ready to accept the future shader. */
GPU_nodes_prune(&mat->nodes, mat->outlink);
@ -697,6 +701,10 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
frag_lib,
defines);
if (GPU_material_flag_get(mat, GPU_MATFLAG_SSS)) {
MEM_freeN((char *)defines);
}
if (mat->pass == NULL) {
/* We had a cache hit and the shader has already failed to compile. */
mat->status = GPU_MAT_FAILED;

View File

@ -2381,7 +2381,7 @@ enum {
SCE_EEVEE_MOTION_BLUR_ENABLED = (1 << 9),
SCE_EEVEE_SHADOW_HIGH_BITDEPTH = (1 << 10),
SCE_EEVEE_TAA_REPROJECTION = (1 << 11),
SCE_EEVEE_SSS_ENABLED = (1 << 12),
// SCE_EEVEE_SSS_ENABLED = (1 << 12), /* Unused */
SCE_EEVEE_SSS_SEPARATE_ALBEDO = (1 << 13),
SCE_EEVEE_SSR_ENABLED = (1 << 14),
SCE_EEVEE_SSR_REFRACTION = (1 << 15),

View File

@ -6787,14 +6787,6 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
/* Screen Space Subsurface Scattering */
prop = RNA_def_property(srna, "use_sss", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSS_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(
prop, "Subsurface Scattering", "Enable screen space subsurface scattering");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "sss_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_default(prop, 7);
RNA_def_property_ui_text(prop, "Samples", "Number of samples to compute the scattering effect");