WIP: EEVEE-Next: Use luma weighted history blending #120867
|
@ -42,6 +42,21 @@ vec4 colorspace_scene_linear_from_YCoCg(vec4 ycocg_color)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Hyperbolic space
|
||||
*
|
||||
* Allow non linear accumulations that reduces flickering.
|
||||
* Slide 20 of "High Quality Temporal Supersampling" by Brian Karis at SIGGRAPH 2014.
|
||||
* To preserve more details in dark areas, we use a bigger bias (4 instead of 1).
|
||||
* \{ */
|
||||
|
||||
float colorspace_hyperbolic_from_scene_linear(float value)
|
||||
{
|
||||
return 1.0 / (4.0 + value);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
* Clamp components to avoid black square artifacts if a pixel goes NaN or negative.
|
||||
* Threshold is arbitrary.
|
||||
|
|
|
@ -37,9 +37,7 @@ vec4 film_texelfetch_as_YCoCg_opacity(sampler2D tx, ivec2 texel)
|
|||
/* Returns a weight based on Luma to reduce the flickering introduced by high energy pixels. */
|
||||
float film_luma_weight(float luma)
|
||||
{
|
||||
/* Slide 20 of "High Quality Temporal Supersampling" by Brian Karis at SIGGRAPH 2014. */
|
||||
/* To preserve more details in dark areas, we use a bigger bias. */
|
||||
return 1.0 / (4.0 + luma * uniform_buf.film.exposure_scale);
|
||||
return colorspace_hyperbolic_from_scene_linear(luma * uniform_buf.film.exposure_scale);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -56,6 +56,35 @@ vec3 volume_scatter_light_eval(
|
|||
|
||||
#endif
|
||||
|
||||
float luma_weight(vec3 YCoCg_color)
|
||||
{
|
||||
float exposure = uniform_buf.film.exposure_scale;
|
||||
return colorspace_hyperbolic_from_scene_linear(YCoCg_color.x * exposure);
|
||||
}
|
||||
|
||||
void volume_history_blend(vec3 uvw_history, inout vec3 scattering, inout vec3 extinction)
|
||||
{
|
||||
vec3 scattering_history = texture(scattering_history_tx, uvw_history).rgb;
|
||||
vec3 extinction_history = texture(extinction_history_tx, uvw_history).rgb;
|
||||
|
||||
/* Similar to film accumulation when using reprojection, use luma weighted blend in YCoCg space
|
||||
* to reduce flickering. The difference is that we do not clamp to the neighborhood Bounding box
|
||||
* as it would be very costly. */
|
||||
scattering = colorspace_YCoCg_from_scene_linear(scattering);
|
||||
scattering_history = colorspace_YCoCg_from_scene_linear(scattering_history);
|
||||
|
||||
float blend = uniform_buf.volumes.history_opacity;
|
||||
float weight_src = luma_weight(scattering.x) * (blend);
|
||||
float weight_dst = luma_weight(scattering_history.x) * (1.0 - blend);
|
||||
float weight_sum = weight_src + weight_dst;
|
||||
scattering = (scattering * weight_src + scattering_history * weight_dst) * safe_rcp(weight_sum);
|
||||
|
||||
scattering = colorspace_scene_linear_from_YCoCg(scattering);
|
||||
|
||||
/* Extinction doesn't produce flicker. Do simple blend. */
|
||||
extinction = mix(extinction, extinction_history, blend);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec3 froxel = ivec3(gl_GlobalInvocationID);
|
||||
|
@ -106,10 +135,7 @@ void main()
|
|||
/* Temporal reprojection. */
|
||||
vec3 uvw_history = volume_history_uvw_get(froxel);
|
||||
if (uvw_history.x != -1.0) {
|
||||
vec3 scattering_history = texture(scattering_history_tx, uvw_history).rgb;
|
||||
vec3 extinction_history = texture(extinction_history_tx, uvw_history).rgb;
|
||||
scattering = mix(scattering, scattering_history, uniform_buf.volumes.history_opacity);
|
||||
extinction = mix(extinction, extinction_history, uniform_buf.volumes.history_opacity);
|
||||
volume_history_blend(uvw_history, scattering, extinction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue