From 34d553671daeb5f38d8bbc69ebbdee0f93421000 Mon Sep 17 00:00:00 2001 From: Olivier Maury Date: Fri, 7 Jan 2022 17:15:37 +0100 Subject: Fix wrong shadow terminator geometry offset with deformation motion blur Differential Revision: https://developer.blender.org/D13759 --- intern/cycles/kernel/geom/motion_triangle.h | 46 +++++++++++++++++++++++++++++ intern/cycles/kernel/light/sample.h | 9 +++++- 2 files changed, 54 insertions(+), 1 deletion(-) (limited to 'intern') diff --git a/intern/cycles/kernel/geom/motion_triangle.h b/intern/cycles/kernel/geom/motion_triangle.h index 62b7b630c89..bd62325eaf2 100644 --- a/intern/cycles/kernel/geom/motion_triangle.h +++ b/intern/cycles/kernel/geom/motion_triangle.h @@ -116,6 +116,52 @@ ccl_device_inline void motion_triangle_vertices( verts[2] = (1.0f - t) * verts[2] + t * next_verts[2]; } +ccl_device_inline void motion_triangle_vertices_and_normals( + KernelGlobals kg, int object, int prim, float time, float3 verts[3], float3 normals[3]) +{ + /* get motion info */ + int numsteps, numverts; + object_motion_info(kg, object, &numsteps, &numverts, NULL); + + /* Figure out which steps we need to fetch and their interpolation factor. */ + int maxstep = numsteps * 2; + int step = min((int)(time * maxstep), maxstep - 1); + float t = time * maxstep - step; + + /* Find attribute. */ + int offset = intersection_find_attribute(kg, object, ATTR_STD_MOTION_VERTEX_POSITION); + kernel_assert(offset != ATTR_STD_NOT_FOUND); + + /* Fetch vertex coordinates. */ + float3 next_verts[3]; + uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); + + motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts); + motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts); + + /* Interpolate between steps. */ + verts[0] = (1.0f - t) * verts[0] + t * next_verts[0]; + verts[1] = (1.0f - t) * verts[1] + t * next_verts[1]; + verts[2] = (1.0f - t) * verts[2] + t * next_verts[2]; + + /* Compute smooth normal. */ + + /* Find attribute. */ + offset = intersection_find_attribute(kg, object, ATTR_STD_MOTION_VERTEX_NORMAL); + kernel_assert(offset != ATTR_STD_NOT_FOUND); + + /* Fetch vertex coordinates. */ + float3 next_normals[3]; + motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals); + motion_triangle_normals_for_step( + kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals); + + /* Interpolate between steps. */ + normals[0] = (1.0f - t) * normals[0] + t * next_normals[0]; + normals[1] = (1.0f - t) * normals[1] + t * next_normals[1]; + normals[2] = (1.0f - t) * normals[2] + t * next_normals[2]; +} + ccl_device_inline float3 motion_triangle_smooth_normal( KernelGlobals kg, float3 Ng, int object, int prim, float u, float v, float time) { diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h index 5a4b7c0a302..7dbc783b1bb 100644 --- a/intern/cycles/kernel/light/sample.h +++ b/intern/cycles/kernel/light/sample.h @@ -141,7 +141,14 @@ ccl_device_inline float3 shadow_ray_smooth_surface_offset( KernelGlobals kg, ccl_private const ShaderData *ccl_restrict sd, float3 Ng) { float3 V[3], N[3]; - triangle_vertices_and_normals(kg, sd->prim, V, N); + + if (sd->type == PRIMITIVE_MOTION_TRIANGLE) { + motion_triangle_vertices_and_normals(kg, sd->object, sd->prim, sd->time, V, N); + } + else { + kernel_assert(sd->type == PRIMITIVE_TRIANGLE); + triangle_vertices_and_normals(kg, sd->prim, V, N); + } const float u = sd->u, v = sd->v; const float w = 1 - u - v; -- cgit v1.2.3