From 207338bb58b1a44c531e6d78fad68672c6d3b2e1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 18 Feb 2020 20:54:41 +0100 Subject: Cycles: port curve-ray intersection from Embree for use in Cycles GPU This keeps render results compatible for combined CPU + GPU rendering. Peformance and quality primitives is quite different than before. There are now two options: * Rounded Ribbon: render hair as flat ribbon with (fake) rounded normals, for fast rendering. Hair curves are subdivided with a fixed number of user specified subdivisions. This gives relatively good results, especially when used with the Principled Hair BSDF and hair viewed from a typical distance. There are artifacts when viewed closed up, though this was also the case with all previous primitives (but different ones). * 3D Curve: render hair as 3D curve, for accurate results when viewing hair close up. This automatically subdivides the curve until it is smooth. This gives higher quality than any of the previous primitives, but does come at a performance cost and is somewhat slower than our previous Thick curves. The main problem here is performance. For CPU and OpenCL rendering performance seems usually quite close or better for similar quality results. However for CUDA and Optix, performance of 3D curve intersection is problematic, with e.g. 1.45x longer render time in Koro (though there is no equivalent quality and rounded ribbons seem fine for that scene). Any help or ideas to optimize this are welcome. Ref T73778 Depends on D8012 Maniphest Tasks: T73778 Differential Revision: https://developer.blender.org/D8013 --- intern/cycles/kernel/kernels/optix/kernel_optix.cu | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'intern/cycles/kernel/kernels') diff --git a/intern/cycles/kernel/kernels/optix/kernel_optix.cu b/intern/cycles/kernel/kernels/optix/kernel_optix.cu index 59fece73b3c..c730d952ed4 100644 --- a/intern/cycles/kernel/kernels/optix/kernel_optix.cu +++ b/intern/cycles/kernel/kernels/optix/kernel_optix.cu @@ -256,11 +256,9 @@ extern "C" __global__ void __closesthit__kernel_optix_hit() } #ifdef __HAIR__ -extern "C" __global__ void __intersection__curve() +ccl_device_inline void optix_intersection_curve(const uint prim, const uint type) { - const uint prim = optixGetPrimitiveIndex(); const uint object = get_object_id(); - const uint type = kernel_tex_fetch(__prim_type, prim); const uint visibility = optixGetPayload_4(); float3 P = optixGetObjectRayOrigin(); @@ -288,6 +286,24 @@ extern "C" __global__ void __intersection__curve() __float_as_int(isect.u), // Attribute_0 __float_as_int(isect.v)); // Attribute_1 } + +} + +extern "C" __global__ void __intersection__curve_ribbon() +{ + const uint prim = optixGetPrimitiveIndex(); + const uint type = kernel_tex_fetch(__prim_type, prim); + + if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) { + optix_intersection_curve(prim, type); + } +} + +extern "C" __global__ void __intersection__curve_all() +{ + const uint prim = optixGetPrimitiveIndex(); + const uint type = kernel_tex_fetch(__prim_type, prim); + optix_intersection_curve(prim, type); } #endif -- cgit v1.2.3