From 38af5b0501005d8ee84a59f027417bf6a31fcc5e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 26 Jul 2022 16:07:50 +0200 Subject: Cycles: switch Cycles triangle barycentric convention to match Embree/OptiX Simplifies intersection code a little and slightly improves precision regarding self intersection. The parametric texture coordinate in shader nodes is still the same as before for compatibility. --- intern/cycles/kernel/integrator/init_from_bake.h | 5 +++++ intern/cycles/kernel/integrator/mnee.h | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'intern/cycles/kernel/integrator') diff --git a/intern/cycles/kernel/integrator/init_from_bake.h b/intern/cycles/kernel/integrator/init_from_bake.h index bf3f41b52b9..dd26215bcd2 100644 --- a/intern/cycles/kernel/integrator/init_from_bake.h +++ b/intern/cycles/kernel/integrator/init_from_bake.h @@ -155,6 +155,11 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg, 1.0f - u); } + /* Convert from Blender to Cycles/Embree/OptiX barycentric convention. */ + const float tmp = u; + u = v; + v = 1.0f - tmp - v; + /* Position and normal on triangle. */ const int object = kernel_data.bake.object_index; float3 P, Ng; diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index 7a6f866b1a0..aa72b93c9d2 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -186,7 +186,7 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg, triangle_vertices_and_normals(kg, sd_vtx->prim, verts, normals); /* Compute refined position (same code as in triangle_point_from_uv). */ - sd_vtx->P = isect->u * verts[0] + isect->v * verts[1] + (1.f - isect->u - isect->v) * verts[2]; + sd_vtx->P = (1.f - isect->u - isect->v) * verts[0] + isect->u * verts[1] + isect->v * verts[2]; if (!(sd_vtx->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { const Transform tfm = object_get_transform(kg, sd_vtx); sd_vtx->P = transform_point(&tfm, sd_vtx->P); @@ -213,8 +213,8 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg, } /* Tangent space (position derivatives) WRT barycentric (u, v). */ - float3 dp_du = verts[0] - verts[2]; - float3 dp_dv = verts[1] - verts[2]; + float3 dp_du = verts[1] - verts[0]; + float3 dp_dv = verts[2] - verts[0]; /* Geometric normal. */ vtx->ng = normalize(cross(dp_du, dp_dv)); @@ -223,16 +223,16 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg, /* Shading normals: Interpolate normals between vertices. */ float n_len; - vtx->n = normalize_len(normals[0] * sd_vtx->u + normals[1] * sd_vtx->v + - normals[2] * (1.0f - sd_vtx->u - sd_vtx->v), + vtx->n = normalize_len(normals[0] * (1.0f - sd_vtx->u - sd_vtx->v) + normals[1] * sd_vtx->u + + normals[2] * sd_vtx->v, &n_len); /* Shading normal derivatives WRT barycentric (u, v) * we calculate the derivative of n = |u*n0 + v*n1 + (1-u-v)*n2| using: * d/du [f(u)/|f(u)|] = [d/du f(u)]/|f(u)| - f(u)/|f(u)|^3 . */ const float inv_n_len = 1.f / n_len; - float3 dn_du = inv_n_len * (normals[0] - normals[2]); - float3 dn_dv = inv_n_len * (normals[1] - normals[2]); + float3 dn_du = inv_n_len * (normals[1] - normals[0]); + float3 dn_dv = inv_n_len * (normals[2] - normals[0]); dn_du -= vtx->n * dot(vtx->n, dn_du); dn_dv -= vtx->n * dot(vtx->n, dn_dv); -- cgit v1.2.3