1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "device/device.h"
18 
19 #include "render/mesh.h"
20 #include "render/object.h"
21 #include "render/scene.h"
22 #include "render/shader.h"
23 
24 #include "util/util_foreach.h"
25 #include "util/util_map.h"
26 #include "util/util_progress.h"
27 #include "util/util_set.h"
28 
29 CCL_NAMESPACE_BEGIN
30 
compute_face_normal(const Mesh::Triangle & t,float3 * verts)31 static float3 compute_face_normal(const Mesh::Triangle &t, float3 *verts)
32 {
33   float3 v0 = verts[t.v[0]];
34   float3 v1 = verts[t.v[1]];
35   float3 v2 = verts[t.v[2]];
36 
37   float3 norm = cross(v1 - v0, v2 - v0);
38   float normlen = len(norm);
39 
40   if (normlen == 0.0f)
41     return make_float3(1.0f, 0.0f, 0.0f);
42 
43   return norm / normlen;
44 }
45 
displace(Device * device,DeviceScene * dscene,Scene * scene,Mesh * mesh,Progress & progress)46 bool GeometryManager::displace(
47     Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress &progress)
48 {
49   /* verify if we have a displacement shader */
50   if (!mesh->has_true_displacement()) {
51     return false;
52   }
53 
54   string msg = string_printf("Computing Displacement %s", mesh->name.c_str());
55   progress.set_status("Updating Mesh", msg);
56 
57   /* find object index. todo: is arbitrary */
58   size_t object_index = OBJECT_NONE;
59 
60   for (size_t i = 0; i < scene->objects.size(); i++) {
61     if (scene->objects[i]->geometry == mesh) {
62       object_index = i;
63       break;
64     }
65   }
66 
67   /* setup input for device task */
68   const size_t num_verts = mesh->verts.size();
69   vector<bool> done(num_verts, false);
70   device_vector<uint4> d_input(device, "displace_input", MEM_READ_ONLY);
71   uint4 *d_input_data = d_input.alloc(num_verts);
72   size_t d_input_size = 0;
73 
74   size_t num_triangles = mesh->num_triangles();
75   for (size_t i = 0; i < num_triangles; i++) {
76     Mesh::Triangle t = mesh->get_triangle(i);
77     int shader_index = mesh->shader[i];
78     Shader *shader = (shader_index < mesh->used_shaders.size()) ?
79                          mesh->used_shaders[shader_index] :
80                          scene->default_surface;
81 
82     if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
83       continue;
84     }
85 
86     for (int j = 0; j < 3; j++) {
87       if (done[t.v[j]])
88         continue;
89 
90       done[t.v[j]] = true;
91 
92       /* set up object, primitive and barycentric coordinates */
93       int object = object_index;
94       int prim = mesh->prim_offset + i;
95       float u, v;
96 
97       switch (j) {
98         case 0:
99           u = 1.0f;
100           v = 0.0f;
101           break;
102         case 1:
103           u = 0.0f;
104           v = 1.0f;
105           break;
106         default:
107           u = 0.0f;
108           v = 0.0f;
109           break;
110       }
111 
112       /* back */
113       uint4 in = make_uint4(object, prim, __float_as_int(u), __float_as_int(v));
114       d_input_data[d_input_size++] = in;
115     }
116   }
117 
118   if (d_input_size == 0)
119     return false;
120 
121   /* run device task */
122   device_vector<float4> d_output(device, "displace_output", MEM_READ_WRITE);
123   d_output.alloc(d_input_size);
124   d_output.zero_to_device();
125   d_input.copy_to_device();
126 
127   /* needs to be up to data for attribute access */
128   device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
129 
130   DeviceTask task(DeviceTask::SHADER);
131   task.shader_input = d_input.device_pointer;
132   task.shader_output = d_output.device_pointer;
133   task.shader_eval_type = SHADER_EVAL_DISPLACE;
134   task.shader_x = 0;
135   task.shader_w = d_output.size();
136   task.num_samples = 1;
137   task.get_cancel = function_bind(&Progress::get_cancel, &progress);
138 
139   device->task_add(task);
140   device->task_wait();
141 
142   if (progress.get_cancel()) {
143     d_input.free();
144     d_output.free();
145     return false;
146   }
147 
148   d_output.copy_from_device(0, 1, d_output.size());
149   d_input.free();
150 
151   /* read result */
152   done.clear();
153   done.resize(num_verts, false);
154   int k = 0;
155 
156   float4 *offset = d_output.data();
157 
158   Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
159   for (size_t i = 0; i < num_triangles; i++) {
160     Mesh::Triangle t = mesh->get_triangle(i);
161     int shader_index = mesh->shader[i];
162     Shader *shader = (shader_index < mesh->used_shaders.size()) ?
163                          mesh->used_shaders[shader_index] :
164                          scene->default_surface;
165 
166     if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
167       continue;
168     }
169 
170     for (int j = 0; j < 3; j++) {
171       if (!done[t.v[j]]) {
172         done[t.v[j]] = true;
173         float3 off = float4_to_float3(offset[k++]);
174         /* Avoid illegal vertex coordinates. */
175         off = ensure_finite3(off);
176         mesh->verts[t.v[j]] += off;
177         if (attr_mP != NULL) {
178           for (int step = 0; step < mesh->motion_steps - 1; step++) {
179             float3 *mP = attr_mP->data_float3() + step * num_verts;
180             mP[t.v[j]] += off;
181           }
182         }
183       }
184     }
185   }
186 
187   d_output.free();
188 
189   /* stitch */
190   unordered_set<int> stitch_keys;
191   for (pair<int, int> i : mesh->vert_to_stitching_key_map) {
192     stitch_keys.insert(i.second); /* stitching index */
193   }
194 
195   typedef unordered_multimap<int, int>::iterator map_it_t;
196 
197   for (int key : stitch_keys) {
198     pair<map_it_t, map_it_t> verts = mesh->vert_stitching_map.equal_range(key);
199 
200     float3 pos = make_float3(0.0f, 0.0f, 0.0f);
201     int num = 0;
202 
203     for (map_it_t v = verts.first; v != verts.second; ++v) {
204       int vert = v->second;
205 
206       pos += mesh->verts[vert];
207       num++;
208     }
209 
210     if (num <= 1) {
211       continue;
212     }
213 
214     pos *= 1.0f / num;
215 
216     for (map_it_t v = verts.first; v != verts.second; ++v) {
217       mesh->verts[v->second] = pos;
218     }
219   }
220 
221   /* for displacement method both, we only need to recompute the face
222    * normals, as bump mapping in the shader will already alter the
223    * vertex normal, so we start from the non-displaced vertex normals
224    * to avoid applying the perturbation twice. */
225   mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
226   mesh->add_face_normals();
227 
228   bool need_recompute_vertex_normals = false;
229 
230   foreach (Shader *shader, mesh->used_shaders) {
231     if (shader->has_displacement && shader->displacement_method == DISPLACE_TRUE) {
232       need_recompute_vertex_normals = true;
233       break;
234     }
235   }
236 
237   if (need_recompute_vertex_normals) {
238     bool flip = mesh->transform_negative_scaled;
239     vector<bool> tri_has_true_disp(num_triangles, false);
240 
241     for (size_t i = 0; i < num_triangles; i++) {
242       int shader_index = mesh->shader[i];
243       Shader *shader = (shader_index < mesh->used_shaders.size()) ?
244                            mesh->used_shaders[shader_index] :
245                            scene->default_surface;
246 
247       tri_has_true_disp[i] = shader->has_displacement &&
248                              shader->displacement_method == DISPLACE_TRUE;
249     }
250 
251     /* static vertex normals */
252 
253     /* get attributes */
254     Attribute *attr_fN = mesh->attributes.find(ATTR_STD_FACE_NORMAL);
255     Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
256 
257     float3 *fN = attr_fN->data_float3();
258     float3 *vN = attr_vN->data_float3();
259 
260     /* compute vertex normals */
261 
262     /* zero vertex normals on triangles with true displacement */
263     for (size_t i = 0; i < num_triangles; i++) {
264       if (tri_has_true_disp[i]) {
265         for (size_t j = 0; j < 3; j++) {
266           vN[mesh->get_triangle(i).v[j]] = make_float3(0.0f, 0.0f, 0.0f);
267         }
268       }
269     }
270 
271     /* add face normals to vertex normals */
272     for (size_t i = 0; i < num_triangles; i++) {
273       if (tri_has_true_disp[i]) {
274         for (size_t j = 0; j < 3; j++) {
275           int vert = mesh->get_triangle(i).v[j];
276           vN[vert] += fN[i];
277 
278           /* add face normals to stitched vertices */
279           if (stitch_keys.size()) {
280             map_it_t key = mesh->vert_to_stitching_key_map.find(vert);
281 
282             if (key != mesh->vert_to_stitching_key_map.end()) {
283               pair<map_it_t, map_it_t> verts = mesh->vert_stitching_map.equal_range(key->second);
284 
285               for (map_it_t v = verts.first; v != verts.second; ++v) {
286                 if (v->second == vert) {
287                   continue;
288                 }
289 
290                 vN[v->second] += fN[i];
291               }
292             }
293           }
294         }
295       }
296     }
297 
298     /* normalize vertex normals */
299     done.clear();
300     done.resize(num_verts, false);
301 
302     for (size_t i = 0; i < num_triangles; i++) {
303       if (tri_has_true_disp[i]) {
304         for (size_t j = 0; j < 3; j++) {
305           int vert = mesh->get_triangle(i).v[j];
306 
307           if (done[vert]) {
308             continue;
309           }
310 
311           vN[vert] = normalize(vN[vert]);
312           if (flip)
313             vN[vert] = -vN[vert];
314 
315           done[vert] = true;
316         }
317       }
318     }
319 
320     /* motion vertex normals */
321     Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
322     Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
323 
324     if (mesh->has_motion_blur() && attr_mP && attr_mN) {
325       for (int step = 0; step < mesh->motion_steps - 1; step++) {
326         float3 *mP = attr_mP->data_float3() + step * mesh->verts.size();
327         float3 *mN = attr_mN->data_float3() + step * mesh->verts.size();
328 
329         /* compute */
330 
331         /* zero vertex normals on triangles with true displacement */
332         for (size_t i = 0; i < num_triangles; i++) {
333           if (tri_has_true_disp[i]) {
334             for (size_t j = 0; j < 3; j++) {
335               mN[mesh->get_triangle(i).v[j]] = make_float3(0.0f, 0.0f, 0.0f);
336             }
337           }
338         }
339 
340         /* add face normals to vertex normals */
341         for (size_t i = 0; i < num_triangles; i++) {
342           if (tri_has_true_disp[i]) {
343             for (size_t j = 0; j < 3; j++) {
344               int vert = mesh->get_triangle(i).v[j];
345               float3 fN = compute_face_normal(mesh->get_triangle(i), mP);
346               mN[vert] += fN;
347 
348               /* add face normals to stitched vertices */
349               if (stitch_keys.size()) {
350                 map_it_t key = mesh->vert_to_stitching_key_map.find(vert);
351 
352                 if (key != mesh->vert_to_stitching_key_map.end()) {
353                   pair<map_it_t, map_it_t> verts = mesh->vert_stitching_map.equal_range(
354                       key->second);
355 
356                   for (map_it_t v = verts.first; v != verts.second; ++v) {
357                     if (v->second == vert) {
358                       continue;
359                     }
360 
361                     mN[v->second] += fN;
362                   }
363                 }
364               }
365             }
366           }
367         }
368 
369         /* normalize vertex normals */
370         done.clear();
371         done.resize(num_verts, false);
372 
373         for (size_t i = 0; i < num_triangles; i++) {
374           if (tri_has_true_disp[i]) {
375             for (size_t j = 0; j < 3; j++) {
376               int vert = mesh->get_triangle(i).v[j];
377 
378               if (done[vert]) {
379                 continue;
380               }
381 
382               mN[vert] = normalize(mN[vert]);
383               if (flip)
384                 mN[vert] = -mN[vert];
385 
386               done[vert] = true;
387             }
388           }
389         }
390       }
391     }
392   }
393 
394   return true;
395 }
396 
397 CCL_NAMESPACE_END
398