diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2014-04-21 22:09:20 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2014-04-21 22:27:19 +0400 |
commit | 3de8f255d756b849f764d0c50dadaaf20c517345 (patch) | |
tree | e4dda82b62186ba619906c5865ff7b901945d1e8 /source/blender/render/intern/raytrace | |
parent | 88a22632a38b5acab001d27c834a2557f8db638b (diff) |
Fix T39735: New auto smooth creates artifacts with flat shaded faces(BI)
This actually had nothing specific to new split normals, it was an internal limitation
of BI raytracer, which would check against neighbor face shadowing only when they shared
a common vertex, now it also performs checks when both faces have a vertex with a common
"ancestor" (org index).
Note this allows to also fix same issue when using SplitEdges modifier (and potentially
others?), but only when AutoSmooth is enabled (due to some compute/mem overhead, we
do not want to enable this code systematically).
Thanks to Brecht for advices and review!
Diffstat (limited to 'source/blender/render/intern/raytrace')
-rw-r--r-- | source/blender/render/intern/raytrace/rayobject.cpp | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index 9e639501fdd..1ef44bbdd17 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -43,6 +43,7 @@ #include "rayobject.h" #include "raycounter.h" #include "render_types.h" +#include "renderdatabase.h" /* RayFace * @@ -326,15 +327,33 @@ MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *i if (dist < 0.1f && is->orig.ob == face->ob) { VlakRen *a = (VlakRen *)is->orig.face; VlakRen *b = (VlakRen *)face->face; + ObjectRen *obr = ((ObjectInstanceRen *)face->ob)->obr; + + VertRen **va, **vb; + int *org_idx_a, *org_idx_b; + int i, j; + bool is_neighbor = false; + + /* "same" vertex means either the actual same VertRen, or the same 'final org index', if available + * (autosmooth only, currently). */ + for (i = 0, va = &a->v1; !is_neighbor && i < 4 && *va; ++i, ++va) { + org_idx_a = RE_vertren_get_origindex(obr, *va, false); + for (j = 0, vb = &b->v1; !is_neighbor && j < 4 && *vb; ++j, ++vb) { + if (*va == *vb) { + is_neighbor = true; + } + else if (org_idx_a) { + org_idx_b = RE_vertren_get_origindex(obr, *vb, 0); + if (org_idx_b && *org_idx_a == *org_idx_b) { + is_neighbor = true; + } + } + } + } - /* so there's a shared edge or vertex, let's intersect ray with - * face itself, if that's true we can safely return 1, otherwise - * we assume the intersection is invalid, 0 */ - if (a->v1 == b->v1 || a->v2 == b->v1 || a->v3 == b->v1 || a->v4 == b->v1 || - a->v1 == b->v2 || a->v2 == b->v2 || a->v3 == b->v2 || a->v4 == b->v2 || - a->v1 == b->v3 || a->v2 == b->v3 || a->v3 == b->v3 || a->v4 == b->v3 || - (b->v4 && (a->v1 == b->v4 || a->v2 == b->v4 || a->v3 == b->v4 || a->v4 == b->v4))) - { + /* So there's a shared edge or vertex, let's intersect ray with self, if that's true + * we can safely return 1, otherwise we assume the intersection is invalid, 0 */ + if (is_neighbor) { /* create RayFace from original face, transformed if necessary */ RayFace origface; ObjectInstanceRen *ob = (ObjectInstanceRen *)is->orig.ob; |