Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-04-20 19:18:33 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-04-20 19:29:33 +0300
commite2613e4051d501c8b553d781cb63d06735968f91 (patch)
treebed7313216d92c4c3093bf2b0ef6d8740705253c /source/blender/draw/engines
parent358dfe6ac9f22eb59302f5a04b14b75beadf064c (diff)
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.
Diffstat (limited to 'source/blender/draw/engines')
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c77
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h7
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl19
4 files changed, 101 insertions, 5 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 719ff879e8e..14924345d3e 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -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);
@@ -209,6 +231,26 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
}
/**
+ * 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.
*/
if ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0) {
@@ -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);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 276f23c7cf7..3dd7d98842b 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -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;
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index f0ba458dcc8..07624100ea7 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -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];
diff --git a/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
new file mode 100644
index 00000000000..9c118277212
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
@@ -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;
+}