mesh_displace.cpp 9.2 KB

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