Fix #131420: EEVEE: Temporal projection+Motion blur artifacts
Regression from #131134. The shader still reads `vel.obj.ofs[STEP_NEXT]` even when in the viewport. - Ensure that `vel.obj.ofs[STEP_NEXT]` points to a valid memory location even if the computed value is still wrong. - Ensure that the viewport always uses a 2 channel vector_tx and all texture reads are always swizzled. This also seems to fix the motion vector pass for the realtime compositor. Pull Request: https://projects.blender.org/blender/blender/pulls/131445
This commit is contained in:
@@ -243,19 +243,8 @@ void MotionBlurModule::render(View &view, GPUTexture **input_tx, GPUTexture **ou
|
||||
|
||||
tile_indirection_buf_.clear_to_zero();
|
||||
|
||||
const bool do_motion_vectors_swizzle = inst_.render_buffers.vector_tx_format() == GPU_RG16F;
|
||||
if (do_motion_vectors_swizzle) {
|
||||
/* Change texture swizzling to avoid complexity in gather pass shader. */
|
||||
GPU_texture_swizzle_set(inst_.render_buffers.vector_tx, "rgrg");
|
||||
}
|
||||
|
||||
inst_.manager->submit(motion_blur_ps_, view);
|
||||
|
||||
if (do_motion_vectors_swizzle) {
|
||||
/* Reset swizzle since this texture might be reused in other places. */
|
||||
GPU_texture_swizzle_set(inst_.render_buffers.vector_tx, "rgba");
|
||||
}
|
||||
|
||||
tiles_tx_.release();
|
||||
|
||||
DRW_stats_group_end();
|
||||
|
||||
@@ -82,6 +82,12 @@ void RenderBuffers::acquire(int2 extent)
|
||||
/* TODO(fclem): Make vector pass allocation optional if no TAA or motion blur is needed. */
|
||||
vector_tx.acquire(extent, vector_tx_format(), usage_attachment_read_write);
|
||||
|
||||
const bool do_motion_vectors_swizzle = vector_tx_format() == GPU_RG16F;
|
||||
if (do_motion_vectors_swizzle) {
|
||||
/* Change texture swizzling to avoid complexity in shaders. */
|
||||
GPU_texture_swizzle_set(vector_tx, "rgrg");
|
||||
}
|
||||
|
||||
int color_len = data.color_len + data.aovs.color_len;
|
||||
int value_len = data.value_len + data.aovs.value_len;
|
||||
|
||||
@@ -117,18 +123,25 @@ void RenderBuffers::release()
|
||||
// depth_tx.release();
|
||||
combined_tx.release();
|
||||
|
||||
const bool do_motion_vectors_swizzle = vector_tx_format() == GPU_RG16F;
|
||||
if (do_motion_vectors_swizzle) {
|
||||
/* Reset swizzle since this texture might be reused in other places. */
|
||||
GPU_texture_swizzle_set(vector_tx, "rgba");
|
||||
}
|
||||
vector_tx.release();
|
||||
|
||||
cryptomatte_tx.release();
|
||||
}
|
||||
|
||||
eGPUTextureFormat RenderBuffers::vector_tx_format()
|
||||
{
|
||||
const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get();
|
||||
bool do_vector_render_pass = (enabled_passes & EEVEE_RENDER_PASS_VECTOR) ||
|
||||
(inst_.motion_blur.postfx_enabled() && !inst_.is_viewport());
|
||||
bool do_full_vector_render_pass = ((enabled_passes & EEVEE_RENDER_PASS_VECTOR) ||
|
||||
inst_.motion_blur.postfx_enabled()) &&
|
||||
!inst_.is_viewport();
|
||||
|
||||
/* Only RG16F when only doing only reprojection or motion blur. */
|
||||
return do_vector_render_pass ? GPU_RGBA16F : GPU_RG16F;
|
||||
/* Only RG16F (motion.prev) for the viewport. */
|
||||
return do_full_vector_render_pass ? GPU_RGBA16F : GPU_RG16F;
|
||||
}
|
||||
|
||||
} // namespace blender::eevee
|
||||
|
||||
@@ -167,10 +167,15 @@ bool VelocityModule::step_object_sync(ObjectKey &object_key,
|
||||
object_steps[STEP_PREVIOUS]->get_or_resize(
|
||||
vel.obj.ofs[STEP_PREVIOUS]) = ob->object_to_world();
|
||||
}
|
||||
/* STEP_NEXT is not used in viewport. */
|
||||
if (vel.obj.ofs[STEP_NEXT] == -1 && !inst_.is_viewport()) {
|
||||
vel.obj.ofs[STEP_NEXT] = object_steps_usage[STEP_NEXT]++;
|
||||
object_steps[STEP_NEXT]->get_or_resize(vel.obj.ofs[STEP_NEXT]) = ob->object_to_world();
|
||||
if (vel.obj.ofs[STEP_NEXT] == -1) {
|
||||
if (inst_.is_viewport()) {
|
||||
/* Just set it to 0. motion.next is not meant to be valid in the viewport. */
|
||||
vel.obj.ofs[STEP_NEXT] = 0;
|
||||
}
|
||||
else {
|
||||
vel.obj.ofs[STEP_NEXT] = object_steps_usage[STEP_NEXT]++;
|
||||
object_steps[STEP_NEXT]->get_or_resize(vel.obj.ofs[STEP_NEXT]) = ob->object_to_world();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ void velocity_local_pos_get(vec3 lP, int vert_id, out vec3 lP_prev, out vec3 lP_
|
||||
/**
|
||||
* 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(
|
||||
vec3 lP_prev, vec3 lP, vec3 lP_next, out vec3 motion_prev, out vec3 motion_next)
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
* \{ */
|
||||
|
||||
/* Pass world space deltas to the fragment shader.
|
||||
* This is to make sure that the resulting motion vectors are valid even with displacement. */
|
||||
* This is to make sure that the resulting motion vectors are valid even with displacement.
|
||||
* WARNING: The next value is invalid when rendering the viewport. */
|
||||
GPU_SHADER_NAMED_INTERFACE_INFO(eevee_velocity_surface_iface, motion)
|
||||
SMOOTH(VEC3, prev)
|
||||
SMOOTH(VEC3, next)
|
||||
|
||||
Reference in New Issue
Block a user