Cycles: Store undisplaced coordinates for meshes when needed
authorMai Lavelle <mai.lavelle@gmail.com>
Sat, 13 Aug 2016 16:27:17 +0000 (12:27 -0400)
committerMai Lavelle <mai.lavelle@gmail.com>
Fri, 2 Sep 2016 02:45:29 +0000 (22:45 -0400)
Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2156

intern/cycles/render/mesh.cpp
intern/cycles/render/mesh.h
intern/cycles/render/shader.cpp

index f99454ee1bbe13892b84e821d855960058adc2bc..5445fd3c29cc212c331782bd47fc0d4e3a56c022 100644 (file)
@@ -584,6 +584,28 @@ void Mesh::add_vertex_normals()
        }
 }
 
+void Mesh::add_undisplaced()
+{
+       AttributeSet& attrs = (subdivision_type == SUBDIVISION_NONE) ? attributes : subd_attributes;
+
+       /* don't compute if already there */
+       if(attrs.find(ATTR_STD_POSITION_UNDISPLACED)) {
+               return;
+       }
+
+       /* get attribute */
+       Attribute *attr = attrs.add(ATTR_STD_POSITION_UNDISPLACED);
+       attr->flags |= ATTR_SUBDIVIDED;
+
+       float3 *data = attr->data_float3();
+
+       /* copy verts */
+       size_t size = attr->buffer_size(this, (subdivision_type == SUBDIVISION_NONE) ? ATTR_PRIM_TRIANGLE : ATTR_PRIM_SUBD);
+       if(size) {
+               memcpy(data, verts.data(), size);
+       }
+}
+
 void Mesh::pack_normals(Scene *scene, uint *tri_shader, float4 *vnormal)
 {
        Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
@@ -1682,6 +1704,10 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
                        mesh->add_face_normals();
                        mesh->add_vertex_normals();
 
+                       if(mesh->need_attribute(scene, ATTR_STD_POSITION_UNDISPLACED)) {
+                               mesh->add_undisplaced();
+                       }
+
                        if(progress.get_cancel()) return;
                }
        }
index a77e296ea4a56e9413f8d656c25ce57efb76acf3..c0310f4584077e93d4ae3657ef4c05430e15710c 100644 (file)
@@ -215,6 +215,7 @@ public:
        void compute_bounds();
        void add_face_normals();
        void add_vertex_normals();
+       void add_undisplaced();
 
        void pack_normals(Scene *scene, uint *shader, float4 *vnormal);
        void pack_verts(const vector<uint>& tri_prim_index,
index 4a3233ac764b7290c8c365275fa7c1ca357de11c..1876791c6e851a6d7725a942ce38f299737c36aa 100644 (file)
@@ -240,6 +240,10 @@ void Shader::tag_update(Scene *scene)
        attributes.clear();
        foreach(ShaderNode *node, graph->nodes)
                node->attributes(this, &attributes);
+
+       if(has_displacement && displacement_method == DISPLACE_BOTH) {
+               attributes.add(ATTR_STD_POSITION_UNDISPLACED);
+       }
        
        /* compare if the attributes changed, mesh manager will check
         * need_update_attributes, update the relevant meshes and clear it. */