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