diff options
Diffstat (limited to 'source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl')
-rw-r--r-- | source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl | 107 |
1 files changed, 70 insertions, 37 deletions
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl index 435ae6658c9..8d02609fedc 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl @@ -2,23 +2,38 @@ #pragma BLENDER_REQUIRE(common_view_lib.glsl) #pragma BLENDER_REQUIRE(eevee_camera_lib.glsl) +vec4 velocity_pack(vec4 data) +{ + return data * 0.01; +} + +vec4 velocity_unpack(vec4 data) +{ + return data * 100.0; +} + #ifdef VELOCITY_CAMERA /** * Given a triple of position, compute the previous and next motion vectors. - * Returns uv space motion vectors in pairs (motion_prev.xy, motion_next.xy) + * Returns uv space motion vectors in pairs (motion_prev.xy, motion_next.xy). */ -vec4 velocity_view(vec3 P_prev, vec3 P, vec3 P_next) +vec4 velocity_surface(vec3 P_prv, vec3 P, vec3 P_nxt) { - vec2 prev_uv, curr_uv, next_uv; - - prev_uv = transform_point(ProjectionMatrix, transform_point(camera_prev.viewmat, P_prev)).xy; - curr_uv = transform_point(ViewProjectionMatrix, P).xy; - next_uv = transform_point(ProjectionMatrix, transform_point(camera_next.viewmat, P_next)).xy; - - vec4 motion; - motion.xy = prev_uv - curr_uv; - motion.zw = curr_uv - next_uv; + /* NOTE: We don't use the drw_view.persmat to avoid adding the TAA jitter to the velocity. */ + vec2 prev_uv = project_point(camera_prev.persmat, P_prv).xy; + vec2 curr_uv = project_point(camera_curr.persmat, P).xy; + vec2 next_uv = project_point(camera_next.persmat, P_nxt).xy; + /* Fix issue with perspective division. */ + if (any(isnan(prev_uv))) { + prev_uv = curr_uv; + } + if (any(isnan(next_uv))) { + next_uv = curr_uv; + } + /* NOTE: We output both vectors in the same direction so we can reuse the same vector + * with rgrg swizzle in viewport. */ + vec4 motion = vec4(prev_uv - curr_uv, curr_uv - next_uv); /* Convert NDC velocity to UV velocity */ motion *= 0.5; @@ -26,37 +41,55 @@ vec4 velocity_view(vec3 P_prev, vec3 P, vec3 P_next) } /** - * Given a triple of position, compute the previous and next motion vectors. - * Returns uv space motion vectors in pairs (motion_prev.xy, motion_next.xy) - * \a velocity_camera is the motion in film UV space after camera projection. - * \a velocity_view is the motion in ShadingView UV space. It is different - * from velocity_camera for multi-view rendering. + * Given a view space view vector \a vV, compute the previous and next motion vectors for + * background pixels. + * Returns uv space motion vectors in pairs (motion_prev.xy, motion_next.xy). */ -void velocity_camera(vec3 P_prev, vec3 P, vec3 P_next, out vec4 vel_camera, out vec4 vel_view) +vec4 velocity_background(vec3 vV) { - vec2 prev_uv, curr_uv, next_uv; - prev_uv = camera_uv_from_world(camera_prev, P_prev); - curr_uv = camera_uv_from_world(camera_curr, P); - next_uv = camera_uv_from_world(camera_next, P_next); - - vel_camera.xy = prev_uv - curr_uv; - vel_camera.zw = curr_uv - next_uv; + /* Only transform direction to avoid losing precision. */ + vec3 V = transform_direction(camera_curr.viewinv, vV); + /* NOTE: We don't use the drw_view.winmat to avoid adding the TAA jitter to the velocity. */ + vec2 prev_uv = project_point(camera_prev.winmat, V).xy; + vec2 curr_uv = project_point(camera_curr.winmat, V).xy; + vec2 next_uv = project_point(camera_next.winmat, V).xy; + /* NOTE: We output both vectors in the same direction so we can reuse the same vector + * with rgrg swizzle in viewport. */ + vec4 motion = vec4(prev_uv - curr_uv, curr_uv - next_uv); + /* Convert NDC velocity to UV velocity */ + motion *= 0.5; - if (is_panoramic(camera_curr.type)) { - /* This path is only used if using using panoramic projections. Since the views always have - * the same 45° aperture angle, we can safely reuse the projection matrix. */ - prev_uv = transform_point(ProjectionMatrix, transform_point(camera_prev.viewmat, P_prev)).xy; - curr_uv = transform_point(ViewProjectionMatrix, P).xy; - next_uv = transform_point(ProjectionMatrix, transform_point(camera_next.viewmat, P_next)).xy; + return motion; +} - vel_view.xy = prev_uv - curr_uv; - vel_view.zw = curr_uv - next_uv; - /* Convert NDC velocity to UV velocity */ - vel_view *= 0.5; - } - else { - vel_view = vel_camera; +vec4 velocity_resolve(vec4 vector, vec2 uv, float depth) +{ + if (vector.x == VELOCITY_INVALID) { + bool is_background = (depth == 1.0); + if (is_background) { + /* NOTE: Use viewCameraVec to avoid imprecision if camera is far from origin. */ + vec3 vV = viewCameraVec(get_view_space_from_depth(uv, 1.0)); + return velocity_background(vV); + } + else { + /* Static geometry. No translation in world space. */ + vec3 P = get_world_space_from_depth(uv, depth); + return velocity_surface(P, P, P); + } } + return velocity_unpack(vector); +} + +/** + * Load and resolve correct velocity as some pixels might still not have correct + * motion data for performance reasons. + * Returns motion vector in render UV space. + */ +vec4 velocity_resolve(sampler2D vector_tx, ivec2 texel, float depth) +{ + vec2 uv = (vec2(texel) + 0.5) / vec2(textureSize(vector_tx, 0).xy); + vec4 vector = texelFetch(vector_tx, texel, 0); + return velocity_resolve(vector, uv, depth); } #endif |