Blender  V3.3
triangle.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 /* Triangle Primitive
5  *
6  * Basic triangle with 3 vertices is used to represent mesh surfaces. For BVH
7  * ray intersection we use a precomputed triangle storage to accelerate
8  * intersection at the cost of more memory usage */
9 
10 #pragma once
11 
13 
14 /* Normal on triangle. */
16 {
17  /* load triangle vertices */
18  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
19  const float3 v0 = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
20  const float3 v1 = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
21  const float3 v2 = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
22 
23  /* return normal */
24  if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
25  return normalize(cross(v2 - v0, v1 - v0));
26  }
27  else {
28  return normalize(cross(v1 - v0, v2 - v0));
29  }
30 }
31 
32 /* Point and normal on triangle. */
34  int object,
35  int prim,
36  float u,
37  float v,
39  ccl_private float3 *Ng,
40  ccl_private int *shader)
41 {
42  /* load triangle vertices */
43  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
44  float3 v0 = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
45  float3 v1 = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
46  float3 v2 = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
47  /* compute point */
48  float w = 1.0f - u - v;
49  *P = (w * v0 + u * v1 + v * v2);
50  /* get object flags */
51  int object_flag = kernel_data_fetch(object_flag, object);
52  /* compute normal */
53  if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
54  *Ng = normalize(cross(v2 - v0, v1 - v0));
55  }
56  else {
57  *Ng = normalize(cross(v1 - v0, v2 - v0));
58  }
59  /* shader`*/
60  *shader = kernel_data_fetch(tri_shader, prim);
61 }
62 
63 /* Triangle vertex locations */
64 
66 {
67  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
68  P[0] = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
69  P[1] = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
70  P[2] = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
71 }
72 
73 /* Triangle vertex locations and vertex normals */
74 
76  int prim,
77  float3 P[3],
78  float3 N[3])
79 {
80  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
81  P[0] = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
82  P[1] = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
83  P[2] = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
84  N[0] = kernel_data_fetch(tri_vnormal, tri_vindex.x);
85  N[1] = kernel_data_fetch(tri_vnormal, tri_vindex.y);
86  N[2] = kernel_data_fetch(tri_vnormal, tri_vindex.z);
87 }
88 
89 /* Interpolate smooth vertex normal from vertices */
90 
92 triangle_smooth_normal(KernelGlobals kg, float3 Ng, int prim, float u, float v)
93 {
94  /* load triangle vertices */
95  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
96  float3 n0 = kernel_data_fetch(tri_vnormal, tri_vindex.x);
97  float3 n1 = kernel_data_fetch(tri_vnormal, tri_vindex.y);
98  float3 n2 = kernel_data_fetch(tri_vnormal, tri_vindex.z);
99 
100  float3 N = safe_normalize((1.0f - u - v) * n0 + u * n1 + v * n2);
101 
102  return is_zero(N) ? Ng : N;
103 }
104 
106  KernelGlobals kg, ccl_private const ShaderData *sd, float3 Ng, int prim, float u, float v)
107 {
108  /* load triangle vertices */
109  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
110  float3 n0 = kernel_data_fetch(tri_vnormal, tri_vindex.x);
111  float3 n1 = kernel_data_fetch(tri_vnormal, tri_vindex.y);
112  float3 n2 = kernel_data_fetch(tri_vnormal, tri_vindex.z);
113 
114  /* ensure that the normals are in object space */
115  if (sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED) {
116  object_inverse_normal_transform(kg, sd, &n0);
117  object_inverse_normal_transform(kg, sd, &n1);
118  object_inverse_normal_transform(kg, sd, &n2);
119  }
120 
121  float3 N = (1.0f - u - v) * n0 + u * n1 + v * n2;
122 
123  return is_zero(N) ? Ng : N;
124 }
125 
126 /* Ray differentials on triangle */
127 
129  int prim,
130  ccl_private float3 *dPdu,
131  ccl_private float3 *dPdv)
132 {
133  /* fetch triangle vertex coordinates */
134  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
135  const float3 p0 = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
136  const float3 p1 = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
137  const float3 p2 = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
138 
139  /* compute derivatives of P w.r.t. uv */
140  *dPdu = (p1 - p0);
141  *dPdv = (p2 - p0);
142 }
143 
144 /* Reading attributes on various triangle elements */
145 
147  ccl_private const ShaderData *sd,
148  const AttributeDescriptor desc,
149  ccl_private float *dx,
150  ccl_private float *dy)
151 {
153  float f0, f1, f2;
154 
156  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
157  f0 = kernel_data_fetch(attributes_float, desc.offset + tri_vindex.x);
158  f1 = kernel_data_fetch(attributes_float, desc.offset + tri_vindex.y);
159  f2 = kernel_data_fetch(attributes_float, desc.offset + tri_vindex.z);
160  }
161  else {
162  const int tri = desc.offset + sd->prim * 3;
163  f0 = kernel_data_fetch(attributes_float, tri + 0);
164  f1 = kernel_data_fetch(attributes_float, tri + 1);
165  f2 = kernel_data_fetch(attributes_float, tri + 2);
166  }
167 
168 #ifdef __RAY_DIFFERENTIALS__
169  if (dx)
170  *dx = sd->du.dx * f1 + sd->dv.dx * f2 - (sd->du.dx + sd->dv.dx) * f0;
171  if (dy)
172  *dy = sd->du.dy * f1 + sd->dv.dy * f2 - (sd->du.dy + sd->dv.dy) * f0;
173 #endif
174 
175  return sd->u * f1 + sd->v * f2 + (1.0f - sd->u - sd->v) * f0;
176  }
177  else {
178 #ifdef __RAY_DIFFERENTIALS__
179  if (dx)
180  *dx = 0.0f;
181  if (dy)
182  *dy = 0.0f;
183 #endif
184 
186  const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
187  desc.offset;
188  return kernel_data_fetch(attributes_float, offset);
189  }
190  else {
191  return 0.0f;
192  }
193  }
194 }
195 
197  ccl_private const ShaderData *sd,
198  const AttributeDescriptor desc,
199  ccl_private float2 *dx,
200  ccl_private float2 *dy)
201 {
203  float2 f0, f1, f2;
204 
206  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
207  f0 = kernel_data_fetch(attributes_float2, desc.offset + tri_vindex.x);
208  f1 = kernel_data_fetch(attributes_float2, desc.offset + tri_vindex.y);
209  f2 = kernel_data_fetch(attributes_float2, desc.offset + tri_vindex.z);
210  }
211  else {
212  const int tri = desc.offset + sd->prim * 3;
213  f0 = kernel_data_fetch(attributes_float2, tri + 0);
214  f1 = kernel_data_fetch(attributes_float2, tri + 1);
215  f2 = kernel_data_fetch(attributes_float2, tri + 2);
216  }
217 
218 #ifdef __RAY_DIFFERENTIALS__
219  if (dx)
220  *dx = sd->du.dx * f1 + sd->dv.dx * f2 - (sd->du.dx + sd->dv.dx) * f0;
221  if (dy)
222  *dy = sd->du.dy * f1 + sd->dv.dy * f2 - (sd->du.dy + sd->dv.dy) * f0;
223 #endif
224 
225  return sd->u * f1 + sd->v * f2 + (1.0f - sd->u - sd->v) * f0;
226  }
227  else {
228 #ifdef __RAY_DIFFERENTIALS__
229  if (dx)
230  *dx = make_float2(0.0f, 0.0f);
231  if (dy)
232  *dy = make_float2(0.0f, 0.0f);
233 #endif
234 
236  const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
237  desc.offset;
238  return kernel_data_fetch(attributes_float2, offset);
239  }
240  else {
241  return make_float2(0.0f, 0.0f);
242  }
243  }
244 }
245 
247  ccl_private const ShaderData *sd,
248  const AttributeDescriptor desc,
249  ccl_private float3 *dx,
250  ccl_private float3 *dy)
251 {
253  float3 f0, f1, f2;
254 
256  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
257  f0 = kernel_data_fetch(attributes_float3, desc.offset + tri_vindex.x);
258  f1 = kernel_data_fetch(attributes_float3, desc.offset + tri_vindex.y);
259  f2 = kernel_data_fetch(attributes_float3, desc.offset + tri_vindex.z);
260  }
261  else {
262  const int tri = desc.offset + sd->prim * 3;
263  f0 = kernel_data_fetch(attributes_float3, tri + 0);
264  f1 = kernel_data_fetch(attributes_float3, tri + 1);
265  f2 = kernel_data_fetch(attributes_float3, tri + 2);
266  }
267 
268 #ifdef __RAY_DIFFERENTIALS__
269  if (dx)
270  *dx = sd->du.dx * f1 + sd->dv.dx * f2 - (sd->du.dx + sd->dv.dx) * f0;
271  if (dy)
272  *dy = sd->du.dy * f1 + sd->dv.dy * f2 - (sd->du.dy + sd->dv.dy) * f0;
273 #endif
274 
275  return sd->u * f1 + sd->v * f2 + (1.0f - sd->u - sd->v) * f0;
276  }
277  else {
278 #ifdef __RAY_DIFFERENTIALS__
279  if (dx)
280  *dx = make_float3(0.0f, 0.0f, 0.0f);
281  if (dy)
282  *dy = make_float3(0.0f, 0.0f, 0.0f);
283 #endif
284 
286  const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
287  desc.offset;
288  return kernel_data_fetch(attributes_float3, offset);
289  }
290  else {
291  return make_float3(0.0f, 0.0f, 0.0f);
292  }
293  }
294 }
295 
297  ccl_private const ShaderData *sd,
298  const AttributeDescriptor desc,
299  ccl_private float4 *dx,
300  ccl_private float4 *dy)
301 {
304  float4 f0, f1, f2;
305 
307  const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
308  f0 = kernel_data_fetch(attributes_float4, desc.offset + tri_vindex.x);
309  f1 = kernel_data_fetch(attributes_float4, desc.offset + tri_vindex.y);
310  f2 = kernel_data_fetch(attributes_float4, desc.offset + tri_vindex.z);
311  }
312  else {
313  const int tri = desc.offset + sd->prim * 3;
314  if (desc.element == ATTR_ELEMENT_CORNER) {
315  f0 = kernel_data_fetch(attributes_float4, tri + 0);
316  f1 = kernel_data_fetch(attributes_float4, tri + 1);
317  f2 = kernel_data_fetch(attributes_float4, tri + 2);
318  }
319  else {
321  color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, tri + 0)));
323  color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, tri + 1)));
325  color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, tri + 2)));
326  }
327  }
328 
329 #ifdef __RAY_DIFFERENTIALS__
330  if (dx)
331  *dx = sd->du.dx * f1 + sd->dv.dx * f2 - (sd->du.dx + sd->dv.dx) * f0;
332  if (dy)
333  *dy = sd->du.dy * f1 + sd->dv.dy * f2 - (sd->du.dy + sd->dv.dy) * f0;
334 #endif
335 
336  return sd->u * f1 + sd->v * f2 + (1.0f - sd->u - sd->v) * f0;
337  }
338  else {
339 #ifdef __RAY_DIFFERENTIALS__
340  if (dx)
341  *dx = zero_float4();
342  if (dy)
343  *dy = zero_float4();
344 #endif
345 
347  const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
348  desc.offset;
349  return kernel_data_fetch(attributes_float4, offset);
350  }
351  else {
352  return zero_float4();
353  }
354  }
355 }
356 
_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 v1
float float4[4]
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_inline
Definition: cuda/compat.h:34
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_device_inline void object_inverse_normal_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *N)
ShaderData
Definition: kernel/types.h:925
@ SD_OBJECT_TRANSFORM_APPLIED
Definition: kernel/types.h:808
@ SD_OBJECT_NEGATIVE_SCALE_APPLIED
Definition: kernel/types.h:810
@ ATTR_ELEMENT_CORNER_BYTE
Definition: kernel/types.h:605
@ ATTR_ELEMENT_CORNER
Definition: kernel/types.h:604
@ ATTR_ELEMENT_OBJECT
Definition: kernel/types.h:599
@ ATTR_ELEMENT_VERTEX_MOTION
Definition: kernel/types.h:603
@ ATTR_ELEMENT_VERTEX
Definition: kernel/types.h:602
@ ATTR_ELEMENT_FACE
Definition: kernel/types.h:601
@ ATTR_ELEMENT_MESH
Definition: kernel/types.h:600
ccl_device_inline float2 safe_normalize(const float2 &a)
Definition: math_float2.h:201
ccl_device_inline float4 zero_float4()
Definition: math_float4.h:92
static float P(float k)
Definition: math_interp.c:25
#define N
#define make_float2(x, y)
Definition: metal/compat.h:203
#define make_float3(x, y, z)
Definition: metal/compat.h:204
vec_base< T, 3 > cross(const vec_base< T, 3 > &a, const vec_base< T, 3 > &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
bool is_zero(const T &a)
AttributeElement element
Definition: kernel/types.h:656
uint x
Definition: types_uint4.h:15
uint y
Definition: types_uint4.h:15
uint z
Definition: types_uint4.h:15
uint w
Definition: types_uint4.h:15
ccl_device float triangle_attribute_float(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float *dx, ccl_private float *dy)
Definition: triangle.h:146
CCL_NAMESPACE_BEGIN ccl_device_inline float3 triangle_normal(KernelGlobals kg, ccl_private ShaderData *sd)
Definition: triangle.h:15
ccl_device float2 triangle_attribute_float2(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float2 *dx, ccl_private float2 *dy)
Definition: triangle.h:196
ccl_device float4 triangle_attribute_float4(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float4 *dx, ccl_private float4 *dy)
Definition: triangle.h:296
ccl_device_inline float3 triangle_smooth_normal(KernelGlobals kg, float3 Ng, int prim, float u, float v)
Definition: triangle.h:92
ccl_device_inline void triangle_point_normal(KernelGlobals kg, int object, int prim, float u, float v, ccl_private float3 *P, ccl_private float3 *Ng, ccl_private int *shader)
Definition: triangle.h:33
ccl_device_inline void triangle_vertices(KernelGlobals kg, int prim, float3 P[3])
Definition: triangle.h:65
ccl_device_inline void triangle_vertices_and_normals(KernelGlobals kg, int prim, float3 P[3], float3 N[3])
Definition: triangle.h:75
ccl_device_inline float3 triangle_smooth_normal_unnormalized(KernelGlobals kg, ccl_private const ShaderData *sd, float3 Ng, int prim, float u, float v)
Definition: triangle.h:105
ccl_device_inline void triangle_dPdudv(KernelGlobals kg, int prim, ccl_private float3 *dPdu, ccl_private float3 *dPdv)
Definition: triangle.h:128
ccl_device float3 triangle_attribute_float3(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float3 *dx, ccl_private float3 *dy)
Definition: triangle.h:246
ccl_device_inline float4 color_uchar4_to_float4(uchar4 c)
Definition: util/color.h:50
ccl_device float4 color_srgb_to_linear_v4(float4 c)
Definition: util/color.h:302