From fc42a6185ddeb6a24ec92287dfa7b89beb059716 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 12 Nov 2011 14:29:52 +0000 Subject: Cycles: * Fix object scaling update issue with interactive rendering + static BVH. * Fix negative scaling issue with static BVH. * Fix #29217: excessive fireflies in first sample. --- intern/cycles/blender/blender_object.cpp | 12 +++++++----- intern/cycles/kernel/kernel_random.h | 7 ++++++- intern/cycles/render/mesh.cpp | 14 +++++++++++++- intern/cycles/render/mesh.h | 1 + intern/cycles/render/object.cpp | 11 +++++++++-- intern/cycles/util/util_transform.h | 9 +++++++++ 6 files changed, 45 insertions(+), 9 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 0edac820e94..abadee9328e 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -171,8 +171,14 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Object *object; bool object_updated = false; + if(object_map.sync(&object, b_ob, b_parent, key)) + object_updated = true; + + /* mesh sync */ + object->mesh = sync_mesh(b_ob, object_updated); + /* object sync */ - if(object_map.sync(&object, b_ob, b_parent, key)) { + if(object_updated || (object->mesh && object->mesh->need_update)) { object->name = b_ob.name().c_str(); object->tfm = tfm; @@ -181,11 +187,7 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, object->visibility &= object_ray_visibility(b_parent); object->tag_update(scene); - object_updated = true; } - - /* mesh sync */ - object->mesh = sync_mesh(b_ob, object_updated); } /* Object Loop */ diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index df876e6f726..ba97ab3e3b6 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -22,6 +22,11 @@ typedef uint RNG; #ifdef __SOBOL__ +/* skip initial numbers that are not as well distributed, especially the + first sequence is just 0 everywhere, which can be problematic for e.g. + path termination */ +#define SOBOL_SKIP 64 + /* High Dimensional Sobol */ /* van der corput radical inverse */ @@ -103,7 +108,7 @@ __device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dime return r; #else /* compute sobol sequence value using direction vectors */ - uint result = sobol_dimension(kg, sample, dimension); + uint result = sobol_dimension(kg, sample + SOBOL_SKIP, dimension); float r = (float)result * (1.0f/(float)0xFFFFFFFF); /* Cranly-Patterson rotation using rng seed */ diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 2fef54605a1..19992771c1d 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -42,6 +42,7 @@ Mesh::Mesh() { need_update = true; transform_applied = false; + transform_negative_scaled = false; displacement_method = DISPLACE_BUMP; bvh = NULL; @@ -75,6 +76,9 @@ void Mesh::clear() attributes.clear(); used_shaders.clear(); + + transform_applied = false; + transform_negative_scaled = false; } void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_) @@ -116,6 +120,7 @@ void Mesh::add_face_normals() /* compute face normals */ size_t triangles_size = triangles.size(); + bool flip = transform_negative_scaled; if(triangles_size) { float3 *verts_ptr = &verts[0]; @@ -128,6 +133,9 @@ void Mesh::add_face_normals() float3 v2 = verts_ptr[t.v[2]]; fN[i] = normalize(cross(v1 - v0, v2 - v0)); + + if(flip) + fN[i] = -fN[i]; } } } @@ -150,6 +158,7 @@ void Mesh::add_vertex_normals() size_t verts_size = verts.size(); size_t triangles_size = triangles.size(); + bool flip = transform_negative_scaled; if(triangles_size) { Triangle *triangles_ptr = &triangles[0]; @@ -159,8 +168,11 @@ void Mesh::add_vertex_normals() vN[triangles_ptr[i].v[j]] += fN[i]; } - for(size_t i = 0; i < verts_size; i++) + for(size_t i = 0; i < verts_size; i++) { vN[i] = normalize(vN[i]); + if(flip) + vN[i] = -vN[i]; + } } void Mesh::pack_normals(Scene *scene, float4 *normal, float4 *vnormal) diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index 367896697ed..585203484c7 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -70,6 +70,7 @@ public: BoundBox bounds; bool transform_applied; + bool transform_negative_scaled; DisplacementMethod displacement_method; /* Update Flags */ diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index b91531ac462..3a9f0add735 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -60,6 +60,11 @@ void Object::apply_transform() Transform ntfm = transform_transpose(transform_inverse(tfm)); + /* we keep normals pointing in same direction on negative scale, notify + mesh about this in it (re)calculates normals */ + if(transform_negative_scale(tfm)) + mesh->transform_negative_scaled = true; + if(attr_fN) { float3 *fN = attr_fN->data_float3(); @@ -232,8 +237,10 @@ void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress) /* apply transforms for objects with single user meshes */ foreach(Object *object, scene->objects) { if(mesh_users[object->mesh] == 1) { - object->apply_transform(); - object->mesh->transform_applied = true; + if(!object->mesh->transform_applied) { + object->apply_transform(); + object->mesh->transform_applied = true; + } if(progress.get_cancel()) return; } diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index c43736fb2e4..8f4e2b46616 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -234,6 +234,15 @@ __device_inline bool transform_uniform_scale(const Transform& tfm, float& scale) return false; } +__device_inline bool transform_negative_scale(const Transform& tfm) +{ + float3 c0 = transform_get_column(&tfm, 0); + float3 c1 = transform_get_column(&tfm, 1); + float3 c2 = transform_get_column(&tfm, 2); + + return (dot(cross(c0, c1), c2) < 0.0f); +} + #endif CCL_NAMESPACE_END -- cgit v1.2.3