Cycles microdisplacement: Move displacement options from mesh to material settings
[blender.git] / intern / cycles / render / mesh_displace.cpp
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.h"
18
19 #include "mesh.h"
20 #include "object.h"
21 #include "scene.h"
22 #include "shader.h"
23
24 #include "util_foreach.h"
25 #include "util_progress.h"
26
27 CCL_NAMESPACE_BEGIN
28
29 static float3 compute_face_normal(const Mesh::Triangle& t, float3 *verts)
30 {
31         float3 v0 = verts[t.v[0]];
32         float3 v1 = verts[t.v[1]];
33         float3 v2 = verts[t.v[2]];
34
35         float3 norm = cross(v1 - v0, v2 - v0);
36         float normlen = len(norm);
37
38         if(normlen == 0.0f)
39                 return make_float3(1.0f, 0.0f, 0.0f);
40
41         return norm / normlen;
42 }
43
44 bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress& progress)
45 {
46         /* verify if we have a displacement shader */
47         if(!mesh->has_true_displacement()) {
48                 return false;
49         }
50
51         string msg = string_printf("Computing Displacement %s", mesh->name.c_str());
52         progress.set_status("Updating Mesh", msg);
53
54         /* find object index. todo: is arbitrary */
55         size_t object_index = OBJECT_NONE;
56
57         for(size_t i = 0; i < scene->objects.size(); i++) {
58                 if(scene->objects[i]->mesh == mesh) {
59                         object_index = i;
60                         break;
61                 }
62         }
63
64         /* setup input for device task */
65         const size_t num_verts = mesh->verts.size();
66         vector<bool> done(num_verts, false);
67         device_vector<uint4> d_input;
68         uint4 *d_input_data = d_input.resize(num_verts);
69         size_t d_input_size = 0;
70
71         size_t num_triangles = mesh->num_triangles();
72         for(size_t i = 0; i < num_triangles; i++) {
73                 Mesh::Triangle t = mesh->get_triangle(i);
74                 int shader_index = mesh->shader[i];
75                 Shader *shader = (shader_index < mesh->used_shaders.size()) ?
76                         mesh->used_shaders[shader_index] : scene->default_surface;
77
78                 if(!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
79                         continue;
80                 }
81
82                 for(int j = 0; j < 3; j++) {
83                         if(done[t.v[j]])
84                                 continue;
85
86                         done[t.v[j]] = true;
87
88                         /* set up object, primitive and barycentric coordinates */
89                         /* when used, non-instanced convention: object = ~object */
90                         int object = ~object_index;
91                         int prim = mesh->tri_offset + i;
92                         float u, v;
93                         
94                         switch(j) {
95                                 case 0:
96                                         u = 1.0f;
97                                         v = 0.0f;
98                                         break;
99                                 case 1:
100                                         u = 0.0f;
101                                         v = 1.0f;
102                                         break;
103                                 default:
104                                         u = 0.0f;
105                                         v = 0.0f;
106                                         break;
107                         }
108
109                         /* back */
110                         uint4 in = make_uint4(object, prim, __float_as_int(u), __float_as_int(v));
111                         d_input_data[d_input_size++] = in;
112                 }
113         }
114
115         if(d_input_size == 0)
116                 return false;
117         
118         /* run device task */
119         device_vector<float4> d_output;
120         d_output.resize(d_input_size);
121
122         /* needs to be up to data for attribute access */
123         device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
124
125         device->mem_alloc(d_input, MEM_READ_ONLY);
126         device->mem_copy_to(d_input);
127         device->mem_alloc(d_output, MEM_WRITE_ONLY);
128
129         DeviceTask task(DeviceTask::SHADER);
130         task.shader_input = d_input.device_pointer;
131         task.shader_output = d_output.device_pointer;
132         task.shader_eval_type = SHADER_EVAL_DISPLACE;
133         task.shader_x = 0;
134         task.shader_w = d_output.size();
135         task.num_samples = 1;
136         task.get_cancel = function_bind(&Progress::get_cancel, &progress);
137
138         device->task_add(task);
139         device->task_wait();
140
141         if(progress.get_cancel()) {
142                 device->mem_free(d_input);
143                 device->mem_free(d_output);
144                 return false;
145         }
146
147         device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
148         device->mem_free(d_input);
149         device->mem_free(d_output);
150
151         /* read result */
152         done.clear();
153         done.resize(num_verts, false);
154         int k = 0;
155
156         float4 *offset = (float4*)d_output.data_pointer;
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] : scene->default_surface;
164
165                 if(!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
166                         continue;
167                 }
168
169                 for(int j = 0; j < 3; j++) {
170                         if(!done[t.v[j]]) {
171                                 done[t.v[j]] = true;
172                                 float3 off = float4_to_float3(offset[k++]);
173                                 mesh->verts[t.v[j]] += off;
174                                 if(attr_mP != NULL) {
175                                         for(int step = 0; step < mesh->motion_steps - 1; step++) {
176                                                 float3 *mP = attr_mP->data_float3() + step*num_verts;
177                                                 mP[t.v[j]] += off;
178                                         }
179                                 }
180                         }
181                 }
182         }
183
184         /* for displacement method both, we only need to recompute the face
185          * normals, as bump mapping in the shader will already alter the
186          * vertex normal, so we start from the non-displaced vertex normals
187          * to avoid applying the perturbation twice. */
188         mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
189         mesh->add_face_normals();
190
191         bool need_recompute_vertex_normals = false;
192
193         foreach(Shader *shader, mesh->used_shaders) {
194                 if(shader->has_displacement && shader->displacement_method == DISPLACE_TRUE) {
195                         need_recompute_vertex_normals = true;
196                         break;
197                 }
198         }
199
200         if(need_recompute_vertex_normals) {
201                 bool flip = mesh->transform_negative_scaled;
202                 vector<bool> tri_has_true_disp(num_triangles, false);
203
204                 for(size_t i = 0; i < num_triangles; i++) {
205                         int shader_index = mesh->shader[i];
206                         Shader *shader = (shader_index < mesh->used_shaders.size()) ?
207                                 mesh->used_shaders[shader_index] : scene->default_surface;
208
209                         tri_has_true_disp[i] = shader->has_displacement && shader->displacement_method == DISPLACE_TRUE;
210                 }
211
212                 /* static vertex normals */
213
214                 /* get attributes */
215                 Attribute *attr_fN = mesh->attributes.find(ATTR_STD_FACE_NORMAL);
216                 Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
217
218                 float3 *fN = attr_fN->data_float3();
219                 float3 *vN = attr_vN->data_float3();
220
221                 /* compute vertex normals */
222
223                 /* zero vertex normals on triangles with true displacement */
224                 for(size_t i = 0; i < num_triangles; i++) {
225                         if(tri_has_true_disp[i]) {
226                                 for(size_t j = 0; j < 3; j++) {
227                                         vN[mesh->get_triangle(i).v[j]] = make_float3(0.0f, 0.0f, 0.0f);
228                                 }
229                         }
230                 }
231
232                 /* add face normals to vertex normals */
233                 for(size_t i = 0; i < num_triangles; i++) {
234                         if(tri_has_true_disp[i]) {
235                                 for(size_t j = 0; j < 3; j++) {
236                                         vN[mesh->get_triangle(i).v[j]] += fN[i];
237                                 }
238                         }
239                 }
240
241                 /* normalize vertex normals */
242                 done.clear();
243                 done.resize(num_verts, false);
244
245                 for(size_t i = 0; i < num_triangles; i++) {
246                         if(tri_has_true_disp[i]) {
247                                 for(size_t j = 0; j < 3; j++) {
248                                         int vert = mesh->get_triangle(i).v[j];
249
250                                         if(done[vert]) {
251                                                 continue;
252                                         }
253
254                                         vN[vert] = normalize(vN[vert]);
255                                         if(flip)
256                                                 vN[vert] = -vN[vert];
257
258                                         done[vert] = true;
259                                 }
260                         }
261                 }
262
263                 /* motion vertex normals */
264                 Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
265                 Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
266
267                 if(mesh->has_motion_blur() && attr_mP && attr_mN) {
268                         for(int step = 0; step < mesh->motion_steps - 1; step++) {
269                                 float3 *mP = attr_mP->data_float3() + step*mesh->verts.size();
270                                 float3 *mN = attr_mN->data_float3() + step*mesh->verts.size();
271
272                                 /* compute */
273
274                                 /* zero vertex normals on triangles with true displacement */
275                                 for(size_t i = 0; i < num_triangles; i++) {
276                                         if(tri_has_true_disp[i]) {
277                                                 for(size_t j = 0; j < 3; j++) {
278                                                         mN[mesh->get_triangle(i).v[j]] = make_float3(0.0f, 0.0f, 0.0f);
279                                                 }
280                                         }
281                                 }
282
283                                 /* add face normals to vertex normals */
284                                 for(size_t i = 0; i < num_triangles; i++) {
285                                         if(tri_has_true_disp[i]) {
286                                                 for(size_t j = 0; j < 3; j++) {
287                                                         float3 fN = compute_face_normal(mesh->get_triangle(i), mP);
288                                                         mN[mesh->get_triangle(i).v[j]] += fN;
289                                                 }
290                                         }
291                                 }
292
293                                 /* normalize vertex normals */
294                                 done.clear();
295                                 done.resize(num_verts, false);
296
297                                 for(size_t i = 0; i < num_triangles; i++) {
298                                         if(tri_has_true_disp[i]) {
299                                                 for(size_t j = 0; j < 3; j++) {
300                                                         int vert = mesh->get_triangle(i).v[j];
301
302                                                         if(done[vert]) {
303                                                                 continue;
304                                                         }
305
306                                                         mN[vert] = normalize(mN[vert]);
307                                                         if(flip)
308                                                                 mN[vert] = -mN[vert];
309
310                                                         done[vert] = true;
311                                                 }
312                                         }
313                                 }
314                         }
315                 }
316         }
317
318         return true;
319 }
320
321 CCL_NAMESPACE_END
322