diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-12-25 20:40:02 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-12-25 20:40:02 +0300 |
commit | cd095aae139ecbcfdf2103f635eae8d5bc5f3b8e (patch) | |
tree | 655ab197b47b076e8903f586ad22c061e5215abe /intern/cycles/kernel/geom/geom_object.h | |
parent | 30e3aa1561ef0b2b1fdebc343b628b6bbf6365c5 (diff) |
Cycles: Distance optimization for QBVH
This commit implements heuristic which allows to skip nodes pushed to the stack
from intersection if distance to them is larger than the distance to the current
intersection.
This should solve speed regression which i didn't notice in the original QBVH
commit (which could have because i had WIP version of this patch applied in my
local branch).
From quick tests speed seems to be much closer to what is was with regular BVH.
There's still some possible code cleanup, but they'll need a bit of assembly
code check and now i want to make it so artists can happily use Cycles over the
holidays.
Diffstat (limited to 'intern/cycles/kernel/geom/geom_object.h')
-rw-r--r-- | intern/cycles/kernel/geom/geom_object.h | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index 91edd5863ac..79a56683454 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -391,6 +391,38 @@ ccl_device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ra *t *= len; } +#ifdef __QBVH__ +/* Same as above, but optimized for QBVH scene intersection, + * which needs to modify two max distances. + * + * TODO(sergey): Investigate if passing NULL instead of t1 gets optimized + * so we can avoid having this duplication. + */ +ccl_device_inline void qbvh_instance_push(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float *t, + float *t1) +{ + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + + *P = transform_point(&tfm, ray->P); + + float len; + *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len)); + *idir = bvh_inverse_direction(*dir); + + if(*t != FLT_MAX) + *t *= len; + + if(*t1 != -FLT_MAX) + *t1 *= len; +} +#endif + /* Transorm ray to exit static object in BVH */ ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t) @@ -436,6 +468,33 @@ ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, c *t *= len; } +#ifdef __QBVH__ +/* Same as above, but optimized for QBVH scene intersection, + * which needs to modify two max distances. + * + * TODO(sergey): Investigate if passing NULL instead of t1 gets optimized + * so we can avoid having this duplication. + */ +ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, float *t1, Transform *tfm) +{ + Transform itfm; + *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm); + + *P = transform_point(&itfm, ray->P); + + float len; + *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len)); + *idir = bvh_inverse_direction(*dir); + + + if(*t != FLT_MAX) + *t *= len; + + if(*t1 != -FLT_MAX) + *t1 *= len; +} +#endif + /* Transorm ray to exit motion blurred object in BVH */ ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, Transform *tfm) |