Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-11-25 00:29:18 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-11-25 00:29:28 +0300
commit7cbc7dd90499f98e3f44f86fdacae5365e53cd77 (patch)
tree63eecf24db2b50ec51e9241eb20c20ecde7a8a66 /source
parent8d4aa6bf44106bbc1605151c05ae6d5bb5c30e29 (diff)
Eevee: SSS: Add separated Albedo option.
This option prevent from automatically blurring the albedo color applied to the SSS. While this is great for preserving details it can bleed more light onto the nearby objects since the blurring will be done on pure "white" irradiance. This issue is to be tackled in a separate commit.
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c1
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h3
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c43
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl25
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl5
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl16
-rw-r--r--source/blender/makesrna/intern/rna_layer.c9
8 files changed, 95 insertions, 11 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 2378a3c8784..f059fbe2268 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -326,6 +326,7 @@ static void EEVEE_view_layer_settings_create(RenderEngine *UNUSED(engine), IDPro
BKE_collection_engine_property_add_bool(props, "sss_enable", false);
BKE_collection_engine_property_add_int(props, "sss_samples", 7);
BKE_collection_engine_property_add_float(props, "sss_jitter_threshold", 0.3f);
+ BKE_collection_engine_property_add_bool(props, "sss_separate_albedo", false);
BKE_collection_engine_property_add_bool(props, "ssr_enable", false);
BKE_collection_engine_property_add_bool(props, "ssr_refraction", false);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 7069e46edf1..77d57716852 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -307,6 +307,9 @@ static char *eevee_get_defines(int options)
if ((options & VAR_MAT_SSS) != 0) {
BLI_dynstr_appendf(ds, "#define USE_SSS\n");
}
+ if ((options & VAR_MAT_SSSALBED) != 0) {
+ BLI_dynstr_appendf(ds, "#define USE_SSS_ALBEDO\n");
+ }
if ((options & VAR_MAT_TRANSLUC) != 0) {
BLI_dynstr_appendf(ds, "#define USE_TRANSLUCENCY\n");
}
@@ -651,6 +654,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(
if (use_multiply) options |= VAR_MAT_MULT;
if (use_refract) options |= VAR_MAT_REFRACT;
if (use_sss) options |= VAR_MAT_SSS;
+ if (use_sss && vedata->stl->effects->sss_separate_albedo) options |= VAR_MAT_SSSALBED;
if (use_translucency) options |= VAR_MAT_TRANSLUC;
if (vedata->stl->effects->use_volumetrics && use_blend) options |= VAR_MAT_VOLUME;
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index a97f7db5c0d..93fc3ee27d3 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -117,6 +117,7 @@ enum {
VAR_MAT_VOLUME = (1 << 13),
VAR_MAT_SSS = (1 << 14),
VAR_MAT_TRANSLUC = (1 << 15),
+ VAR_MAT_SSSALBED = (1 << 16),
};
/* Shadow Technique */
@@ -252,6 +253,7 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *gtao_horizons;
struct GPUTexture *sss_data;
+ struct GPUTexture *sss_albedo;
struct GPUTexture *sss_blur;
struct GPUTexture *sss_stencil;
@@ -433,6 +435,7 @@ typedef struct EEVEE_EffectsInfo {
/* SSSS */
int sss_sample_count;
float sss_jitter_threshold;
+ bool sss_separate_albedo;
/* Volumetrics */
bool use_volumetrics;
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index d96d7b6a983..4efdfb0fb84 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[2];
+ struct GPUShader *sss_sh[3];
} e_data = {NULL}; /* Engine data */
extern char datatoc_effect_subsurface_frag_glsl[];
@@ -42,6 +42,8 @@ static void eevee_create_shader_subsurface(void)
{
e_data.sss_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_subsurface_frag_glsl, "#define FIRST_PASS\n");
e_data.sss_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_subsurface_frag_glsl, "#define SECOND_PASS\n");
+ e_data.sss_sh[2] = DRW_shader_create_fullscreen(datatoc_effect_subsurface_frag_glsl, "#define SECOND_PASS\n"
+ "#define USE_SEP_ALBEDO\n");
}
int EEVEE_subsurface_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
@@ -59,6 +61,7 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedat
if (BKE_collection_engine_property_value_get_bool(props, "sss_enable")) {
effects->sss_sample_count = 1 + BKE_collection_engine_property_value_get_int(props, "sss_samples") * 2;
effects->sss_jitter_threshold = BKE_collection_engine_property_value_get_float(props, "sss_jitter_threshold");
+ effects->sss_separate_albedo = BKE_collection_engine_property_value_get_bool(props, "sss_separate_albedo");
/* Shaders */
if (!e_data.sss_sh[0]) {
@@ -79,10 +82,16 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedat
DRW_framebuffer_init(&fbl->sss_clear_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1],
&tex_data, 1);
+ if (effects->sss_separate_albedo && (txl->sss_albedo == NULL)) {
+ txl->sss_albedo = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1],
+ DRW_TEX_RGB_11_11_10, 0, NULL);
+ }
+
return EFFECT_SSS;
}
/* Cleanup to release memory */
+ DRW_TEXTURE_FREE_SAFE(txl->sss_albedo);
DRW_TEXTURE_FREE_SAFE(txl->sss_data);
DRW_TEXTURE_FREE_SAFE(txl->sss_blur);
DRW_TEXTURE_FREE_SAFE(txl->sss_stencil);
@@ -127,7 +136,8 @@ void EEVEE_subsurface_add_pass(EEVEE_Data *vedata, unsigned int sss_id, struct G
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call_add(grp, quad, NULL);
- grp = DRW_shgroup_create(e_data.sss_sh[1], psl->sss_resolve_ps);
+ struct GPUShader *sh = (effects->sss_separate_albedo) ? e_data.sss_sh[2] : e_data.sss_sh[1];
+ grp = DRW_shgroup_create(sh, psl->sss_resolve_ps);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
@@ -136,6 +146,10 @@ void EEVEE_subsurface_add_pass(EEVEE_Data *vedata, unsigned int sss_id, struct G
DRW_shgroup_uniform_float(grp, "jitterThreshold", &effects->sss_jitter_threshold, 1);
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call_add(grp, quad, NULL);
+
+ if (effects->sss_separate_albedo) {
+ DRW_shgroup_uniform_buffer(grp, "sssAlbedo", &txl->sss_albedo);
+ }
}
void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
@@ -152,38 +166,50 @@ void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
DRW_framebuffer_bind(fbl->sss_clear_fb);
DRW_framebuffer_clear(true, false, false, clear, 0.0f);
+
+ DRW_framebuffer_texture_detach(txl->sss_data);
if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) {
DRW_framebuffer_texture_detach(txl->ssr_normal_input);
}
if ((effects->enabled_effects & EFFECT_SSR) != 0) {
DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
}
+
+ /* Start at slot 1 because slot 0 is txl->color */
+ int tex_slot = 1;
+ DRW_framebuffer_texture_attach(fbl->main, txl->sss_data, tex_slot++, 0);
+ if (effects->sss_separate_albedo) {
+ DRW_framebuffer_texture_attach(fbl->main, txl->sss_albedo, tex_slot++, 0);
+ }
if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) {
- DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 2, 0);
+ DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, tex_slot++, 0);
}
if ((effects->enabled_effects & EFFECT_SSR) != 0) {
- DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 3, 0);
+ DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, tex_slot++, 0);
}
- DRW_framebuffer_texture_detach(txl->sss_data);
- DRW_framebuffer_texture_attach(fbl->main, txl->sss_data, 1, 0);
DRW_framebuffer_bind(fbl->main);
DRW_draw_pass(psl->sss_pass);
+ /* Restore */
+ DRW_framebuffer_texture_detach(txl->sss_data);
+ if (effects->sss_separate_albedo) {
+ DRW_framebuffer_texture_detach(txl->sss_albedo);
+ }
if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) {
DRW_framebuffer_texture_detach(txl->ssr_normal_input);
}
if ((effects->enabled_effects & EFFECT_SSR) != 0) {
DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
}
- DRW_framebuffer_texture_detach(txl->sss_data);
+
+ DRW_framebuffer_texture_attach(fbl->sss_clear_fb, txl->sss_data, 0, 0);
if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) {
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
}
if ((effects->enabled_effects & EFFECT_SSR) != 0) {
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
}
- DRW_framebuffer_texture_attach(fbl->sss_clear_fb, txl->sss_data, 0, 0);
}
}
@@ -230,4 +256,5 @@ void EEVEE_subsurface_free(void)
{
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]);
}
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index 32d27838da3..54825303b5d 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -583,6 +583,9 @@ struct Closure {
float opacity;
#ifdef USE_SSS
vec4 sss_data;
+#ifdef USE_SSS_ALBEDO
+ vec3 sss_albedo;
+#endif
#endif
vec4 ssr_data;
vec2 ssr_normal;
@@ -594,7 +597,11 @@ struct Closure {
#define REFRACT_CLOSURE_FLAG -3
#ifdef USE_SSS
+#ifdef USE_SSS_ALBEDO
+#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1)
+#else
#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1)
+#endif
#else
#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1)
#endif
@@ -608,6 +615,9 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
#ifdef USE_SSS
cl.sss_data.rgb = mix(cl1.sss_data.rgb, cl2.sss_data.rgb, fac);
cl.sss_data.a = (cl1.sss_data.a > 0.0) ? cl1.sss_data.a : cl2.sss_data.a;
+#ifdef USE_SSS_ALBEDO
+ cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo;
+#endif
#endif
if (cl1.ssr_id == outputSsrId) {
@@ -637,6 +647,9 @@ Closure closure_add(Closure cl1, Closure cl2)
Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2;
#ifdef USE_SSS
cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data;
+#ifdef USE_SSS_ALBEDO
+ cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo;
+#endif
#endif
cl.radiance = cl1.radiance + cl2.radiance;
cl.opacity = cl1.opacity + cl2.opacity;
@@ -646,13 +659,20 @@ Closure closure_add(Closure cl1, Closure cl2)
#if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY)
layout(location = 0) out vec4 fragColor;
#ifdef USE_SSS
+#ifdef USE_SSS_ALBEDO
+layout(location = 1) out vec4 sssData;
+layout(location = 2) out vec4 sssAlbedo;
+layout(location = 3) out vec4 ssrNormals;
+layout(location = 4) out vec4 ssrData;
+#else
layout(location = 1) out vec4 sssData;
layout(location = 2) out vec4 ssrNormals;
layout(location = 3) out vec4 ssrData;
+#endif /* USE_SSS_ALBEDO */
#else
layout(location = 1) out vec4 ssrNormals;
layout(location = 2) out vec4 ssrData;
-#endif
+#endif /* USE_SSS */
Closure nodetree_exec(void); /* Prototype */
@@ -678,6 +698,9 @@ void main()
ssrData = cl.ssr_data;
#ifdef USE_SSS
sssData = cl.sss_data;
+#ifdef USE_SSS_ALBEDO
+ sssAlbedo = cl.sss_albedo.rgbb;
+#endif
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
index ea9711a6cad..88e71a060c5 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
@@ -11,6 +11,7 @@ layout(std140) uniform sssProfile {
uniform float jitterThreshold;
uniform sampler2D depthBuffer;
uniform sampler2D sssData;
+uniform sampler2D sssAlbedo;
uniform sampler2DArray utilTex;
out vec4 FragColor;
@@ -80,6 +81,10 @@ void main(void)
#ifdef FIRST_PASS
FragColor = vec4(accum, sss_data.a);
#else /* SECOND_PASS */
+ #ifdef USE_SEP_ALBEDO
+ FragColor = vec4(accum * texture(sssAlbedo, uvs).rgb, 1.0);
+ #else
FragColor = vec4(accum, 1.0);
+ #endif
#endif
}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index b23c1708ee1..9d22fbba65e 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2909,7 +2909,12 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs
result.ssr_id = int(ssr_id);
#ifdef USE_SSS
result.sss_data.a = sss_scalef;
- result.sss_data.rgb = (out_diff + out_trans) * mix(vec3(0.0), subsurface_color.rgb, subsurface);
+ result.sss_data.rgb = out_diff + out_trans;
+#ifdef USE_SSS_ALBEDO
+ result.sss_albedo.rgb = mix(vec3(0.0), subsurface_color.rgb, subsurface);
+#else
+ result.sss_data.rgb *= mix(vec3(0.0), subsurface_color.rgb, subsurface);
+#endif
result.sss_data.rgb *= (1.0 - transmission);
#endif
@@ -2954,7 +2959,14 @@ void node_subsurface_scattering(
result.ssr_id = -1;
result.sss_data.a = scale;
eevee_closure_subsurface(N, color.rgb, 1.0, scale, out_diff, out_trans);
- result.sss_data.rgb = (out_diff + out_trans) * color.rgb;
+ result.sss_data.rgb = out_diff + out_trans;
+#ifdef USE_SSS_ALBEDO
+ /* Not perfect for texture_blur not exaclty equal to 0.0 or 1.0. */
+ result.sss_albedo.rgb = mix(color.rgb, vec3(1.0), texture_blur);
+ result.sss_data.rgb *= mix(vec3(1.0), color.rgb, texture_blur);
+#else
+ result.sss_data.rgb *= color.rgb;
+#endif
#else
node_bsdf_diffuse(color, 0.0, N, result);
#endif
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index 81e10324241..4583774318b 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -370,6 +370,7 @@ RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_colored_transmittance)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(sss_enable)
RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(sss_samples)
RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(sss_jitter_threshold)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(sss_separate_albedo)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_refraction)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_enable)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_halfres)
@@ -1217,6 +1218,14 @@ static void rna_def_view_layer_engine_settings_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update");
+ prop = RNA_def_property(srna, "sss_separate_albedo", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_sss_separate_albedo_get",
+ "rna_LayerEngineSettings_Eevee_sss_separate_albedo_set");
+ RNA_def_property_ui_text(prop, "Separate Albedo", "Avoid albedo being blured by the subsurface scattering "
+ "but uses more video memory");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update");
+
/* Screen Space Reflection */
prop = RNA_def_property(srna, "ssr_enable", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_enable_get",