Blender  V3.3
cycles/kernel/bvh/util.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
7 
9 {
10  /* NOTE: Due to some vectorization code non-finite origin point might
11  * cause lots of false-positive intersections which will overflow traversal
12  * stack.
13  * This code is a quick way to perform early output, to avoid crashes in
14  * such cases.
15  * From production scenes so far it seems it's enough to test first element
16  * only.
17  * Scene intersection may also called with empty rays for conditional trace
18  * calls that evaluate to false, so filter those out.
19  */
20  return isfinite_safe(ray->P.x) && isfinite_safe(ray->D.x) && len_squared(ray->D) != 0.0f;
21 }
22 
23 /* Offset intersection distance by the smallest possible amount, to skip
24  * intersections at this distance. This works in cases where the ray start
25  * position is unchanged and only tmin is updated, since for self
26  * intersection we'll be comparing against the exact same distances. */
28 {
29  /* This is a simplified version of `nextafterf(t, FLT_MAX)`, only dealing with
30  * non-negative and finite t. */
31  kernel_assert(t >= 0.0f && isfinite_safe(t));
32  const uint32_t bits = (t == 0.0f) ? 1 : __float_as_uint(t) + 1;
33  return __uint_as_float(bits);
34 }
35 
36 /* Ray offset to avoid self intersection.
37  *
38  * This function can be used to compute a modified ray start position for rays
39  * leaving from a surface. This is from:
40  * "A Fast and Robust Method for Avoiding Self-Intersection"
41  * Ray Tracing Gems, chapter 6.
42  */
44 {
45  const float int_scale = 256.0f;
46  const int3 of_i = make_int3(
47  (int)(int_scale * Ng.x), (int)(int_scale * Ng.y), (int)(int_scale * Ng.z));
48 
49  const float3 p_i = make_float3(
50  __int_as_float(__float_as_int(P.x) + ((P.x < 0) ? -of_i.x : of_i.x)),
51  __int_as_float(__float_as_int(P.y) + ((P.y < 0) ? -of_i.y : of_i.y)),
52  __int_as_float(__float_as_int(P.z) + ((P.z < 0) ? -of_i.z : of_i.z)));
53  const float origin = 1.0f / 32.0f;
54  const float float_scale = 1.0f / 65536.0f;
55  return make_float3(fabsf(P.x) < origin ? P.x + float_scale * Ng.x : p_i.x,
56  fabsf(P.y) < origin ? P.y + float_scale * Ng.y : p_i.y,
57  fabsf(P.z) < origin ? P.z + float_scale * Ng.z : p_i.z);
58 }
59 
60 #ifndef __KERNEL_GPU__
61 ccl_device int intersections_compare(const void *a, const void *b)
62 {
63  const Intersection *isect_a = (const Intersection *)a;
64  const Intersection *isect_b = (const Intersection *)b;
65 
66  if (isect_a->t < isect_b->t)
67  return -1;
68  else if (isect_a->t > isect_b->t)
69  return 1;
70  else
71  return 0;
72 }
73 #endif
74 
75 /* For subsurface scattering, only sorting a small amount of intersections
76  * so bubble sort is fine for CPU and GPU. */
78  ccl_private float3 *Ng,
79  uint num_hits)
80 {
81  bool swapped;
82  do {
83  swapped = false;
84  for (int j = 0; j < num_hits - 1; ++j) {
85  if (hits[j].t > hits[j + 1].t) {
86  Intersection tmp_hit = hits[j];
87  float3 tmp_Ng = Ng[j];
88  hits[j] = hits[j + 1];
89  Ng[j] = Ng[j + 1];
90  hits[j + 1] = tmp_hit;
91  Ng[j + 1] = tmp_Ng;
92  swapped = true;
93  }
94  }
95  --num_hits;
96  } while (swapped);
97 }
98 
99 /* Utility to quickly get flags from an intersection. */
100 
102  const int prim,
103  const int type)
104 {
105  int shader = 0;
106 
107  if (type & PRIMITIVE_TRIANGLE) {
108  shader = kernel_data_fetch(tri_shader, prim);
109  }
110 #ifdef __POINTCLOUD__
111  else if (type & PRIMITIVE_POINT) {
112  shader = kernel_data_fetch(points_shader, prim);
113  }
114 #endif
115 #ifdef __HAIR__
116  else if (type & PRIMITIVE_CURVE) {
117  shader = kernel_data_fetch(curves, prim).shader_id;
118  }
119 #endif
120 
121  return kernel_data_fetch(shaders, (shader & SHADER_MASK)).flags;
122 }
123 
125  const int prim,
126  const int isect_type)
127 {
128  int shader = 0;
129 
130  if (isect_type & PRIMITIVE_TRIANGLE) {
131  shader = kernel_data_fetch(tri_shader, prim);
132  }
133 #ifdef __POINTCLOUD__
134  else if (isect_type & PRIMITIVE_POINT) {
135  shader = kernel_data_fetch(points_shader, prim);
136  }
137 #endif
138 #ifdef __HAIR__
139  else if (isect_type & PRIMITIVE_CURVE) {
140  shader = kernel_data_fetch(curves, prim).shader_id;
141  }
142 #endif
143 
144  return shader & SHADER_MASK;
145 }
146 
149 {
150  return intersection_get_shader_from_isect_prim(kg, isect->prim, isect->type);
151 }
152 
155 {
156  return kernel_data_fetch(object_flag, isect->object);
157 }
158 
159 /* TODO: find a better (faster) solution for this. Maybe store offset per object for
160  * attributes needed in intersection? */
162  const int object,
163  const uint id)
164 {
165  uint attr_offset = kernel_data_fetch(objects, object).attribute_map_offset;
166  AttributeMap attr_map = kernel_data_fetch(attributes_map, attr_offset);
167 
168  while (attr_map.id != id) {
169  if (UNLIKELY(attr_map.id == ATTR_STD_NONE)) {
170  if (UNLIKELY(attr_map.element == 0)) {
171  return (int)ATTR_STD_NOT_FOUND;
172  }
173  else {
174  /* Chain jump to a different part of the table. */
175  attr_offset = attr_map.offset;
176  }
177  }
178  else {
179  attr_offset += ATTR_PRIM_TYPES;
180  }
181  attr_map = kernel_data_fetch(attributes_map, attr_offset);
182  }
183 
184  /* return result */
185  return (attr_map.element == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.offset;
186 }
187 
188 /* Transparent Shadows */
189 
190 /* Cut-off value to stop transparent shadow tracing when practically opaque. */
191 #define CURVE_SHADOW_TRANSPARENCY_CUTOFF 0.001f
192 
194  KernelGlobals kg, const int object, const int prim, const int type, const float u)
195 {
196  /* Find attribute. */
198  if (offset == ATTR_STD_NOT_FOUND) {
199  /* If no shadow transparency attribute, assume opaque. */
200  return 0.0f;
201  }
202 
203  /* Interpolate transparency between curve keys. */
204  const KernelCurve kcurve = kernel_data_fetch(curves, prim);
205  const int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(type);
206  const int k1 = k0 + 1;
207 
208  const float f0 = kernel_data_fetch(attributes_float, offset + k0);
209  const float f1 = kernel_data_fetch(attributes_float, offset + k1);
210 
211  return (1.0f - u) * f0 + u * f1;
212 }
213 
215  const int object,
216  const int prim)
217 {
218  return (self.prim == prim) && (self.object == object);
219 }
220 
222  const int object,
223  const int prim)
224 {
225  return ((self.prim == prim) && (self.object == object)) ||
226  ((self.light_prim == prim) && (self.light_object == object));
227 }
228 
230  const int prim)
231 {
232  return (self.prim == prim);
233 }
234 
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNLIKELY(x)
_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 type
_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 t
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
#define kernel_assert(cond)
Definition: cpu/compat.h:34
#define ccl_restrict
Definition: cuda/compat.h:50
#define ccl_device_forceinline
Definition: cuda/compat.h:35
#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
ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals kg, const int prim, const int type)
ccl_device_inline void sort_intersections_and_normals(ccl_private Intersection *hits, ccl_private float3 *Ng, uint num_hits)
ccl_device_forceinline int intersection_get_object_flags(KernelGlobals kg, ccl_private const Intersection *ccl_restrict isect)
ccl_device_inline bool intersection_skip_self_local(ccl_private const RaySelfPrimitives &self, const int prim)
ccl_device_forceinline float intersection_t_offset(const float t)
ccl_device int intersections_compare(const void *a, const void *b)
ccl_device_forceinline int intersection_get_shader(KernelGlobals kg, ccl_private const Intersection *ccl_restrict isect)
ccl_device_inline float intersection_curve_shadow_transparency(KernelGlobals kg, const int object, const int prim, const int type, const float u)
ccl_device_inline int intersection_find_attribute(KernelGlobals kg, const int object, const uint id)
ccl_device_inline bool intersection_skip_self_shadow(ccl_private const RaySelfPrimitives &self, const int object, const int prim)
ccl_device_inline float3 ray_offset(const float3 P, const float3 Ng)
ccl_device_inline bool intersection_skip_self(ccl_private const RaySelfPrimitives &self, const int object, const int prim)
CCL_NAMESPACE_BEGIN ccl_device_inline bool intersection_ray_valid(ccl_private const Ray *ray)
ccl_device_forceinline int intersection_get_shader_from_isect_prim(KernelGlobals kg, const int prim, const int isect_type)
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
@ PRIMITIVE_CURVE
Definition: kernel/types.h:564
@ PRIMITIVE_TRIANGLE
Definition: kernel/types.h:551
@ PRIMITIVE_POINT
Definition: kernel/types.h:554
@ ATTR_STD_NOT_FOUND
Definition: kernel/types.h:647
@ ATTR_STD_NONE
Definition: kernel/types.h:613
@ ATTR_STD_SHADOW_TRANSPARENCY
Definition: kernel/types.h:644
#define PRIMITIVE_UNPACK_SEGMENT(type)
Definition: kernel/types.h:579
@ SHADER_MASK
Definition: kernel/types.h:449
@ ATTR_ELEMENT_NONE
Definition: kernel/types.h:598
@ ATTR_PRIM_TYPES
Definition: kernel/types.h:594
ccl_device_inline float len_squared(const float3 a)
Definition: math_float3.h:423
static float P(float k)
Definition: math_interp.c:25
#define fabsf(x)
Definition: metal/compat.h:219
#define make_int3(x, y, z)
Definition: metal/compat.h:207
#define make_float3(x, y, z)
Definition: metal/compat.h:204
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
unsigned int uint32_t
Definition: stdint.h:80
float z
float y
float x
ccl_device_inline float __uint_as_float(uint i)
Definition: util/math.h:273
ccl_device_inline uint __float_as_uint(float f)
Definition: util/math.h:263
ccl_device_inline int __float_as_int(float f)
Definition: util/math.h:243
ccl_device_inline bool isfinite_safe(float f)
Definition: util/math.h:353
ccl_device_inline float __int_as_float(int i)
Definition: util/math.h:253