215
215
float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state, float difl, float extmax)
217
217
float epsilon = 0.0f;
218
int depth = kernel_data.curve_kernel_data.subdivisions;
220
/* curve Intersection check */
221
float3 dir = 1.0f/idir;
220
int depth = kernel_data.curve.subdivisions;
221
int flags = kernel_data.curve.curveflags;
222
int prim = kernel_tex_fetch(__prim_index, curveAddr);
223
int flags = kernel_data.curve_kernel_data.curveflags;
225
int prim = kernel_tex_fetch(__prim_index, curveAddr);
227
224
float3 curve_coef[4];
230
/*obtain curve parameters*/
226
/* curve Intersection check */
227
float3 dir = 1.0f/idir;
229
/* obtain curve parameters */
232
/*ray transform created - this should be created at beginning of intersection loop*/
231
/* ray transform created - this should be created at beginning of intersection loop */
234
233
float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
235
234
htfm = make_transform(
271
270
if((flags & CURVE_KN_RIBBONS) || !(flags & CURVE_KN_BACKFACING))
272
271
epsilon = 2 * r_curr;
274
/*find bounds - this is slow for cubic curves*/
273
/* find bounds - this is slow for cubic curves */
277
276
float zextrem[4];
278
277
curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
279
278
if(lower - r_curr > isect->t || upper + r_curr < epsilon)
282
/*minimum width extension*/
281
/* minimum width extension */
283
282
float mw_extension = min(difl * fabsf(upper), extmax);
284
283
float r_ext = mw_extension + r_curr;
369
368
w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
370
369
w = clamp((float)w, 0.0f, 1.0f);
372
/* compute u on the curve segment.*/
371
/* compute u on the curve segment */
373
372
u = i_st * (1 - w) + i_en * w;
374
373
r_curr = r_st + (r_en - r_st) * u;
375
/* compare x-y distances.*/
374
/* compare x-y distances */
376
375
float3 p_curr = ((curve_coef[3] * u + curve_coef[2]) * u + curve_coef[1]) * u + curve_coef[0];
378
377
float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
479
478
w = clamp((float)w, 0.0f, 1.0f);
480
/* compute u on the curve segment.*/
479
/* compute u on the curve segment */
481
480
u = i_st * (1 - w) + i_en * w;
482
481
r_curr = r1 + (r2 - r1) * w;
483
482
r_ext = or1 + (or2 - or1) * w;
484
483
coverage = r_curr/r_ext;
487
/* we found a new intersection.*/
486
/* we found a new intersection */
489
/*stochastic fade from minimum width*/
488
/* stochastic fade from minimum width */
490
489
if(lcg_state && coverage != 1.0f) {
491
if(lcg_step(lcg_state) > coverage)
490
if(lcg_step_float(lcg_state) > coverage)
525
524
float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state, float difl, float extmax)
527
526
/* curve Intersection check */
528
int flags = kernel_data.curve_kernel_data.curveflags;
527
int flags = kernel_data.curve.curveflags;
530
529
int prim = kernel_tex_fetch(__prim_index, curveAddr);
531
530
float4 v00 = kernel_tex_fetch(__curves, prim);
690
689
* only want to intersect with primitives in the same object, and if case of
691
690
* multiple hits we pick a single random primitive as the intersection point. */
693
__device_inline bool bvh_triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect,
694
float3 P, float3 idir, int object, int triAddr, float tmax, int *num_hits, float subsurface_random)
692
__device_inline void bvh_triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect_array,
693
float3 P, float3 idir, int object, int triAddr, float tmax, uint *num_hits, uint *lcg_state, int max_hits)
696
695
/* compute and check intersection t-value */
697
696
float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0);
718
717
if(v >= 0.0f && u + v <= 1.0f) {
721
if(subsurface_random * (*num_hits) <= 1.0f) {
722
/* record intersection */
723
isect->prim = triAddr;
724
isect->object = object;
722
if(*num_hits <= max_hits) {
726
/* reservoir sampling: if we are at the maximum number of
727
* hits, randomly replace element or skip it */
728
hit = lcg_step_uint(lcg_state) % *num_hits;
734
/* record intersection */
735
Intersection *isect = &isect_array[hit];
736
isect->prim = triAddr;
737
isect->object = object;
774
782
#if defined(__SUBSURFACE__)
775
783
#define BVH_FUNCTION_NAME bvh_intersect_subsurface
776
#define BVH_FUNCTION_FEATURES BVH_SUBSURFACE
777
#include "kernel_bvh_traversal.h"
784
#define BVH_FUNCTION_FEATURES 0
785
#include "kernel_bvh_subsurface.h"
780
788
#if defined(__SUBSURFACE__) && defined(__INSTANCING__)
781
789
#define BVH_FUNCTION_NAME bvh_intersect_subsurface_instancing
782
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_SUBSURFACE
783
#include "kernel_bvh_traversal.h"
790
#define BVH_FUNCTION_FEATURES BVH_INSTANCING
791
#include "kernel_bvh_subsurface.h"
786
794
#if defined(__SUBSURFACE__) && defined(__HAIR__)
787
795
#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair
788
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_SUBSURFACE|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH
789
#include "kernel_bvh_traversal.h"
796
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR
797
#include "kernel_bvh_subsurface.h"
792
800
#if defined(__SUBSURFACE__) && defined(__OBJECT_MOTION__)
793
801
#define BVH_FUNCTION_NAME bvh_intersect_subsurface_motion
794
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_SUBSURFACE|BVH_MOTION
795
#include "kernel_bvh_traversal.h"
802
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
803
#include "kernel_bvh_subsurface.h"
798
806
#if defined(__SUBSURFACE__) && defined(__HAIR__) && defined(__OBJECT_MOTION__)
799
807
#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair_motion
800
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_SUBSURFACE|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH|BVH_MOTION
801
#include "kernel_bvh_traversal.h"
808
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION
809
#include "kernel_bvh_subsurface.h"
812
/* to work around titan bug when using arrays instead of textures */
813
#if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
806
__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect, uint *lcg_state, float difl, float extmax)
819
bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect, uint *lcg_state, float difl, float extmax)
808
__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
821
bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
811
824
#ifdef __OBJECT_MOTION__
843
856
#endif /* __KERNEL_CPU__ */
859
/* to work around titan bug when using arrays instead of textures */
846
860
#ifdef __SUBSURFACE__
847
__device_inline int scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection *isect, int subsurface_object, float subsurface_random)
861
#if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
866
uint scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection *isect, int subsurface_object, uint *lcg_state, int max_hits)
849
868
#ifdef __OBJECT_MOTION__
850
869
if(kernel_data.bvh.have_motion) {
852
871
if(kernel_data.bvh.have_curves)
853
return bvh_intersect_subsurface_hair_motion(kg, ray, isect, subsurface_object, subsurface_random);
872
return bvh_intersect_subsurface_hair_motion(kg, ray, isect, subsurface_object, lcg_state, max_hits);
854
873
#endif /* __HAIR__ */
856
return bvh_intersect_subsurface_motion(kg, ray, isect, subsurface_object, subsurface_random);
875
return bvh_intersect_subsurface_motion(kg, ray, isect, subsurface_object, lcg_state, max_hits);
858
877
#endif /* __OBJECT_MOTION__ */
861
880
if(kernel_data.bvh.have_curves)
862
return bvh_intersect_subsurface_hair(kg, ray, isect, subsurface_object, subsurface_random);
881
return bvh_intersect_subsurface_hair(kg, ray, isect, subsurface_object, lcg_state, max_hits);
863
882
#endif /* __HAIR__ */
865
884
#ifdef __KERNEL_CPU__
867
886
#ifdef __INSTANCING__
868
887
if(kernel_data.bvh.have_instancing)
869
return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, subsurface_random);
888
return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, lcg_state, max_hits);
870
889
#endif /* __INSTANCING__ */
872
return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, subsurface_random);
891
return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, lcg_state, max_hits);
873
892
#else /* __KERNEL_CPU__ */
875
894
#ifdef __INSTANCING__
876
return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, subsurface_random);
895
return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, lcg_state, max_hits);
878
return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, subsurface_random);
897
return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, lcg_state, max_hits);
879
898
#endif /* __INSTANCING__ */
881
900
#endif /* __KERNEL_CPU__ */
1002
/* same as above, except that isect->t is assumed to be in object space for instancing */
1003
__device_inline float3 bvh_triangle_refine_subsurface(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
1009
#ifdef __INTERSECTION_REFINE__
1010
if(isect->object != ~0) {
1011
#ifdef __OBJECT_MOTION__
1012
Transform tfm = sd->ob_itfm;
1014
Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
1017
P = transform_point(&tfm, P);
1018
D = transform_direction(&tfm, D);
1024
float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0);
1025
float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
1026
float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z);
1027
float rt = Oz * invDz;
1031
if(isect->object != ~0) {
1032
#ifdef __OBJECT_MOTION__
1033
Transform tfm = sd->ob_tfm;
1035
Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
1038
P = transform_point(&tfm, P);
985
1049
__device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3)
1098
1158
sd->N = sd->Ng;
1100
1160
if (flag & CURVE_KN_TANGENTGNORMAL && !(flag & CURVE_KN_TRUETANGENTGNORMAL)) {
1101
sd->N = -(D - tg * (dot(tg,D) * kernel_data.curve_kernel_data.normalmix));
1161
sd->N = -(D - tg * dot(tg,D));
1102
1162
sd->N = normalize(sd->N);
1103
if (flag & CURVE_KN_NORMALCORRECTION) {
1104
sd->N = sd->N - gd * tg;
1105
sd->N = normalize(sd->N);
1108
1164
if (!(flag & CURVE_KN_TANGENTGNORMAL) && flag & CURVE_KN_TRUETANGENTGNORMAL) {
1109
1165
sd->N = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd);