Eevee: Fix Hashed Alpha.

Now hashed alpha materials are stable when moving the camera/not using TAA.
It also converge to a noise free image when using TAA. No more numerical imprecision.

There still can be situations with multiple overlapping transparent surfaces that can lead to residual noise.
This commit is contained in:
Clément Foucault 2018-01-16 19:40:17 +01:00
parent 9fd28c7769
commit 213e34a6c3
2 changed files with 25 additions and 4 deletions

View File

@ -28,6 +28,7 @@
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
#include "BLI_alloca.h"
#include "BLI_rand.h"
#include "BKE_particle.h"
#include "BKE_paint.h"
@ -61,6 +62,7 @@ static struct {
unsigned int sss_count;
float viewvecs[2][4];
float alpha_hash_offset;
} e_data = {NULL}; /* Engine data */
extern char datatoc_lamps_lib_glsl[];
@ -548,6 +550,19 @@ void EEVEE_materials_init(EEVEE_StorageList *stl)
EEVEE_update_util_texture(offsets);
}
/* Alpha hash scale: Non-flickering size if we are not refining the render. */
if (!DRW_state_is_image_render() &&
(((stl->effects->enabled_effects & EFFECT_TAA) == 0) ||
(stl->effects->taa_current_sample == 1)))
{
e_data.alpha_hash_offset = 0.0f;
}
else {
double r;
BLI_halton_1D(5, 0.0, stl->effects->taa_current_sample, &r);
e_data.alpha_hash_offset = (float)r;
}
{
/* Update viewvecs */
const bool is_persp = DRW_viewport_is_persp_get();
@ -1069,6 +1084,10 @@ static void material_opaque(
DRW_shgroup_uniform_float(*shgrp_depth, "alphaThreshold", &ma->alpha_threshold, 1);
DRW_shgroup_uniform_float(*shgrp_depth_clip, "alphaThreshold", &ma->alpha_threshold, 1);
}
else if (ma->blend_method == MA_BM_HASHED) {
DRW_shgroup_uniform_float(*shgrp_depth, "hashAlphaOffset", &e_data.alpha_hash_offset, 1);
DRW_shgroup_uniform_float(*shgrp_depth_clip, "hashAlphaOffset", &e_data.alpha_hash_offset, 1);
}
}
}
}

View File

@ -10,14 +10,15 @@ float hash3d(vec3 a) {
return hash(vec2(hash(a.xy), a.z));
}
//uniform float hashScale;
float hashScale = 0.001;
uniform float hashAlphaOffset;
float hashed_alpha_threshold(vec3 co)
{
const float hash_scale = 1.0; /* Roughly in pixel */
/* Find the discretized derivatives of our coordinates. */
float max_deriv = max(length(dFdx(co)), length(dFdy(co)));
float pix_scale = 1.0 / (hashScale * max_deriv);
float pix_scale = 1.0 / (hash_scale * max_deriv);
/* Find two nearest log-discretized noise scales. */
float pix_scale_log = log2(pix_scale);
@ -53,7 +54,8 @@ float hashed_alpha_threshold(vec3 co)
/* Avoids threshold == 0. */
threshold = clamp(threshold, 1.0e-6, 1.0);
return threshold;
/* Jitter the threshold for TAA accumulation. */
return fract(threshold + hashAlphaOffset);
}
#endif