Blender  V2.93
geom_curve.h
Go to the documentation of this file.
1 /*
2  * Licensed under the Apache License, Version 2.0 (the "License");
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14 
16 
17 /* Curve Primitive
18  *
19  * Curve primitive for rendering hair and fur. These can be render as flat
20  * ribbons or curves with actual thickness. The curve can also be rendered as
21  * line segments rather than curves for better performance.
22  */
23 
24 #ifdef __HAIR__
25 
26 /* Reading attributes on various curve elements */
27 
28 ccl_device float curve_attribute_float(
29  KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
30 {
32  float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
33  int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
34  int k1 = k0 + 1;
35 
36  float f0 = kernel_tex_fetch(__attributes_float, desc.offset + k0);
37  float f1 = kernel_tex_fetch(__attributes_float, desc.offset + k1);
38 
39 # ifdef __RAY_DIFFERENTIALS__
40  if (dx)
41  *dx = sd->du.dx * (f1 - f0);
42  if (dy)
43  *dy = 0.0f;
44 # endif
45 
46  return (1.0f - sd->u) * f0 + sd->u * f1;
47  }
48  else {
49 # ifdef __RAY_DIFFERENTIALS__
50  if (dx)
51  *dx = 0.0f;
52  if (dy)
53  *dy = 0.0f;
54 # endif
55 
57  const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
58  desc.offset;
59  return kernel_tex_fetch(__attributes_float, offset);
60  }
61  else {
62  return 0.0f;
63  }
64  }
65 }
66 
67 ccl_device float2 curve_attribute_float2(KernelGlobals *kg,
68  const ShaderData *sd,
69  const AttributeDescriptor desc,
70  float2 *dx,
71  float2 *dy)
72 {
74  float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
75  int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
76  int k1 = k0 + 1;
77 
78  float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + k0);
79  float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + k1);
80 
81 # ifdef __RAY_DIFFERENTIALS__
82  if (dx)
83  *dx = sd->du.dx * (f1 - f0);
84  if (dy)
85  *dy = make_float2(0.0f, 0.0f);
86 # endif
87 
88  return (1.0f - sd->u) * f0 + sd->u * f1;
89  }
90  else {
91  /* idea: we can't derive any useful differentials here, but for tiled
92  * mipmap image caching it would be useful to avoid reading the highest
93  * detail level always. maybe a derivative based on the hair density
94  * could be computed somehow? */
95 # ifdef __RAY_DIFFERENTIALS__
96  if (dx)
97  *dx = make_float2(0.0f, 0.0f);
98  if (dy)
99  *dy = make_float2(0.0f, 0.0f);
100 # endif
101 
103  const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
104  desc.offset;
105  return kernel_tex_fetch(__attributes_float2, offset);
106  }
107  else {
108  return make_float2(0.0f, 0.0f);
109  }
110  }
111 }
112 
113 ccl_device float3 curve_attribute_float3(KernelGlobals *kg,
114  const ShaderData *sd,
115  const AttributeDescriptor desc,
116  float3 *dx,
117  float3 *dy)
118 {
120  float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
121  int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
122  int k1 = k0 + 1;
123 
124  float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k0));
125  float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k1));
126 
127 # ifdef __RAY_DIFFERENTIALS__
128  if (dx)
129  *dx = sd->du.dx * (f1 - f0);
130  if (dy)
131  *dy = make_float3(0.0f, 0.0f, 0.0f);
132 # endif
133 
134  return (1.0f - sd->u) * f0 + sd->u * f1;
135  }
136  else {
137 # ifdef __RAY_DIFFERENTIALS__
138  if (dx)
139  *dx = make_float3(0.0f, 0.0f, 0.0f);
140  if (dy)
141  *dy = make_float3(0.0f, 0.0f, 0.0f);
142 # endif
143 
145  const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
146  desc.offset;
147  return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset));
148  }
149  else {
150  return make_float3(0.0f, 0.0f, 0.0f);
151  }
152  }
153 }
154 
155 ccl_device float4 curve_attribute_float4(KernelGlobals *kg,
156  const ShaderData *sd,
157  const AttributeDescriptor desc,
158  float4 *dx,
159  float4 *dy)
160 {
162  float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
163  int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
164  int k1 = k0 + 1;
165 
166  float4 f0 = kernel_tex_fetch(__attributes_float3, desc.offset + k0);
167  float4 f1 = kernel_tex_fetch(__attributes_float3, desc.offset + k1);
168 
169 # ifdef __RAY_DIFFERENTIALS__
170  if (dx)
171  *dx = sd->du.dx * (f1 - f0);
172  if (dy)
173  *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
174 # endif
175 
176  return (1.0f - sd->u) * f0 + sd->u * f1;
177  }
178  else {
179 # ifdef __RAY_DIFFERENTIALS__
180  if (dx)
181  *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
182  if (dy)
183  *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
184 # endif
185 
187  const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
188  desc.offset;
189  return kernel_tex_fetch(__attributes_float3, offset);
190  }
191  else {
192  return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
193  }
194  }
195 }
196 
197 /* Curve thickness */
198 
199 ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
200 {
201  float r = 0.0f;
202 
203  if (sd->type & PRIMITIVE_ALL_CURVE) {
204  float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
205  int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
206  int k1 = k0 + 1;
207 
208  float4 P_curve[2];
209 
210  if (!(sd->type & PRIMITIVE_ALL_MOTION)) {
211  P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
212  P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
213  }
214  else {
215  motion_curve_keys_linear(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
216  }
217 
218  r = (P_curve[1].w - P_curve[0].w) * sd->u + P_curve[0].w;
219  }
220 
221  return r * 2.0f;
222 }
223 
224 /* Curve location for motion pass, linear interpolation between keys and
225  * ignoring radius because we do the same for the motion keys */
226 
227 ccl_device float3 curve_motion_center_location(KernelGlobals *kg, ShaderData *sd)
228 {
229  float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
230  int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
231  int k1 = k0 + 1;
232 
233  float4 P_curve[2];
234 
235  P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
236  P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
237 
238  return float4_to_float3(P_curve[1]) * sd->u + float4_to_float3(P_curve[0]) * (1.0f - sd->u);
239 }
240 
241 /* Curve tangent normal */
242 
243 ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
244 {
245  float3 tgN = make_float3(0.0f, 0.0f, 0.0f);
246 
247  if (sd->type & PRIMITIVE_ALL_CURVE) {
248 
249  tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu, -sd->I) / len_squared(sd->dPdu)));
250  tgN = normalize(tgN);
251 
252  /* need to find suitable scaled gd for corrected normal */
253 # if 0
254  tgN = normalize(tgN - gd * sd->dPdu);
255 # endif
256  }
257 
258  return tgN;
259 }
260 
261 /* Curve bounds utility function */
262 
263 ccl_device_inline void curvebounds(float *lower,
264  float *upper,
265  float *extremta,
266  float *extrema,
267  float *extremtb,
268  float *extremb,
269  float p0,
270  float p1,
271  float p2,
272  float p3)
273 {
274  float halfdiscroot = (p2 * p2 - 3 * p3 * p1);
275  float ta = -1.0f;
276  float tb = -1.0f;
277 
278  *extremta = -1.0f;
279  *extremtb = -1.0f;
280  *upper = p0;
281  *lower = (p0 + p1) + (p2 + p3);
282  *extrema = *upper;
283  *extremb = *lower;
284 
285  if (*lower >= *upper) {
286  *upper = *lower;
287  *lower = p0;
288  }
289 
290  if (halfdiscroot >= 0) {
291  float inv3p3 = (1.0f / 3.0f) / p3;
292  halfdiscroot = sqrtf(halfdiscroot);
293  ta = (-p2 - halfdiscroot) * inv3p3;
294  tb = (-p2 + halfdiscroot) * inv3p3;
295  }
296 
297  float t2;
298  float t3;
299 
300  if (ta > 0.0f && ta < 1.0f) {
301  t2 = ta * ta;
302  t3 = t2 * ta;
303  *extremta = ta;
304  *extrema = p3 * t3 + p2 * t2 + p1 * ta + p0;
305 
306  *upper = fmaxf(*extrema, *upper);
307  *lower = fminf(*extrema, *lower);
308  }
309 
310  if (tb > 0.0f && tb < 1.0f) {
311  t2 = tb * tb;
312  t3 = t2 * tb;
313  *extremtb = tb;
314  *extremb = p3 * t3 + p2 * t2 + p1 * tb + p0;
315 
316  *upper = fmaxf(*extremb, *upper);
317  *lower = fminf(*extremb, *lower);
318  }
319 }
320 
321 #endif /* __HAIR__ */
322 
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
CCL_NAMESPACE_BEGIN void curvebounds(float *lower, float *upper, float3 *p, int dim)
Definition: curves.cpp:32
#define kernel_tex_fetch(tex, index)
#define ccl_device
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define fmaxf(x, y)
#define make_float2(x, y)
#define fminf(x, y)
#define make_float4(x, y, z, w)
#define sqrtf(x)
#define make_float3(x, y, z)
@ PRIMITIVE_ALL_CURVE
Definition: kernel_types.h:698
@ PRIMITIVE_ALL_MOTION
Definition: kernel_types.h:700
#define PRIMITIVE_UNPACK_SEGMENT(type)
Definition: kernel_types.h:711
ShaderData
@ ATTR_ELEMENT_CURVE_KEY
Definition: kernel_types.h:739
@ ATTR_ELEMENT_CURVE_KEY_MOTION
Definition: kernel_types.h:740
@ ATTR_ELEMENT_OBJECT
Definition: kernel_types.h:731
@ ATTR_ELEMENT_MESH
Definition: kernel_types.h:732
@ ATTR_ELEMENT_CURVE
Definition: kernel_types.h:738
AttributeElement element
Definition: kernel_types.h:782
ccl_device_inline int __float_as_int(float f)
Definition: util_math.h:202
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition: util_math.h:415
ccl_device_inline float2 normalize(const float2 &a)
ccl_device_inline float dot(const float2 &a, const float2 &b)
ccl_device_inline float len_squared(const float3 a)