diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-07-31 16:18:22 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-07-31 16:18:38 +0300 |
commit | b71366801e45dafd7fb8c658edeaf88dfb4cb84e (patch) | |
tree | d293feb992da5c1fe6d411d295b82617414af23a /source | |
parent | 1be1600c325eb1a52e405fa06fb23f5dca156b17 (diff) |
Eevee: SSR: Change clamp to a real clamp and add Max Roughness.
Clamp will now works as in Cycles.
Max roughness limit ssr to a certain roughness level: for noise / performance tweaking.
Diffstat (limited to 'source')
6 files changed, 63 insertions, 36 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 6d1dadf06b5..7592e5c08d9 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -583,6 +583,11 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) effects->ssr_thickness = BKE_collection_engine_property_value_get_float(props, "ssr_thickness"); effects->ssr_border_fac = BKE_collection_engine_property_value_get_float(props, "ssr_border_fade"); effects->ssr_firefly_fac = BKE_collection_engine_property_value_get_float(props, "ssr_firefly_fac"); + effects->ssr_max_roughness = BKE_collection_engine_property_value_get_float(props, "ssr_max_roughness"); + + if (effects->ssr_firefly_fac < 1e-8f) { + effects->ssr_firefly_fac = FLT_MAX; + } /* Important, can lead to breakage otherwise. */ CLAMP(effects->ssr_ray_count, 1, 4); @@ -752,6 +757,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) DRW_shgroup_uniform_vec4(grp, "ssrParameters", &effects->ssr_quality, 1); DRW_shgroup_uniform_int(grp, "rayCount", &effects->ssr_ray_count, 1); DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1); + DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1); DRW_shgroup_uniform_buffer(grp, "planarDepth", &vedata->txl->planar_depth); DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); DRW_shgroup_call_add(grp, quad, NULL); @@ -768,6 +774,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1); DRW_shgroup_uniform_int(grp, "probe_count", &sldata->probes->num_render_cube, 1); DRW_shgroup_uniform_float(grp, "borderFadeFactor", &effects->ssr_border_fac, 1); + DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1); DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1); DRW_shgroup_uniform_float(grp, "lodPlanarMax", &sldata->probes->lod_planar_max, 1); DRW_shgroup_uniform_float(grp, "fireflyFactor", &effects->ssr_firefly_fac, 1); @@ -1252,8 +1259,7 @@ void EEVEE_draw_effects(EEVEE_Data *vedata) if (stl->g_data->ssr_hit_output[0]) DRW_transform_to_display(stl->g_data->ssr_hit_output[0]); break; case 3: - if (stl->g_data->ssr_hit_output[1]) DRW_transform_to_display(stl->g_data->ssr_hit_output[1]); - // if (txl->ssr_normal_input) DRW_transform_to_display(txl->ssr_normal_input); + if (txl->ssr_normal_input) DRW_transform_to_display(txl->ssr_normal_input); break; case 4: if (txl->ssr_specrough_input) DRW_transform_to_display(txl->ssr_specrough_input); diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index ea72569b4d0..f2af9c53aa8 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -238,7 +238,8 @@ static void EEVEE_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDPr BKE_collection_engine_property_add_bool(props, "ssr_enable", false); BKE_collection_engine_property_add_bool(props, "ssr_halfres", true); BKE_collection_engine_property_add_int(props, "ssr_ray_count", 1); - BKE_collection_engine_property_add_float(props, "ssr_quality", 0.25); + BKE_collection_engine_property_add_float(props, "ssr_quality", 0.25f); + BKE_collection_engine_property_add_float(props, "ssr_max_roughness", 0.5f); BKE_collection_engine_property_add_float(props, "ssr_thickness", 0.2f); BKE_collection_engine_property_add_float(props, "ssr_border_fade", 0.075f); BKE_collection_engine_property_add_float(props, "ssr_firefly_fac", 0.0f); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 115e2a25ea4..906f6a0f454 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -327,6 +327,7 @@ typedef struct EEVEE_EffectsInfo { int ssr_ray_count; float ssr_firefly_fac; float ssr_border_fac; + float ssr_max_roughness; float ssr_quality; float ssr_thickness; float ssr_pixelsize[2]; diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl index 673440c3d54..8e5ffb37e2e 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl @@ -8,6 +8,7 @@ uniform sampler2DArray utilTex; #endif /* UTIL_TEX */ uniform int rayCount; +uniform float maxRoughness; #define BRDF_BIAS 0.7 @@ -122,10 +123,16 @@ void main() if (dot(speccol_roughness.rgb, vec3(1.0)) == 0.0) discard; + float roughness = speccol_roughness.a; float roughnessSquared = max(1e-3, roughness * roughness); float a2 = roughnessSquared * roughnessSquared; + if (roughness > maxRoughness + 0.2) { + hitData0 = hitData1 = hitData2 = hitData3 = vec4(0.0); + return; + } + vec3 rand = texelFetch(utilTex, ivec3(halfres_texel % LUT_SIZE, 2), 0).rba; vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition); @@ -292,17 +299,17 @@ vec4 get_ssr_sample( mask *= screen_border_mask(uvs); /* Compute cone footprint Using UV distance because we are using screen space filtering. */ - cone_footprint = 1.5 * cone_tan * distance(ref_uvs, source_uvs); + cone_footprint = cone_tan * distance(ref_uvs, source_uvs); } mask = min(mask, screen_border_mask(ref_uvs)); mask *= float(has_hit); /* Estimate a cone footprint to sample a corresponding mipmap level. */ - float mip = BRDF_BIAS * clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, MAX_MIP); + float mip = BRDF_BIAS * clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, MAX_MIP) - 1.0; /* Slide 54 */ float bsdf = bsdf_ggx(N, L, V, roughnessSquared); - float weight = bsdf / max(1e-8, hit_co_pdf.w); + float weight = step(1e-8, hit_co_pdf.w) * bsdf / max(1e-8, hit_co_pdf.w); weight_acc += weight; vec3 sample; @@ -313,12 +320,13 @@ vec4 get_ssr_sample( sample = textureLod(colorBuffer, ref_uvs, mip).rgb; } + /* Clamped brightness. */ + float luma = max(1e-8, brightness(sample)); + sample *= 1.0 - max(0.0, luma - fireflyFactor) / luma; + /* Do not add light if ray has failed. */ sample *= float(has_hit); - /* Firefly removal */ - sample /= 1.0 + fireflyFactor * brightness(sample); - return vec4(sample, mask) * weight; } @@ -397,26 +405,28 @@ void main() invert_neighbor.x = ((fullres_texel.x & 0x1) == 0) ? 1 : -1; invert_neighbor.y = ((fullres_texel.y & 0x1) == 0) ? 1 : -1; - for (int i = 0; i < NUM_NEIGHBORS; i++) { - ivec2 target_texel = halfres_texel + neighbors[i] * invert_neighbor; + if (roughness < maxRoughness + 0.2) { + for (int i = 0; i < NUM_NEIGHBORS; i++) { + ivec2 target_texel = halfres_texel + neighbors[i] * invert_neighbor; - ssr_accum += get_ssr_sample(hitBuffer0, pd, planar_index, worldPosition, N, V, - roughnessSquared, cone_tan, source_uvs, - texture_size, target_texel, weight_acc); - if (rayCount > 1) { - ssr_accum += get_ssr_sample(hitBuffer1, pd, planar_index, worldPosition, N, V, - roughnessSquared, cone_tan, source_uvs, - texture_size, target_texel, weight_acc); - } - if (rayCount > 2) { - ssr_accum += get_ssr_sample(hitBuffer2, pd, planar_index, worldPosition, N, V, - roughnessSquared, cone_tan, source_uvs, - texture_size, target_texel, weight_acc); - } - if (rayCount > 3) { - ssr_accum += get_ssr_sample(hitBuffer3, pd, planar_index, worldPosition, N, V, + ssr_accum += get_ssr_sample(hitBuffer0, pd, planar_index, worldPosition, N, V, roughnessSquared, cone_tan, source_uvs, texture_size, target_texel, weight_acc); + if (rayCount > 1) { + ssr_accum += get_ssr_sample(hitBuffer1, pd, planar_index, worldPosition, N, V, + roughnessSquared, cone_tan, source_uvs, + texture_size, target_texel, weight_acc); + } + if (rayCount > 2) { + ssr_accum += get_ssr_sample(hitBuffer2, pd, planar_index, worldPosition, N, V, + roughnessSquared, cone_tan, source_uvs, + texture_size, target_texel, weight_acc); + } + if (rayCount > 3) { + ssr_accum += get_ssr_sample(hitBuffer3, pd, planar_index, worldPosition, N, V, + roughnessSquared, cone_tan, source_uvs, + texture_size, target_texel, weight_acc); + } } } @@ -424,7 +434,7 @@ void main() if (weight_acc > 0.0) { ssr_accum /= weight_acc; /* fade between 0.5 and 1.0 roughness */ - //ssr_accum.a *= saturate(2.0 - roughness * 2.0); + ssr_accum.a *= smoothstep(maxRoughness + 0.2, maxRoughness, roughness); accumulate_light(ssr_accum.rgb, ssr_accum.a, spec_accum); } diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index c5d44ba684a..21202a10fb0 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -91,7 +91,7 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao, vec4 spec_accum = vec4(0.0); /* SSR lobe is applied later in a defered style */ - if (!ssrToggle || ssr_id != outputSsrId) { + if (!(ssrToggle && ssr_id == outputSsrId)) { /* Planar Reflections */ for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) { PlanarData pd = planars_data[i]; @@ -238,7 +238,7 @@ vec3 eevee_surface_clearcoat_lit( float fade = probe_attenuation_planar(pd, worldPosition, worldNormal, roughness); if (fade > 0.0) { - if (!ssrToggle || ssr_id != outputSsrId) { + if (!(ssrToggle && ssr_id == outputSsrId)) { vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, roughness, fade); accumulate_light(spec, fade, spec_accum); } @@ -259,7 +259,7 @@ vec3 eevee_surface_clearcoat_lit( float fade = probe_attenuation_cube(cd, worldPosition); if (fade > 0.0) { - if (!ssrToggle || ssr_id != outputSsrId) { + if (!(ssrToggle && ssr_id == outputSsrId)) { vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness); accumulate_light(spec, fade, spec_accum); } @@ -271,7 +271,7 @@ vec3 eevee_surface_clearcoat_lit( /* World Specular */ if (spec_accum.a < 0.999) { - if (!ssrToggle || ssr_id != outputSsrId) { + if (!(ssrToggle && ssr_id == outputSsrId)) { vec3 spec = probe_evaluate_world_spec(spec_dir, roughness); accumulate_light(spec, 1.0, spec_accum); } @@ -454,7 +454,7 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao, int ss /* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */ vec4 spec_accum = vec4(0.0); - if (!ssrToggle || ssr_id != outputSsrId) { + if (!(ssrToggle && ssr_id == outputSsrId)) { /* Planar Reflections */ for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) { PlanarData pd = planars_data[i]; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 953bc134360..23907db522e 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2629,6 +2629,7 @@ RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_enable) RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_halfres) RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(ssr_ray_count) RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_quality) +RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_max_roughness) RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_thickness) RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_border_fade) RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_firefly_fac) @@ -6204,7 +6205,15 @@ static void rna_def_scene_layer_engine_settings_eevee(BlenderRNA *brna) prop = RNA_def_property(srna, "ssr_quality", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_quality_get", "rna_LayerEngineSettings_Eevee_ssr_quality_set", NULL); - RNA_def_property_ui_text(prop, "Quality", "Quality of the screen space raytracing"); + RNA_def_property_ui_text(prop, "Trace Quality", "Quality of the screen space raytracing"); + 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"); + + prop = RNA_def_property(srna, "ssr_max_roughness", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_max_roughness_get", + "rna_LayerEngineSettings_Eevee_ssr_max_roughness_set", NULL); + RNA_def_property_ui_text(prop, "Max Roughness", "Do not raytrace reflections for roughness above this value"); 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"); @@ -6234,11 +6243,11 @@ 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, "ssr_firefly_fac", PROP_FLOAT, PROP_FACTOR); + prop = RNA_def_property(srna, "ssr_firefly_fac", PROP_FLOAT, PROP_NONE); RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_firefly_fac_get", "rna_LayerEngineSettings_Eevee_ssr_firefly_fac_set", NULL); - RNA_def_property_ui_text(prop, "Clamp", "Smoothly clamp pixel intensity to remove noise"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Clamp", "Clamp pixel intensity to remove noise (0 to disabled)"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update"); |