Eevee: Add Velocity pass.
This pass create a velocity buffer which is basically a 2D motion vector texture. This is not yet used for rendering but will be usefull for motion blur and temporal reprojection.
This commit is contained in:
parent
358dfe6ac9
commit
e2613e4051
|
@ -174,6 +174,7 @@ data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
|
|||
data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_downsample_cube_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_velocity_resolve_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_minmaxz_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_mist_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC)
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "BKE_global.h" /* for G.debug_value */
|
||||
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "eevee_private.h"
|
||||
#include "GPU_texture.h"
|
||||
#include "GPU_extensions.h"
|
||||
|
@ -46,6 +50,9 @@ static struct {
|
|||
struct GPUShader *downsample_sh;
|
||||
struct GPUShader *downsample_cube_sh;
|
||||
|
||||
/* Velocity Resolve */
|
||||
struct GPUShader *velocity_resolve_sh;
|
||||
|
||||
/* Theses are just references, not actually allocated */
|
||||
struct GPUTexture *depth_src;
|
||||
struct GPUTexture *color_src;
|
||||
|
@ -54,6 +61,10 @@ static struct {
|
|||
float cube_texel_size;
|
||||
} e_data = {NULL}; /* Engine data */
|
||||
|
||||
extern char datatoc_common_uniforms_lib_glsl[];
|
||||
extern char datatoc_common_view_lib_glsl[];
|
||||
extern char datatoc_bsdf_common_lib_glsl[];
|
||||
extern char datatoc_effect_velocity_resolve_frag_glsl[];
|
||||
extern char datatoc_effect_minmaxz_frag_glsl[];
|
||||
extern char datatoc_effect_downsample_frag_glsl[];
|
||||
extern char datatoc_effect_downsample_cube_frag_glsl[];
|
||||
|
@ -62,6 +73,16 @@ extern char datatoc_lightprobe_geom_glsl[];
|
|||
|
||||
static void eevee_create_shader_downsample(void)
|
||||
{
|
||||
char *frag_str = BLI_string_joinN(
|
||||
datatoc_common_uniforms_lib_glsl,
|
||||
datatoc_common_view_lib_glsl,
|
||||
datatoc_bsdf_common_lib_glsl,
|
||||
datatoc_effect_velocity_resolve_frag_glsl);
|
||||
|
||||
e_data.velocity_resolve_sh = DRW_shader_create_fullscreen(frag_str, NULL);
|
||||
|
||||
MEM_freeN(frag_str);
|
||||
|
||||
e_data.downsample_sh = DRW_shader_create_fullscreen(datatoc_effect_downsample_frag_glsl, NULL);
|
||||
e_data.downsample_cube_sh = DRW_shader_create(
|
||||
datatoc_lightprobe_vert_glsl,
|
||||
|
@ -110,6 +131,8 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
|
|||
ViewLayer *view_layer = draw_ctx->view_layer;
|
||||
|
||||
const float *viewport_size = DRW_viewport_size_get();
|
||||
int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
|
||||
|
||||
/* Shaders */
|
||||
if (!e_data.downsample_sh) {
|
||||
eevee_create_shader_downsample();
|
||||
|
@ -122,6 +145,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
|
|||
effects = stl->effects;
|
||||
|
||||
effects->enabled_effects = 0;
|
||||
effects->enabled_effects |= (G.debug_value == 9) ? EFFECT_VELOCITY_BUFFER : 0;
|
||||
effects->enabled_effects |= EEVEE_motion_blur_init(sldata, vedata, camera);
|
||||
effects->enabled_effects |= EEVEE_bloom_init(sldata, vedata);
|
||||
effects->enabled_effects |= EEVEE_depth_of_field_init(sldata, vedata, camera);
|
||||
|
@ -163,9 +187,9 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
|
|||
/**
|
||||
* MinMax Pyramid
|
||||
*/
|
||||
int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
|
||||
size[0] = max_ii(size[0] / 2, 1);
|
||||
size[1] = max_ii(size[1] / 2, 1);
|
||||
int size[2];
|
||||
size[0] = max_ii(size_fs[0] / 2, 1);
|
||||
size[1] = max_ii(size_fs[1] / 2, 1);
|
||||
|
||||
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
|
||||
/* Intel gpu seems to have problem rendering to only depth format */
|
||||
|
@ -197,8 +221,6 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
|
|||
* Normal buffer for deferred passes.
|
||||
*/
|
||||
if ((effects->enabled_effects & EFFECT_NORMAL_BUFFER) != 0) {
|
||||
int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
|
||||
|
||||
effects->ssr_normal_input = DRW_texture_pool_query_2D(size_fs[0], size_fs[1], DRW_TEX_RG_16,
|
||||
&draw_engine_eevee_type);
|
||||
|
||||
|
@ -208,6 +230,26 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
|
|||
effects->ssr_normal_input = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Motion vector buffer for correct TAA / motion blur.
|
||||
*/
|
||||
if ((effects->enabled_effects & EFFECT_VELOCITY_BUFFER) != 0) {
|
||||
/* TODO use RG16_UNORM */
|
||||
effects->velocity_tx = DRW_texture_pool_query_2D(size_fs[0], size_fs[1], DRW_TEX_RG_32,
|
||||
&draw_engine_eevee_type);
|
||||
|
||||
/* TODO output objects velocity during the mainpass. */
|
||||
// GPU_framebuffer_texture_attach(fbl->main_fb, effects->velocity_tx, 1, 0);
|
||||
|
||||
GPU_framebuffer_ensure_config(&fbl->velocity_resolve_fb, {
|
||||
GPU_ATTACHMENT_NONE,
|
||||
GPU_ATTACHMENT_TEXTURE(effects->velocity_tx)
|
||||
});
|
||||
}
|
||||
else {
|
||||
effects->velocity_tx = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup double buffer so we can access last frame as it was before post processes.
|
||||
*/
|
||||
|
@ -235,6 +277,8 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|||
{
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
EEVEE_TextureList *txl = vedata->txl;
|
||||
EEVEE_StorageList *stl = vedata->stl;
|
||||
EEVEE_EffectsInfo *effects = stl->effects;
|
||||
int downsample_write = DRW_STATE_WRITE_DEPTH;
|
||||
|
||||
/* Intel gpu seems to have problem rendering to only depth format.
|
||||
|
@ -291,6 +335,17 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|||
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
|
||||
DRW_shgroup_call_add(grp, quad, NULL);
|
||||
}
|
||||
|
||||
if ((effects->enabled_effects & EFFECT_VELOCITY_BUFFER) != 0) {
|
||||
/* This pass compute camera motions to the non moving objects. */
|
||||
psl->velocity_resolve = DRW_pass_create("Velocity Resolve", DRW_STATE_WRITE_COLOR);
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(e_data.velocity_resolve_sh, psl->velocity_resolve);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
|
||||
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
|
||||
DRW_shgroup_uniform_mat4(grp, "currPersinv", effects->velocity_curr_persinv);
|
||||
DRW_shgroup_uniform_mat4(grp, "pastPersmat", effects->velocity_past_persmat);
|
||||
DRW_shgroup_call_add(grp, quad, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* Not required for now */
|
||||
|
@ -401,11 +456,21 @@ void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, GPUTexture *texture_src, i
|
|||
|
||||
void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
EEVEE_TextureList *txl = vedata->txl;
|
||||
EEVEE_FramebufferList *fbl = vedata->fbl;
|
||||
EEVEE_StorageList *stl = vedata->stl;
|
||||
EEVEE_EffectsInfo *effects = stl->effects;
|
||||
|
||||
/* First resolve the velocity. */
|
||||
if ((effects->enabled_effects & EFFECT_VELOCITY_BUFFER) != 0) {
|
||||
DRW_viewport_matrix_get(effects->velocity_curr_persinv, DRW_MAT_PERSINV);
|
||||
|
||||
GPU_framebuffer_bind(fbl->velocity_resolve_fb);
|
||||
DRW_draw_pass(psl->velocity_resolve);
|
||||
}
|
||||
DRW_viewport_matrix_get(effects->velocity_past_persmat, DRW_MAT_PERS);
|
||||
|
||||
/* only once per frame after the first post process */
|
||||
effects->swap_double_buffer = ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0);
|
||||
|
||||
|
@ -448,6 +513,8 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
|
|||
|
||||
void EEVEE_effects_free(void)
|
||||
{
|
||||
DRW_SHADER_FREE_SAFE(e_data.velocity_resolve_sh);
|
||||
|
||||
DRW_SHADER_FREE_SAFE(e_data.downsample_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.downsample_cube_sh);
|
||||
|
||||
|
|
|
@ -333,6 +333,9 @@ static void eevee_draw_background(void *vedata)
|
|||
case 8:
|
||||
if (effects->sss_data) DRW_transform_to_display(effects->sss_data);
|
||||
break;
|
||||
case 9:
|
||||
if (effects->velocity_tx) DRW_transform_to_display(effects->velocity_tx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -184,6 +184,7 @@ typedef struct EEVEE_PassList {
|
|||
struct DRWPass *sss_accum_ps;
|
||||
struct DRWPass *color_downsample_ps;
|
||||
struct DRWPass *color_downsample_cube_ps;
|
||||
struct DRWPass *velocity_resolve;
|
||||
struct DRWPass *taa_resolve;
|
||||
|
||||
/* HiZ */
|
||||
|
@ -235,6 +236,7 @@ typedef struct EEVEE_FramebufferList {
|
|||
struct GPUFrameBuffer *refract_fb;
|
||||
struct GPUFrameBuffer *mist_accum_fb;
|
||||
struct GPUFrameBuffer *ao_accum_fb;
|
||||
struct GPUFrameBuffer *velocity_resolve_fb;
|
||||
|
||||
struct GPUFrameBuffer *update_noise_fb;
|
||||
|
||||
|
@ -480,6 +482,7 @@ typedef enum EEVEE_EffectsFlag {
|
|||
EFFECT_POST_BUFFER = (1 << 9), /* Not really an effect but a feature */
|
||||
EFFECT_NORMAL_BUFFER = (1 << 10), /* Not really an effect but a feature */
|
||||
EFFECT_SSS = (1 << 11),
|
||||
EFFECT_VELOCITY_BUFFER = (1 << 12), /* Not really an effect but a feature */
|
||||
} EEVEE_EffectsFlag;
|
||||
|
||||
typedef struct EEVEE_EffectsInfo {
|
||||
|
@ -522,6 +525,10 @@ typedef struct EEVEE_EffectsInfo {
|
|||
float current_ndc_to_world[4][4];
|
||||
float past_world_to_ndc[4][4];
|
||||
int motion_blur_samples;
|
||||
/* Velocity Pass */
|
||||
float velocity_curr_persinv[4][4];
|
||||
float velocity_past_persmat[4][4];
|
||||
struct GPUTexture *velocity_tx; /* Texture from pool */
|
||||
/* Depth Of Field */
|
||||
float dof_near_far[2];
|
||||
float dof_params[3];
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
uniform mat4 currPersinv;
|
||||
uniform mat4 pastPersmat;
|
||||
|
||||
out vec2 outData;
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Extract pixel motion vector from camera movement. */
|
||||
ivec2 texel = ivec2(gl_FragCoord.xy);
|
||||
vec2 uv = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0).xy);
|
||||
|
||||
float depth = texelFetch(depthBuffer, texel, 0).r;
|
||||
|
||||
vec3 world_position = project_point(currPersinv, vec3(uv, depth) * 2.0 - 1.0);
|
||||
vec2 uv_history = project_point(pastPersmat, world_position).xy * 0.5 + 0.5;
|
||||
|
||||
outData = uv - uv_history;
|
||||
}
|
Loading…
Reference in New Issue