diff options
author | Brecht Van Lommel <brecht@blender.org> | 2021-12-01 19:30:46 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2021-12-16 22:54:04 +0300 |
commit | 35b1e9fc3acd6db565e7e54252a4a4152d8343d9 (patch) | |
tree | 8599df3b2be192d1fe19d30a8afb7e8d8729499e /intern/cycles/kernel/device | |
parent | 2229179faa44e2c685b4eabd0c51d4c7d5c1f193 (diff) |
Cycles: pointcloud rendering
This add support for rendering of the point cloud object in Blender, as a native
geometry type in Cycles that is more memory and time efficient than instancing
sphere meshes. This can be useful for rendering sand, water splashes, particles,
motion graphics, etc.
Points are currently always rendered as spheres, with backface culling. More
shapes are likely to be added later, but this is the most important one and can
be customized with shaders.
For CPU rendering the Embree primitive is used, for GPU there is our own
intersection code. Motion blur is suppored. Volumes inside points are not
currently supported.
Implemented with help from:
* Kévin Dietrich: Alembic procedural integration
* Patrick Mourse: OptiX integration
* Josh Whelchel: update for cycles-x changes
Ref T92573
Differential Revision: https://developer.blender.org/D9887
Diffstat (limited to 'intern/cycles/kernel/device')
-rw-r--r-- | intern/cycles/kernel/device/optix/kernel.cu | 64 |
1 files changed, 58 insertions, 6 deletions
diff --git a/intern/cycles/kernel/device/optix/kernel.cu b/intern/cycles/kernel/device/optix/kernel.cu index c9a48315544..c639dc87f35 100644 --- a/intern/cycles/kernel/device/optix/kernel.cu +++ b/intern/cycles/kernel/device/optix/kernel.cu @@ -97,9 +97,9 @@ extern "C" __global__ void __miss__kernel_optix_miss() extern "C" __global__ void __anyhit__kernel_optix_local_hit() { -#ifdef __HAIR__ +#if defined(__HAIR__) || defined(__POINTCLOUD__) if (!optixIsTriangleHit()) { - /* Ignore curves. */ + /* Ignore curves and points. */ return optixIgnoreIntersection(); } #endif @@ -194,7 +194,7 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit() type = kernel_tex_fetch(__objects, object).primitive_type; } # ifdef __HAIR__ - else { + else if (optixGetHitKind() & PRIMITIVE_ALL_CURVE) { u = __uint_as_float(optixGetAttribute_0()); v = __uint_as_float(optixGetAttribute_1()); @@ -210,6 +210,11 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit() # endif } # endif + else { + type = kernel_tex_fetch(__objects, object).primitive_type; + u = 0.0f; + v = 0.0f; + } # ifndef __TRANSPARENT_SHADOWS__ /* No transparent shadows support compiled in, make opaque. */ @@ -291,7 +296,7 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit() extern "C" __global__ void __anyhit__kernel_optix_volume_test() { -#ifdef __HAIR__ +#if defined(__HAIR__) || defined(__POINTCLOUD__) if (!optixIsTriangleHit()) { /* Ignore curves. */ return optixIgnoreIntersection(); @@ -315,7 +320,7 @@ extern "C" __global__ void __anyhit__kernel_optix_visibility_test() { #ifdef __HAIR__ # if OPTIX_ABI_VERSION < 55 - if (!optixIsTriangleHit()) { + if (optixGetHitKind() & PRIMITIVE_ALL_CURVE) { /* Filter out curve endcaps. */ const float u = __uint_as_float(optixGetAttribute_0()); if (u == 0.0f || u == 1.0f) { @@ -354,13 +359,19 @@ extern "C" __global__ void __closesthit__kernel_optix_hit() optixSetPayload_3(prim); optixSetPayload_5(kernel_tex_fetch(__objects, object).primitive_type); } - else { + else if (optixGetHitKind() & PRIMITIVE_ALL_CURVE) { const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, prim); optixSetPayload_1(optixGetAttribute_0()); /* Same as 'optixGetCurveParameter()' */ optixSetPayload_2(optixGetAttribute_1()); optixSetPayload_3(segment.prim); optixSetPayload_5(segment.type); } + else { + optixSetPayload_1(0); + optixSetPayload_2(0); + optixSetPayload_3(prim); + optixSetPayload_5(kernel_tex_fetch(__objects, object).primitive_type); + } } #ifdef __HAIR__ @@ -411,4 +422,45 @@ extern "C" __global__ void __intersection__curve_ribbon() optix_intersection_curve(prim, type); } } + +#endif + +#ifdef __POINTCLOUD__ +extern "C" __global__ void __intersection__point() +{ + const int prim = optixGetPrimitiveIndex(); + const int object = get_object_id(); + const int type = kernel_tex_fetch(__objects, object).primitive_type; + +# ifdef __VISIBILITY_FLAG__ + const uint visibility = optixGetPayload_4(); + if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) { + return; + } +# endif + + float3 P = optixGetObjectRayOrigin(); + float3 dir = optixGetObjectRayDirection(); + + /* The direction is not normalized by default, the point intersection routine expects that. */ + float len; + dir = normalize_len(dir, &len); + +# ifdef __OBJECT_MOTION__ + const float time = optixGetRayTime(); +# else + const float time = 0.0f; +# endif + + Intersection isect; + isect.t = optixGetRayTmax(); + /* Transform maximum distance into object space. */ + if (isect.t != FLT_MAX) { + isect.t *= len; + } + + if (point_intersect(NULL, &isect, P, dir, isect.t, object, prim, time, type)) { + optixReportIntersection(isect.t / len, type & PRIMITIVE_ALL); + } +} #endif |