geom_primitive.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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. /* Primitive Utilities
  17. *
  18. * Generic functions to look up mesh, curve and volume primitive attributes for
  19. * shading and render passes. */
  20. CCL_NAMESPACE_BEGIN
  21. /* Generic primitive attribute reading functions */
  22. ccl_device_inline float primitive_attribute_float(
  23. KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
  24. {
  25. if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
  26. if (subd_triangle_patch(kg, sd) == ~0)
  27. return triangle_attribute_float(kg, sd, desc, dx, dy);
  28. else
  29. return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
  30. }
  31. #ifdef __HAIR__
  32. else if (sd->type & PRIMITIVE_ALL_CURVE) {
  33. return curve_attribute_float(kg, sd, desc, dx, dy);
  34. }
  35. #endif
  36. #ifdef __VOLUME__
  37. else if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
  38. if (dx)
  39. *dx = 0.0f;
  40. if (dy)
  41. *dy = 0.0f;
  42. return volume_attribute_float(kg, sd, desc);
  43. }
  44. #endif
  45. else {
  46. if (dx)
  47. *dx = 0.0f;
  48. if (dy)
  49. *dy = 0.0f;
  50. return 0.0f;
  51. }
  52. }
  53. ccl_device_inline float primitive_surface_attribute_float(
  54. KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
  55. {
  56. if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
  57. if (subd_triangle_patch(kg, sd) == ~0)
  58. return triangle_attribute_float(kg, sd, desc, dx, dy);
  59. else
  60. return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
  61. }
  62. #ifdef __HAIR__
  63. else if (sd->type & PRIMITIVE_ALL_CURVE) {
  64. return curve_attribute_float(kg, sd, desc, dx, dy);
  65. }
  66. #endif
  67. else {
  68. if (dx)
  69. *dx = 0.0f;
  70. if (dy)
  71. *dy = 0.0f;
  72. return 0.0f;
  73. }
  74. }
  75. #ifdef __VOLUME__
  76. ccl_device_inline float primitive_volume_attribute_float(KernelGlobals *kg,
  77. const ShaderData *sd,
  78. const AttributeDescriptor desc)
  79. {
  80. if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
  81. return volume_attribute_float(kg, sd, desc);
  82. }
  83. else {
  84. return 0.0f;
  85. }
  86. }
  87. #endif
  88. ccl_device_inline float2 primitive_attribute_float2(KernelGlobals *kg,
  89. const ShaderData *sd,
  90. const AttributeDescriptor desc,
  91. float2 *dx,
  92. float2 *dy)
  93. {
  94. if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
  95. if (subd_triangle_patch(kg, sd) == ~0)
  96. return triangle_attribute_float2(kg, sd, desc, dx, dy);
  97. else
  98. return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
  99. }
  100. #ifdef __HAIR__
  101. else if (sd->type & PRIMITIVE_ALL_CURVE) {
  102. return curve_attribute_float2(kg, sd, desc, dx, dy);
  103. }
  104. #endif
  105. #ifdef __VOLUME__
  106. else if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
  107. kernel_assert(0);
  108. if (dx)
  109. *dx = make_float2(0.0f, 0.0f);
  110. if (dy)
  111. *dy = make_float2(0.0f, 0.0f);
  112. return make_float2(0.0f, 0.0f);
  113. }
  114. #endif
  115. else {
  116. if (dx)
  117. *dx = make_float2(0.0f, 0.0f);
  118. if (dy)
  119. *dy = make_float2(0.0f, 0.0f);
  120. return make_float2(0.0f, 0.0f);
  121. }
  122. }
  123. ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg,
  124. const ShaderData *sd,
  125. const AttributeDescriptor desc,
  126. float3 *dx,
  127. float3 *dy)
  128. {
  129. if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
  130. if (subd_triangle_patch(kg, sd) == ~0)
  131. return triangle_attribute_float3(kg, sd, desc, dx, dy);
  132. else
  133. return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
  134. }
  135. #ifdef __HAIR__
  136. else if (sd->type & PRIMITIVE_ALL_CURVE) {
  137. return curve_attribute_float3(kg, sd, desc, dx, dy);
  138. }
  139. #endif
  140. #ifdef __VOLUME__
  141. else if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
  142. if (dx)
  143. *dx = make_float3(0.0f, 0.0f, 0.0f);
  144. if (dy)
  145. *dy = make_float3(0.0f, 0.0f, 0.0f);
  146. return volume_attribute_float3(kg, sd, desc);
  147. }
  148. #endif
  149. else {
  150. if (dx)
  151. *dx = make_float3(0.0f, 0.0f, 0.0f);
  152. if (dy)
  153. *dy = make_float3(0.0f, 0.0f, 0.0f);
  154. return make_float3(0.0f, 0.0f, 0.0f);
  155. }
  156. }
  157. ccl_device_inline float2 primitive_surface_attribute_float2(KernelGlobals *kg,
  158. const ShaderData *sd,
  159. const AttributeDescriptor desc,
  160. float2 *dx,
  161. float2 *dy)
  162. {
  163. if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
  164. if (subd_triangle_patch(kg, sd) == ~0)
  165. return triangle_attribute_float2(kg, sd, desc, dx, dy);
  166. else
  167. return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
  168. }
  169. #ifdef __HAIR__
  170. else if (sd->type & PRIMITIVE_ALL_CURVE) {
  171. return curve_attribute_float2(kg, sd, desc, dx, dy);
  172. }
  173. #endif
  174. else {
  175. if (dx)
  176. *dx = make_float2(0.0f, 0.0f);
  177. if (dy)
  178. *dy = make_float2(0.0f, 0.0f);
  179. return make_float2(0.0f, 0.0f);
  180. }
  181. }
  182. ccl_device_inline float3 primitive_surface_attribute_float3(KernelGlobals *kg,
  183. const ShaderData *sd,
  184. const AttributeDescriptor desc,
  185. float3 *dx,
  186. float3 *dy)
  187. {
  188. if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
  189. if (subd_triangle_patch(kg, sd) == ~0)
  190. return triangle_attribute_float3(kg, sd, desc, dx, dy);
  191. else
  192. return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
  193. }
  194. #ifdef __HAIR__
  195. else if (sd->type & PRIMITIVE_ALL_CURVE) {
  196. return curve_attribute_float3(kg, sd, desc, dx, dy);
  197. }
  198. #endif
  199. else {
  200. if (dx)
  201. *dx = make_float3(0.0f, 0.0f, 0.0f);
  202. if (dy)
  203. *dy = make_float3(0.0f, 0.0f, 0.0f);
  204. return make_float3(0.0f, 0.0f, 0.0f);
  205. }
  206. }
  207. #ifdef __VOLUME__
  208. ccl_device_inline float3 primitive_volume_attribute_float3(KernelGlobals *kg,
  209. const ShaderData *sd,
  210. const AttributeDescriptor desc)
  211. {
  212. if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
  213. return volume_attribute_float3(kg, sd, desc);
  214. }
  215. else {
  216. return make_float3(0.0f, 0.0f, 0.0f);
  217. }
  218. }
  219. #endif
  220. /* Default UV coordinate */
  221. ccl_device_inline float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
  222. {
  223. const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_UV);
  224. if (desc.offset == ATTR_STD_NOT_FOUND)
  225. return make_float3(0.0f, 0.0f, 0.0f);
  226. float2 uv = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
  227. return make_float3(uv.x, uv.y, 1.0f);
  228. }
  229. /* Ptex coordinates */
  230. ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, int *face_id)
  231. {
  232. /* storing ptex data as attributes is not memory efficient but simple for tests */
  233. const AttributeDescriptor desc_face_id = find_attribute(kg, sd, ATTR_STD_PTEX_FACE_ID);
  234. const AttributeDescriptor desc_uv = find_attribute(kg, sd, ATTR_STD_PTEX_UV);
  235. if (desc_face_id.offset == ATTR_STD_NOT_FOUND || desc_uv.offset == ATTR_STD_NOT_FOUND)
  236. return false;
  237. float3 uv3 = primitive_surface_attribute_float3(kg, sd, desc_uv, NULL, NULL);
  238. float face_id_f = primitive_surface_attribute_float(kg, sd, desc_face_id, NULL, NULL);
  239. *uv = make_float2(uv3.x, uv3.y);
  240. *face_id = (int)face_id_f;
  241. return true;
  242. }
  243. /* Surface tangent */
  244. ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
  245. {
  246. #ifdef __HAIR__
  247. if (sd->type & PRIMITIVE_ALL_CURVE)
  248. # ifdef __DPDU__
  249. return normalize(sd->dPdu);
  250. # else
  251. return make_float3(0.0f, 0.0f, 0.0f);
  252. # endif
  253. #endif
  254. /* try to create spherical tangent from generated coordinates */
  255. const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_GENERATED);
  256. if (desc.offset != ATTR_STD_NOT_FOUND) {
  257. float3 data = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
  258. data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
  259. object_normal_transform(kg, sd, &data);
  260. return cross(sd->N, normalize(cross(data, sd->N)));
  261. }
  262. else {
  263. /* otherwise use surface derivatives */
  264. #ifdef __DPDU__
  265. return normalize(sd->dPdu);
  266. #else
  267. return make_float3(0.0f, 0.0f, 0.0f);
  268. #endif
  269. }
  270. }
  271. /* Motion vector for motion pass */
  272. ccl_device_inline float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
  273. {
  274. /* center position */
  275. float3 center;
  276. #ifdef __HAIR__
  277. bool is_curve_primitive = sd->type & PRIMITIVE_ALL_CURVE;
  278. if (is_curve_primitive) {
  279. center = curve_motion_center_location(kg, sd);
  280. if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
  281. object_position_transform(kg, sd, &center);
  282. }
  283. }
  284. else
  285. #endif
  286. center = sd->P;
  287. float3 motion_pre = center, motion_post = center;
  288. /* deformation motion */
  289. AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_MOTION_VERTEX_POSITION);
  290. if (desc.offset != ATTR_STD_NOT_FOUND) {
  291. /* get motion info */
  292. int numverts, numkeys;
  293. object_motion_info(kg, sd->object, NULL, &numverts, &numkeys);
  294. /* lookup attributes */
  295. motion_pre = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
  296. desc.offset += (sd->type & PRIMITIVE_ALL_TRIANGLE) ? numverts : numkeys;
  297. motion_post = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
  298. #ifdef __HAIR__
  299. if (is_curve_primitive && (sd->object_flag & SD_OBJECT_HAS_VERTEX_MOTION) == 0) {
  300. object_position_transform(kg, sd, &motion_pre);
  301. object_position_transform(kg, sd, &motion_post);
  302. }
  303. #endif
  304. }
  305. /* object motion. note that depending on the mesh having motion vectors, this
  306. * transformation was set match the world/object space of motion_pre/post */
  307. Transform tfm;
  308. tfm = object_fetch_motion_pass_transform(kg, sd->object, OBJECT_PASS_MOTION_PRE);
  309. motion_pre = transform_point(&tfm, motion_pre);
  310. tfm = object_fetch_motion_pass_transform(kg, sd->object, OBJECT_PASS_MOTION_POST);
  311. motion_post = transform_point(&tfm, motion_post);
  312. float3 motion_center;
  313. /* camera motion, for perspective/orthographic motion.pre/post will be a
  314. * world-to-raster matrix, for panorama it's world-to-camera */
  315. if (kernel_data.cam.type != CAMERA_PANORAMA) {
  316. ProjectionTransform projection = kernel_data.cam.worldtoraster;
  317. motion_center = transform_perspective(&projection, center);
  318. projection = kernel_data.cam.perspective_pre;
  319. motion_pre = transform_perspective(&projection, motion_pre);
  320. projection = kernel_data.cam.perspective_post;
  321. motion_post = transform_perspective(&projection, motion_post);
  322. }
  323. else {
  324. tfm = kernel_data.cam.worldtocamera;
  325. motion_center = normalize(transform_point(&tfm, center));
  326. motion_center = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_center));
  327. motion_center.x *= kernel_data.cam.width;
  328. motion_center.y *= kernel_data.cam.height;
  329. tfm = kernel_data.cam.motion_pass_pre;
  330. motion_pre = normalize(transform_point(&tfm, motion_pre));
  331. motion_pre = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_pre));
  332. motion_pre.x *= kernel_data.cam.width;
  333. motion_pre.y *= kernel_data.cam.height;
  334. tfm = kernel_data.cam.motion_pass_post;
  335. motion_post = normalize(transform_point(&tfm, motion_post));
  336. motion_post = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_post));
  337. motion_post.x *= kernel_data.cam.width;
  338. motion_post.y *= kernel_data.cam.height;
  339. }
  340. motion_pre = motion_pre - motion_center;
  341. motion_post = motion_center - motion_post;
  342. return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
  343. }
  344. CCL_NAMESPACE_END