Files
test2/source/blender/draw/engines/eevee/shaders/eevee_velocity_lib.glsl
Clément Foucault fe213f80a4 GPU: Shader: Make info files generated
This is the first step of moving the create infos
back inside shader sources.

All info files are now treated as source files.
However, they are not considered in the include tree
yet. This will come in another following PR.

Each shader source file now generate a `.info` file
containing only the create info declarations.

This renames all info files so that they do not
conflict with their previous versions that were
copied (non-generated).

Pull Request: https://projects.blender.org/blender/blender/pulls/146676
2025-09-25 10:57:02 +02:00

149 lines
4.8 KiB
GLSL

/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "infos/eevee_velocity_infos.hh"
SHADER_LIBRARY_CREATE_INFO(eevee_velocity_camera)
#include "draw_view_lib.glsl"
#include "gpu_shader_math_matrix_transform_lib.glsl"
float4 velocity_pack(float4 data)
{
return data * 0.01f;
}
float4 velocity_unpack(float4 data)
{
return data * 100.0f;
}
#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).
*/
float4 velocity_surface(float3 P_prv, float3 P, float3 P_nxt)
{
/* NOTE: We use CameraData matrices instead of drw_view().persmat to avoid adding the TAA jitter
* to the velocity. */
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;
/* 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. */
float4 motion = float4(prev_uv - curr_uv, curr_uv - next_uv);
/* Convert NDC velocity to UV velocity */
motion *= 0.5f;
return motion;
}
/**
* 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).
*/
float4 velocity_background(float3 vV)
{
float3 V = transform_direction(camera_curr.viewinv, vV);
/* NOTE: We use CameraData matrices instead of drw_view().winmat to avoid adding the TAA jitter
* to the velocity. */
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;
/* NOTE: We output both vectors in the same direction so we can reuse the same vector
* with RGRG swizzle in viewport. */
float4 motion = float4(prev_uv - curr_uv, curr_uv - next_uv);
/* Convert NDC velocity to UV velocity */
motion *= 0.5f;
return motion;
}
float4 velocity_resolve(float4 vector, float2 uv, float depth)
{
if (vector.x == VELOCITY_INVALID) {
bool is_background = (depth == 1.0f);
if (is_background) {
/* NOTE: Use view vector to avoid imprecision if camera is far from origin. */
float3 vV = -drw_view_incident_vector(drw_point_screen_to_view(float3(uv, 1.0f)));
return velocity_background(vV);
}
else {
/* Static geometry. No translation in world space. */
float3 P = drw_point_screen_to_world(float3(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.
*/
float4 velocity_resolve(sampler2D vector_tx, int2 texel, float depth)
{
float2 uv = (float2(texel) + 0.5f) / float2(textureSize(vector_tx, 0).xy);
float4 vector = texelFetch(vector_tx, texel, 0);
return velocity_resolve(vector, uv, depth);
}
#endif
#ifdef MAT_VELOCITY
/**
* Given a triple of position, compute the previous and next motion vectors.
* Returns a tuple of local space motion deltas.
*/
void velocity_local_pos_get(float3 lP, int vert_id, out float3 lP_prev, out float3 lP_next)
{
VelocityIndex vel = velocity_indirection_buf[drw_resource_id()];
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.
* WARNING: The returned motion_next is invalid when rendering the viewport.
*/
void velocity_vertex(
float3 lP_prev, float3 lP, float3 lP_next, out float3 motion_prev, out float3 motion_next)
{
VelocityIndex vel = velocity_indirection_buf[drw_resource_id()];
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);
motion_prev = P_prev - P;
motion_next = P_next - P;
}
#endif