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