Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2021-04-15 17:36:35 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-04-19 22:07:34 +0300
commitb42454be8bf08381a4c3578e6a4bdfaec0471586 (patch)
tree83ff65a6d1418a75805293481fd698b33e7dd9b0 /intern/cycles
parent68cbf0a2be8a6636ab3c05aa1d48b17b29e6f791 (diff)
Cleanup: move BVH utility functions into own file
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/kernel/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/bvh/bvh.h98
-rw-r--r--intern/cycles/kernel/bvh/bvh_shadow_all.h19
-rw-r--r--intern/cycles/kernel/bvh/bvh_util.h162
4 files changed, 168 insertions, 112 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index f6b4b963a7a..ea0f16c9233 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -93,6 +93,7 @@ set(SRC_BVH_HEADERS
bvh/bvh_local.h
bvh/bvh_traversal.h
bvh/bvh_types.h
+ bvh/bvh_util.h
bvh/bvh_volume.h
bvh/bvh_volume_all.h
bvh/bvh_embree.h
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h
index 3049f243ae9..3a3f38539c5 100644
--- a/intern/cycles/kernel/bvh/bvh.h
+++ b/intern/cycles/kernel/bvh/bvh.h
@@ -29,9 +29,10 @@
# include "kernel/bvh/bvh_embree.h"
#endif
-CCL_NAMESPACE_BEGIN
-
#include "kernel/bvh/bvh_types.h"
+#include "kernel/bvh/bvh_util.h"
+
+CCL_NAMESPACE_BEGIN
#ifndef __KERNEL_OPTIX__
@@ -533,97 +534,4 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
}
#endif /* __VOLUME_RECORD_ALL__ */
-/* Ray offset to avoid self intersection.
- *
- * This function should be used to compute a modified ray start position for
- * rays leaving from a surface. */
-
-ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
-{
-#ifdef __INTERSECTION_REFINE__
- const float epsilon_f = 1e-5f;
- /* ideally this should match epsilon_f, but instancing and motion blur
- * precision makes it problematic */
- const float epsilon_test = 1.0f;
- const int epsilon_i = 32;
-
- float3 res;
-
- /* x component */
- if (fabsf(P.x) < epsilon_test) {
- res.x = P.x + Ng.x * epsilon_f;
- }
- else {
- uint ix = __float_as_uint(P.x);
- ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i;
- res.x = __uint_as_float(ix);
- }
-
- /* y component */
- if (fabsf(P.y) < epsilon_test) {
- res.y = P.y + Ng.y * epsilon_f;
- }
- else {
- uint iy = __float_as_uint(P.y);
- iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i;
- res.y = __uint_as_float(iy);
- }
-
- /* z component */
- if (fabsf(P.z) < epsilon_test) {
- res.z = P.z + Ng.z * epsilon_f;
- }
- else {
- uint iz = __float_as_uint(P.z);
- iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i;
- res.z = __uint_as_float(iz);
- }
-
- return res;
-#else
- const float epsilon_f = 1e-4f;
- return P + epsilon_f * Ng;
-#endif
-}
-
-#if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__))
-/* ToDo: Move to another file? */
-ccl_device int intersections_compare(const void *a, const void *b)
-{
- const Intersection *isect_a = (const Intersection *)a;
- const Intersection *isect_b = (const Intersection *)b;
-
- if (isect_a->t < isect_b->t)
- return -1;
- else if (isect_a->t > isect_b->t)
- return 1;
- else
- return 0;
-}
-#endif
-
-#if defined(__SHADOW_RECORD_ALL__)
-ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits)
-{
-# ifdef __KERNEL_GPU__
- /* Use bubble sort which has more friendly memory pattern on GPU. */
- bool swapped;
- do {
- swapped = false;
- for (int j = 0; j < num_hits - 1; ++j) {
- if (hits[j].t > hits[j + 1].t) {
- struct Intersection tmp = hits[j];
- hits[j] = hits[j + 1];
- hits[j + 1] = tmp;
- swapped = true;
- }
- }
- --num_hits;
- } while (swapped);
-# else
- qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
-# endif
-}
-#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h
index dccd257d2de..2e94b1d7c37 100644
--- a/intern/cycles/kernel/bvh/bvh_shadow_all.h
+++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h
@@ -180,25 +180,10 @@ ccl_device_inline
/* todo: optimize so primitive visibility flag indicates if
* the primitive has a transparent shadow shader? */
- int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
- int shader = 0;
-
-#ifdef __HAIR__
- if (kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
-#endif
- {
- shader = kernel_tex_fetch(__tri_shader, prim);
- }
-#ifdef __HAIR__
- else {
- float4 str = kernel_tex_fetch(__curves, prim);
- shader = __float_as_int(str.z);
- }
-#endif
- int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+ const int flags = intersection_get_shader_flags(kg, isect_array);
/* if no transparent shadows, all light is blocked */
- if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
+ if (!(flags & SD_HAS_TRANSPARENT_SHADOW)) {
return true;
}
/* if maximum number of hits reached, block all light */
diff --git a/intern/cycles/kernel/bvh/bvh_util.h b/intern/cycles/kernel/bvh/bvh_util.h
new file mode 100644
index 00000000000..a694e4dc259
--- /dev/null
+++ b/intern/cycles/kernel/bvh/bvh_util.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2011-2013 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+CCL_NAMESPACE_BEGIN
+
+/* Ray offset to avoid self intersection.
+ *
+ * This function should be used to compute a modified ray start position for
+ * rays leaving from a surface. */
+
+ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
+{
+#ifdef __INTERSECTION_REFINE__
+ const float epsilon_f = 1e-5f;
+ /* ideally this should match epsilon_f, but instancing and motion blur
+ * precision makes it problematic */
+ const float epsilon_test = 1.0f;
+ const int epsilon_i = 32;
+
+ float3 res;
+
+ /* x component */
+ if (fabsf(P.x) < epsilon_test) {
+ res.x = P.x + Ng.x * epsilon_f;
+ }
+ else {
+ uint ix = __float_as_uint(P.x);
+ ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i;
+ res.x = __uint_as_float(ix);
+ }
+
+ /* y component */
+ if (fabsf(P.y) < epsilon_test) {
+ res.y = P.y + Ng.y * epsilon_f;
+ }
+ else {
+ uint iy = __float_as_uint(P.y);
+ iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i;
+ res.y = __uint_as_float(iy);
+ }
+
+ /* z component */
+ if (fabsf(P.z) < epsilon_test) {
+ res.z = P.z + Ng.z * epsilon_f;
+ }
+ else {
+ uint iz = __float_as_uint(P.z);
+ iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i;
+ res.z = __uint_as_float(iz);
+ }
+
+ return res;
+#else
+ const float epsilon_f = 1e-4f;
+ return P + epsilon_f * Ng;
+#endif
+}
+
+#if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__))
+/* ToDo: Move to another file? */
+ccl_device int intersections_compare(const void *a, const void *b)
+{
+ const Intersection *isect_a = (const Intersection *)a;
+ const Intersection *isect_b = (const Intersection *)b;
+
+ if (isect_a->t < isect_b->t)
+ return -1;
+ else if (isect_a->t > isect_b->t)
+ return 1;
+ else
+ return 0;
+}
+#endif
+
+#if defined(__SHADOW_RECORD_ALL__)
+ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits)
+{
+ kernel_assert(num_hits > 0);
+
+# ifdef __KERNEL_GPU__
+ /* Use bubble sort which has more friendly memory pattern on GPU. */
+ bool swapped;
+ do {
+ swapped = false;
+ for (int j = 0; j < num_hits - 1; ++j) {
+ if (hits[j].t > hits[j + 1].t) {
+ struct Intersection tmp = hits[j];
+ hits[j] = hits[j + 1];
+ hits[j + 1] = tmp;
+ swapped = true;
+ }
+ }
+ --num_hits;
+ } while (swapped);
+# else
+ qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
+# endif
+}
+#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
+
+/* Utility to quickly get a shader flags from an intersection. */
+
+ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals *ccl_restrict kg,
+ const Intersection *isect)
+{
+ const int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ int shader = 0;
+
+#ifdef __HAIR__
+ if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE)
+#endif
+ {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
+#ifdef __HAIR__
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+#endif
+
+ return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+}
+
+ccl_device_forceinline int intersection_get_shader(KernelGlobals *ccl_restrict kg,
+ const Intersection *isect)
+{
+ const int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ int shader = 0;
+
+#ifdef __HAIR__
+ if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE)
+#endif
+ {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
+#ifdef __HAIR__
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+#endif
+
+ return shader & SHADER_MASK;
+}
+
+CCL_NAMESPACE_END