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
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_render_layer.py2
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h4
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c21
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl21
-rw-r--r--source/blender/gpu/GPU_material.h2
-rw-r--r--source/blender/gpu/intern/gpu_material.c51
-rw-r--r--source/blender/makesrna/intern/rna_layer.c18
10 files changed, 74 insertions, 52 deletions
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 65fa38af652..51ebc79294f 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -778,6 +778,8 @@ class RENDER_PT_eevee_subsurface_scattering(RenderButtonsPanel, Panel):
props = scene.layer_properties['BLENDER_EEVEE']
col = layout.column()
+ col.prop(props, "sss_samples")
+ col.prop(props, "sss_jitter_threshold")
class RENDER_PT_eevee_screen_space_reflections(RenderButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py
index c4013480c74..1a2ed307c6d 100644
--- a/release/scripts/startup/bl_ui/properties_render_layer.py
+++ b/release/scripts/startup/bl_ui/properties_render_layer.py
@@ -344,6 +344,8 @@ class RENDERLAYER_PT_eevee_subsurface_scattering(RenderLayerButtonsPanel, Panel)
layer_props = layer.engine_overrides['BLENDER_EEVEE']
col = layout.column()
+ col.template_override_property(layer_props, scene_props, "sss_samples")
+ col.template_override_property(layer_props, scene_props, "sss_jitter_threshold")
class RENDERLAYER_PT_eevee_screen_space_reflections(RenderLayerButtonsPanel, Panel):
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 217dc2f0227..4ca59aaa39e 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -323,6 +323,8 @@ static void EEVEE_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDPr
BKE_collection_engine_property_add_int(props, "taa_samples", 8);
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, "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 f7985fb7ddf..23057bd91c0 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1006,7 +1006,8 @@ static void material_opaque(
add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract, false);
if (use_sss) {
- struct GPUUniformBuffer *sss_profile = GPU_material_sss_profile_get(*gpumat);
+ struct GPUUniformBuffer *sss_profile = GPU_material_sss_profile_get(*gpumat,
+ stl->effects->sss_sample_count);
if (sss_profile) {
DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1);
EEVEE_subsurface_add_pass(vedata, e_data.sss_count + 1, sss_profile);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 43540762a52..b1ed108bad0 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -429,6 +429,10 @@ typedef struct EEVEE_EffectsInfo {
int enabled_effects;
bool swap_double_buffer;
+ /* SSSS */
+ int sss_sample_count;
+ float sss_jitter_threshold;
+
/* Volumetrics */
bool use_volumetrics;
int volume_current_sample;
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index b2f3d1fee48..2784125ca58 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -19,7 +19,7 @@
*
*/
-/* Screen space reflections and refractions techniques.
+/* Screen space subsurface scattering technique.
*/
/** \file eevee_subsurface.c
@@ -33,16 +33,7 @@
#include "eevee_private.h"
#include "GPU_texture.h"
-/* SSR shader variations */
-enum {
- SSR_SAMPLES = (1 << 0) | (1 << 1),
- SSR_RESOLVE = (1 << 2),
- SSR_FULL_TRACE = (1 << 3),
- SSR_MAX_SHADER = (1 << 4),
-};
-
static struct {
- /* Screen Space SubSurfaceScattering */
struct GPUShader *sss_sh[2];
} e_data = {NULL}; /* Engine data */
@@ -56,6 +47,8 @@ static void eevee_create_shader_subsurface(void)
int EEVEE_subsurface_init(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *vedata)
{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
const float *viewport_size = DRW_viewport_size_get();
@@ -65,6 +58,8 @@ int EEVEE_subsurface_init(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *veda
IDProperty *props = BKE_scene_layer_engine_evaluated_get(scene_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
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");
/* Shaders */
if (!e_data.sss_sh[0]) {
@@ -119,6 +114,8 @@ void EEVEE_subsurface_add_pass(EEVEE_Data *vedata, unsigned int sss_id, struct G
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
EEVEE_TextureList *txl = vedata->txl;
EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[0], psl->sss_blur_ps);
@@ -127,6 +124,8 @@ void EEVEE_subsurface_add_pass(EEVEE_Data *vedata, unsigned int sss_id, struct G
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_buffer(grp, "sssData", &txl->sss_data);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
+ DRW_shgroup_uniform_int(grp, "sampleCount", &effects->sss_sample_count, 1);
+ 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);
@@ -136,6 +135,8 @@ void EEVEE_subsurface_add_pass(EEVEE_Data *vedata, unsigned int sss_id, struct G
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_buffer(grp, "sssData", &txl->sss_blur);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
+ DRW_shgroup_uniform_int(grp, "sampleCount", &effects->sss_sample_count, 1);
+ 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);
}
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 5cc47796ec0..9ee713ab483 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
@@ -1,12 +1,14 @@
/* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */
-#define SSS_SAMPLES 25
+#define MAX_SSS_SAMPLES 65
layout(std140) uniform sssProfile {
- vec4 kernel[SSS_SAMPLES];
+ vec4 kernel[MAX_SSS_SAMPLES];
vec4 radii_max_radius;
};
+uniform int sampleCount;
+uniform float jitterThreshold;
uniform sampler2D depthBuffer;
uniform sampler2D sssData;
uniform sampler2DArray utilTex;
@@ -27,16 +29,6 @@ float get_view_z_from_depth(float depth)
}
}
-vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- return (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz) * get_view_z_from_depth(depth);
- }
- else {
- return viewvecs[0].xyz + vec3(uvcoords, depth) * viewvecs[1].xyz;
- }
-}
-
#define LUT_SIZE 64
#define M_PI_2 1.5707963267948966 /* pi/2 */
#define M_2PI 6.2831853071795865 /* 2*pi */
@@ -67,9 +59,8 @@ void main(void)
/* Center sample */
vec3 accum = sss_data.rgb * kernel[0].rgb;
- for (int i = 1; i < SSS_SAMPLES; i++) {
- /* Rotate samples that are near the kernel center. */
- vec2 sample_uv = uvs + kernel[i].a * finalStep * ((abs(kernel[i].a) > 0.3) ? dir : dir_rand);
+ for (int i = 1; i < sampleCount && i < MAX_SSS_SAMPLES; i++) {
+ vec2 sample_uv = uvs + kernel[i].a * finalStep * ((abs(kernel[i].a) > jitterThreshold) ? dir : dir_rand);
vec3 color = texture(sssData, sample_uv).rgb;
float sample_depth = texture(depthBuffer, sample_uv).r;
sample_depth = get_view_z_from_depth(sample_depth);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 039adc68e6d..4b9f3c1d519 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -236,7 +236,7 @@ GPUBuiltin GPU_get_material_builtins(GPUMaterial *material);
GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
void GPU_material_sss_profile_create(GPUMaterial *material, float *radii);
-struct GPUUniformBuffer *GPU_material_sss_profile_get(GPUMaterial *material);
+struct GPUUniformBuffer *GPU_material_sss_profile_get(GPUMaterial *material, int sample_ct);
/* High level functions to create and use GPU materials */
GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 1304cfc28a0..a405991002d 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -144,6 +144,7 @@ struct GPUMaterial {
GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */
GPUUniformBuffer *sss_profile; /* UBO containing SSS profile. */
float *sss_radii; /* UBO containing SSS profile. */
+ int sss_samples;
bool sss_dirty;
};
@@ -485,7 +486,7 @@ void GPU_material_uniform_buffer_tag_dirty(ListBase *gpumaterials)
/* Eevee Subsurface scattering. */
/* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */
-#define SSS_SAMPLES 25
+#define SSS_SAMPLES 65
#define SSS_EXPONENT 2.0f /* Importance sampling exponent */
typedef struct GPUSssKernelData {
@@ -493,10 +494,10 @@ typedef struct GPUSssKernelData {
float radii_n[3], max_radius;
} GPUSssKernelData;
-static void sss_calculate_offsets(GPUSssKernelData *kd)
+static void sss_calculate_offsets(GPUSssKernelData *kd, int count)
{
- float step = 2.0f / (float)(SSS_SAMPLES - 1);
- for (int i = 0; i < SSS_SAMPLES; i++) {
+ float step = 2.0f / (float)(count - 1);
+ for (int i = 0; i < count; i++) {
float o = ((float)i) * step - 1.0f;
float sign = (o < 0.0f) ? -1.0f : 1.0f;
float ofs = sign * fabsf(powf(o, SSS_EXPONENT));
@@ -543,7 +544,7 @@ static float gaussian_integral(float x0, float x1) {
return gaussian_primitive(x0) - gaussian_primitive(x1);
}
-static void compute_sss_kernel(GPUSssKernelData *kd, float *radii)
+static void compute_sss_kernel(GPUSssKernelData *kd, float *radii, int sample_ct)
{
/* Normalize size */
copy_v3_v3(kd->radii_n, radii);
@@ -551,7 +552,7 @@ static void compute_sss_kernel(GPUSssKernelData *kd, float *radii)
mul_v3_fl(kd->radii_n, 1.0f / kd->max_radius);
/* Compute samples locations on the 1d kernel */
- sss_calculate_offsets(kd);
+ sss_calculate_offsets(kd, sample_ct);
#if 0 /* Maybe used for other distributions */
/* Calculate areas (using importance-sampling) */
@@ -563,7 +564,7 @@ static void compute_sss_kernel(GPUSssKernelData *kd, float *radii)
float sum[3] = {0.0f, 0.0f, 0.0f};
/* Compute interpolated weights */
- for (int i = 0; i < SSS_SAMPLES; i++) {
+ for (int i = 0; i < sample_ct; i++) {
float x0, x1;
if (i == 0) {
@@ -573,8 +574,8 @@ static void compute_sss_kernel(GPUSssKernelData *kd, float *radii)
x0 = (kd->kernel[i - 1][3] + kd->kernel[i][3]) / 2.0f;
}
- if (i == SSS_SAMPLES - 1) {
- x1 = kd->kernel[SSS_SAMPLES - 1][3] + abs(kd->kernel[SSS_SAMPLES - 2][3] - kd->kernel[SSS_SAMPLES - 1][3]) / 2.0f;
+ if (i == sample_ct - 1) {
+ x1 = kd->kernel[sample_ct - 1][3] + abs(kd->kernel[sample_ct - 2][3] - kd->kernel[sample_ct - 1][3]) / 2.0f;
}
else {
x1 = (kd->kernel[i][3] + kd->kernel[i + 1][3]) / 2.0f;
@@ -590,7 +591,7 @@ static void compute_sss_kernel(GPUSssKernelData *kd, float *radii)
}
/* Normalize */
- for (int i = 0; i < SSS_SAMPLES; i++) {
+ for (int i = 0; i < sample_ct; i++) {
kd->kernel[i][0] /= sum[0];
kd->kernel[i][1] /= sum[1];
kd->kernel[i][2] /= sum[2];
@@ -598,8 +599,8 @@ static void compute_sss_kernel(GPUSssKernelData *kd, float *radii)
/* Put center sample at the start of the array (to sample first) */
float tmpv[4];
- copy_v4_v4(tmpv, kd->kernel[SSS_SAMPLES / 2]);
- for (int i = SSS_SAMPLES / 2; i > 0; i--) {
+ copy_v4_v4(tmpv, kd->kernel[sample_ct / 2]);
+ for (int i = sample_ct / 2; i > 0; i--) {
copy_v4_v4(kd->kernel[i], kd->kernel[i - 1]);
}
copy_v4_v4(kd->kernel[0], tmpv);
@@ -616,24 +617,24 @@ void GPU_material_sss_profile_create(GPUMaterial *material, float *radii)
}
}
-static void GPU_material_sss_profile_update(GPUMaterial *material)
+#undef SSS_EXPONENT
+#undef SSS_SAMPLES
+
+struct GPUUniformBuffer *GPU_material_sss_profile_get(GPUMaterial *material, int sample_ct)
{
- GPUSssKernelData kd;
+ if (material->sss_radii == NULL)
+ return NULL;
- compute_sss_kernel(&kd, material->sss_radii);
+ if (material->sss_dirty || (material->sss_samples != sample_ct)) {
+ GPUSssKernelData kd;
- /* Update / Create UBO */
- GPU_uniformbuffer_update(material->sss_profile, &kd);
+ compute_sss_kernel(&kd, material->sss_radii, sample_ct);
- material->sss_dirty = false;
-}
-#undef SSS_EXPONENT
-#undef SSS_SAMPLES
+ /* Update / Create UBO */
+ GPU_uniformbuffer_update(material->sss_profile, &kd);
-struct GPUUniformBuffer *GPU_material_sss_profile_get(GPUMaterial *material)
-{
- if (material->sss_dirty) {
- GPU_material_sss_profile_update(material);
+ material->sss_samples = sample_ct;
+ material->sss_dirty = false;
}
return material->sss_profile;
}
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index ec2ff5f1741..b5f031ccaaa 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -368,6 +368,8 @@ RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_shadows)
RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(volumetric_shadow_samples)
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(ssr_refraction)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_enable)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_halfres)
@@ -1204,6 +1206,22 @@ static void rna_def_scene_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_SceneLayerEngineSettings_update");
+ prop = RNA_def_property(srna, "sss_samples", PROP_INT, PROP_NONE);
+ RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_sss_samples_get",
+ "rna_LayerEngineSettings_Eevee_sss_samples_set", NULL);
+ RNA_def_property_ui_text(prop, "Samples", "Number of samples to compute the scattering effect");
+ RNA_def_property_range(prop, 1, 32);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "sss_jitter_threshold", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_sss_jitter_threshold_get",
+ "rna_LayerEngineSettings_Eevee_sss_jitter_threshold_set", NULL);
+ RNA_def_property_ui_text(prop, "Jitter Threshold", "Rotate samples that are below this threshold");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_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",