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.
This commit is contained in:
@@ -733,6 +733,7 @@ class RENDER_PT_eevee_screen_space_reflections(RenderButtonsPanel, Panel):
|
||||
col.prop(props, "ssr_halfres")
|
||||
col.prop(props, "ssr_ray_count")
|
||||
col.prop(props, "ssr_quality")
|
||||
col.prop(props, "ssr_max_roughness")
|
||||
col.prop(props, "ssr_thickness")
|
||||
col.prop(props, "ssr_border_fade")
|
||||
col.prop(props, "ssr_firefly_fac")
|
||||
|
||||
@@ -278,6 +278,7 @@ class RENDERLAYER_PT_eevee_screen_space_reflections(RenderLayerButtonsPanel, Pan
|
||||
col.template_override_property(layer_props, scene_props, "ssr_halfres")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_ray_count")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_quality")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_max_roughness")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_thickness")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_border_fade")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_firefly_fac")
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user