2023-08-24 10:54:59 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2022-05-18 22:12:07 +02:00
|
|
|
|
2024-10-04 15:48:22 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
2025-09-25 10:57:02 +02:00
|
|
|
#include "infos/eevee_velocity_infos.hh"
|
2024-12-02 21:26:15 +01:00
|
|
|
|
|
|
|
|
SHADER_LIBRARY_CREATE_INFO(eevee_velocity_camera)
|
|
|
|
|
|
2024-10-04 15:48:22 +02:00
|
|
|
#include "draw_view_lib.glsl"
|
2025-09-15 12:07:26 +02:00
|
|
|
#include "gpu_shader_math_matrix_transform_lib.glsl"
|
2022-05-18 22:12:07 +02:00
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 velocity_pack(float4 data)
|
2022-07-13 17:31:04 +02:00
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
return data * 0.01f;
|
2022-07-13 17:31:04 +02:00
|
|
|
}
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 velocity_unpack(float4 data)
|
2022-07-13 17:31:04 +02:00
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
return data * 100.0f;
|
2022-07-13 17:31:04 +02:00
|
|
|
}
|
|
|
|
|
|
2022-07-27 17:35:10 +02:00
|
|
|
#ifdef VELOCITY_CAMERA
|
|
|
|
|
|
2022-05-18 22:12:07 +02:00
|
|
|
/**
|
|
|
|
|
* Given a triple of position, compute the previous and next motion vectors.
|
2022-07-13 17:31:04 +02:00
|
|
|
* Returns uv space motion vectors in pairs (motion_prev.xy, motion_next.xy).
|
2022-05-18 22:12:07 +02:00
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 velocity_surface(float3 P_prv, float3 P, float3 P_nxt)
|
2022-05-18 22:12:07 +02:00
|
|
|
{
|
2025-03-04 00:45:38 +01:00
|
|
|
/* NOTE: We use CameraData matrices instead of drw_view().persmat to avoid adding the TAA jitter
|
|
|
|
|
* to the velocity. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float2 prev_uv = project_point(camera_prev.persmat, P_prv).xy;
|
|
|
|
|
float2 curr_uv = project_point(camera_curr.persmat, P).xy;
|
|
|
|
|
float2 next_uv = project_point(camera_next.persmat, P_nxt).xy;
|
2022-07-27 17:35:10 +02:00
|
|
|
/* 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
|
2022-10-06 12:12:09 +11:00
|
|
|
* with RGRG swizzle in viewport. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 motion = float4(prev_uv - curr_uv, curr_uv - next_uv);
|
2022-05-18 22:12:07 +02:00
|
|
|
/* Convert NDC velocity to UV velocity */
|
2025-04-11 18:28:45 +02:00
|
|
|
motion *= 0.5f;
|
2022-05-18 22:12:07 +02:00
|
|
|
|
|
|
|
|
return motion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-07-13 17:31:04 +02:00
|
|
|
* 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).
|
2022-05-18 22:12:07 +02:00
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 velocity_background(float3 vV)
|
2022-05-18 22:12:07 +02:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 V = transform_direction(camera_curr.viewinv, vV);
|
2025-03-04 00:45:38 +01:00
|
|
|
/* NOTE: We use CameraData matrices instead of drw_view().winmat to avoid adding the TAA jitter
|
|
|
|
|
* to the velocity. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float2 prev_uv =
|
|
|
|
|
project_point(camera_prev.winmat, transform_direction(camera_prev.viewmat, V)).xy;
|
|
|
|
|
float2 curr_uv =
|
|
|
|
|
project_point(camera_curr.winmat, transform_direction(camera_curr.viewmat, V)).xy;
|
|
|
|
|
float2 next_uv =
|
|
|
|
|
project_point(camera_next.winmat, transform_direction(camera_next.viewmat, V)).xy;
|
2022-07-27 17:35:10 +02:00
|
|
|
/* NOTE: We output both vectors in the same direction so we can reuse the same vector
|
2022-10-06 12:12:09 +11:00
|
|
|
* with RGRG swizzle in viewport. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 motion = float4(prev_uv - curr_uv, curr_uv - next_uv);
|
2022-07-24 09:18:56 +02:00
|
|
|
/* Convert NDC velocity to UV velocity */
|
2025-04-11 18:28:45 +02:00
|
|
|
motion *= 0.5f;
|
2022-07-24 09:18:56 +02:00
|
|
|
|
|
|
|
|
return motion;
|
2022-07-13 17:31:04 +02:00
|
|
|
}
|
2022-05-18 22:12:07 +02:00
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 velocity_resolve(float4 vector, float2 uv, float depth)
|
2022-07-13 17:31:04 +02:00
|
|
|
{
|
|
|
|
|
if (vector.x == VELOCITY_INVALID) {
|
2025-04-11 18:28:45 +02:00
|
|
|
bool is_background = (depth == 1.0f);
|
2022-07-13 17:31:04 +02:00
|
|
|
if (is_background) {
|
2024-09-17 19:33:35 +02:00
|
|
|
/* NOTE: Use view vector to avoid imprecision if camera is far from origin. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 vV = -drw_view_incident_vector(drw_point_screen_to_view(float3(uv, 1.0f)));
|
2022-07-13 17:31:04 +02:00
|
|
|
return velocity_background(vV);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Static geometry. No translation in world space. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 P = drw_point_screen_to_world(float3(uv, depth));
|
2022-07-13 17:31:04 +02:00
|
|
|
return velocity_surface(P, P, P);
|
|
|
|
|
}
|
2022-05-18 22:12:07 +02:00
|
|
|
}
|
2022-07-13 17:31:04 +02:00
|
|
|
return velocity_unpack(vector);
|
2022-05-18 22:12:07 +02:00
|
|
|
}
|
|
|
|
|
|
2022-07-27 17:35:10 +02:00
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 velocity_resolve(sampler2D vector_tx, int2 texel, float depth)
|
2022-07-27 17:35:10 +02:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
float2 uv = (float2(texel) + 0.5f) / float2(textureSize(vector_tx, 0).xy);
|
|
|
|
|
float4 vector = texelFetch(vector_tx, texel, 0);
|
2022-07-27 17:35:10 +02:00
|
|
|
return velocity_resolve(vector, uv, depth);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-18 22:12:07 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef MAT_VELOCITY
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Given a triple of position, compute the previous and next motion vectors.
|
2025-08-27 09:49:43 +02:00
|
|
|
* Returns a tuple of local space motion deltas.
|
2022-05-18 22:12:07 +02:00
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
void velocity_local_pos_get(float3 lP, int vert_id, out float3 lP_prev, out float3 lP_next)
|
2022-05-18 22:12:07 +02:00
|
|
|
{
|
2025-03-04 00:20:52 +01:00
|
|
|
VelocityIndex vel = velocity_indirection_buf[drw_resource_id()];
|
2022-05-18 22:12:07 +02:00
|
|
|
lP_next = lP_prev = lP;
|
|
|
|
|
if (vel.geo.do_deform) {
|
|
|
|
|
if (vel.geo.ofs[STEP_PREVIOUS] != -1) {
|
|
|
|
|
lP_prev = velocity_geo_prev_buf[vel.geo.ofs[STEP_PREVIOUS] + vert_id].xyz;
|
|
|
|
|
}
|
|
|
|
|
if (vel.geo.ofs[STEP_NEXT] != -1) {
|
|
|
|
|
lP_next = velocity_geo_next_buf[vel.geo.ofs[STEP_NEXT] + vert_id].xyz;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Given a triple of position, compute the previous and next motion vectors.
|
|
|
|
|
* Returns a tuple of world space motion deltas.
|
2024-12-09 18:16:34 +01:00
|
|
|
* WARNING: The returned motion_next is invalid when rendering the viewport.
|
2022-05-18 22:12:07 +02:00
|
|
|
*/
|
|
|
|
|
void velocity_vertex(
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 lP_prev, float3 lP, float3 lP_next, out float3 motion_prev, out float3 motion_next)
|
2022-05-18 22:12:07 +02:00
|
|
|
{
|
2025-03-04 00:20:52 +01:00
|
|
|
VelocityIndex vel = velocity_indirection_buf[drw_resource_id()];
|
2025-04-14 13:46:41 +02:00
|
|
|
float4x4 obmat_prev = velocity_obj_prev_buf[vel.obj.ofs[STEP_PREVIOUS]];
|
|
|
|
|
float4x4 obmat_next = velocity_obj_next_buf[vel.obj.ofs[STEP_NEXT]];
|
|
|
|
|
float3 P_prev = transform_point(obmat_prev, lP_prev);
|
|
|
|
|
float3 P_next = transform_point(obmat_next, lP_next);
|
|
|
|
|
float3 P = transform_point(drw_modelmat(), lP);
|
2022-05-18 22:12:07 +02:00
|
|
|
motion_prev = P_prev - P;
|
|
|
|
|
motion_next = P_next - P;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|