Merge branch 'master' into blender2.8
This commit is contained in:
@@ -190,16 +190,25 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
|
||||
return false;
|
||||
}
|
||||
#ifdef __EMBREE__
|
||||
if(kernel_data.bvh.scene != NULL) {
|
||||
return embree_scene_intersect(kg, ray, visibility, isect);
|
||||
if(kernel_data.bvh.scene) {
|
||||
isect->t = ray.t;
|
||||
CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR);
|
||||
IntersectContext rtc_ctx(&ctx);
|
||||
RTCRayHit ray_hit;
|
||||
kernel_embree_setup_rayhit(ray, ray_hit, visibility);
|
||||
rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit);
|
||||
if(ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID && ray_hit.hit.primID != RTC_INVALID_GEOMETRY_ID) {
|
||||
kernel_embree_convert_hit(kg, &ray_hit.ray, &ray_hit.hit, isect);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif /* __EMBREE__ */
|
||||
#ifdef __OBJECT_MOTION__
|
||||
if(kernel_data.bvh.have_motion) {
|
||||
# ifdef __HAIR__
|
||||
if(kernel_data.bvh.have_curves)
|
||||
return bvh_intersect_hair_motion(
|
||||
kg, &ray, isect, visibility, lcg_state, difl, extmax);
|
||||
return bvh_intersect_hair_motion(kg, &ray, isect, visibility, lcg_state, difl, extmax);
|
||||
# endif /* __HAIR__ */
|
||||
|
||||
return bvh_intersect_motion(kg, &ray, isect, visibility);
|
||||
@@ -208,8 +217,7 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
|
||||
|
||||
#ifdef __HAIR__
|
||||
if(kernel_data.bvh.have_curves)
|
||||
return bvh_intersect_hair(
|
||||
kg, &ray, isect, visibility, lcg_state, difl, extmax);
|
||||
return bvh_intersect_hair(kg, &ray, isect, visibility, lcg_state, difl, extmax);
|
||||
#endif /* __HAIR__ */
|
||||
|
||||
#ifdef __KERNEL_CPU__
|
||||
@@ -244,19 +252,70 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg,
|
||||
return false;
|
||||
}
|
||||
#ifdef __EMBREE__
|
||||
if(kernel_data.bvh.scene != NULL) {
|
||||
return embree_scene_intersect_local(
|
||||
kg, ray, local_isect, local_object, lcg_state, max_hits);
|
||||
if(kernel_data.bvh.scene) {
|
||||
CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SSS);
|
||||
ctx.lcg_state = lcg_state;
|
||||
ctx.max_hits = max_hits;
|
||||
ctx.ss_isect = local_isect;
|
||||
local_isect->num_hits = 0;
|
||||
ctx.sss_object_id = local_object;
|
||||
IntersectContext rtc_ctx(&ctx);
|
||||
RTCRay rtc_ray;
|
||||
kernel_embree_setup_ray(ray, rtc_ray, PATH_RAY_ALL_VISIBILITY);
|
||||
|
||||
/* Get the Embree scene for this intersection. */
|
||||
RTCGeometry geom = rtcGetGeometry(kernel_data.bvh.scene, local_object * 2);
|
||||
if(geom) {
|
||||
float3 P = ray.P;
|
||||
float3 dir = ray.D;
|
||||
float3 idir = ray.D;
|
||||
const int object_flag = kernel_tex_fetch(__object_flag, local_object);
|
||||
if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||
Transform ob_itfm;
|
||||
rtc_ray.tfar = bvh_instance_motion_push(kg,
|
||||
local_object,
|
||||
&ray,
|
||||
&P,
|
||||
&dir,
|
||||
&idir,
|
||||
ray.t,
|
||||
&ob_itfm);
|
||||
/* bvh_instance_motion_push() returns the inverse transform but
|
||||
* it's not needed here. */
|
||||
(void) ob_itfm;
|
||||
|
||||
rtc_ray.org_x = P.x;
|
||||
rtc_ray.org_y = P.y;
|
||||
rtc_ray.org_z = P.z;
|
||||
rtc_ray.dir_x = dir.x;
|
||||
rtc_ray.dir_y = dir.y;
|
||||
rtc_ray.dir_z = dir.z;
|
||||
}
|
||||
RTCScene scene = (RTCScene)rtcGetGeometryUserData(geom);
|
||||
if(scene) {
|
||||
rtcOccluded1(scene, &rtc_ctx.context, &rtc_ray);
|
||||
}
|
||||
}
|
||||
|
||||
return local_isect->num_hits > 0;
|
||||
}
|
||||
#endif /* __EMBREE__ */
|
||||
#ifdef __OBJECT_MOTION__
|
||||
if(kernel_data.bvh.have_motion) {
|
||||
return bvh_intersect_local_motion(
|
||||
kg, &ray, local_isect, local_object, lcg_state, max_hits);
|
||||
return bvh_intersect_local_motion(kg,
|
||||
&ray,
|
||||
local_isect,
|
||||
local_object,
|
||||
lcg_state,
|
||||
max_hits);
|
||||
}
|
||||
#endif /* __OBJECT_MOTION__ */
|
||||
return bvh_intersect_local(
|
||||
kg, &ray, local_isect, local_object, lcg_state, max_hits);
|
||||
return bvh_intersect_local(kg,
|
||||
&ray,
|
||||
local_isect,
|
||||
local_object,
|
||||
lcg_state,
|
||||
max_hits);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -272,41 +331,73 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
|
||||
return false;
|
||||
}
|
||||
# ifdef __EMBREE__
|
||||
if(kernel_data.bvh.scene != NULL) {
|
||||
return embree_scene_intersect_shadow_all(
|
||||
kg, ray, isect, max_hits, num_hits);
|
||||
if(kernel_data.bvh.scene) {
|
||||
CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SHADOW_ALL);
|
||||
ctx.isect_s = isect;
|
||||
ctx.max_hits = max_hits;
|
||||
ctx.num_hits = 0;
|
||||
IntersectContext rtc_ctx(&ctx);
|
||||
RTCRay rtc_ray;
|
||||
kernel_embree_setup_ray(*ray, rtc_ray, PATH_RAY_SHADOW);
|
||||
rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
|
||||
|
||||
if(ctx.num_hits > max_hits) {
|
||||
return true;
|
||||
}
|
||||
*num_hits = ctx.num_hits;
|
||||
return rtc_ray.tfar == -INFINITY;
|
||||
}
|
||||
# endif
|
||||
# ifdef __OBJECT_MOTION__
|
||||
if(kernel_data.bvh.have_motion) {
|
||||
# ifdef __HAIR__
|
||||
if(kernel_data.bvh.have_curves) {
|
||||
return bvh_intersect_shadow_all_hair_motion(
|
||||
kg, ray, isect, visibility, max_hits, num_hits);
|
||||
return bvh_intersect_shadow_all_hair_motion(kg,
|
||||
ray,
|
||||
isect,
|
||||
visibility,
|
||||
max_hits,
|
||||
num_hits);
|
||||
}
|
||||
# endif /* __HAIR__ */
|
||||
|
||||
return bvh_intersect_shadow_all_motion(
|
||||
kg, ray, isect, visibility, max_hits, num_hits);
|
||||
return bvh_intersect_shadow_all_motion(kg,
|
||||
ray,
|
||||
isect,
|
||||
visibility,
|
||||
max_hits,
|
||||
num_hits);
|
||||
}
|
||||
# endif /* __OBJECT_MOTION__ */
|
||||
|
||||
# ifdef __HAIR__
|
||||
if(kernel_data.bvh.have_curves) {
|
||||
return bvh_intersect_shadow_all_hair(
|
||||
kg, ray, isect, visibility, max_hits, num_hits);
|
||||
return bvh_intersect_shadow_all_hair(kg,
|
||||
ray,
|
||||
isect,
|
||||
visibility,
|
||||
max_hits,
|
||||
num_hits);
|
||||
}
|
||||
# endif /* __HAIR__ */
|
||||
|
||||
# ifdef __INSTANCING__
|
||||
if(kernel_data.bvh.have_instancing) {
|
||||
return bvh_intersect_shadow_all_instancing(
|
||||
kg, ray, isect, visibility, max_hits, num_hits);
|
||||
return bvh_intersect_shadow_all_instancing(kg,
|
||||
ray,
|
||||
isect,
|
||||
visibility,
|
||||
max_hits,
|
||||
num_hits);
|
||||
}
|
||||
# endif /* __INSTANCING__ */
|
||||
|
||||
return bvh_intersect_shadow_all(
|
||||
kg, ray, isect, visibility, max_hits, num_hits);
|
||||
return bvh_intersect_shadow_all(kg,
|
||||
ray,
|
||||
isect,
|
||||
visibility,
|
||||
max_hits,
|
||||
num_hits);
|
||||
}
|
||||
#endif /* __SHADOW_RECORD_ALL__ */
|
||||
|
||||
@@ -351,21 +442,26 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
|
||||
return false;
|
||||
}
|
||||
# ifdef __EMBREE__
|
||||
if(kernel_data.bvh.scene != NULL) {
|
||||
return embree_scene_intersect_volume_all(
|
||||
kg, ray, isect, max_hits, visibility);
|
||||
if(kernel_data.bvh.scene) {
|
||||
CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_VOLUME_ALL);
|
||||
ctx.isect_s = isect;
|
||||
ctx.max_hits = max_hits;
|
||||
ctx.num_hits = 0;
|
||||
IntersectContext rtc_ctx(&ctx);
|
||||
RTCRay rtc_ray;
|
||||
kernel_embree_setup_ray(*ray, rtc_ray, visibility);
|
||||
rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
|
||||
return rtc_ray.tfar == -INFINITY;
|
||||
}
|
||||
# endif
|
||||
# ifdef __OBJECT_MOTION__
|
||||
if(kernel_data.bvh.have_motion) {
|
||||
return bvh_intersect_volume_all_motion(
|
||||
kg, ray, isect, max_hits, visibility);
|
||||
return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility);
|
||||
}
|
||||
# endif /* __OBJECT_MOTION__ */
|
||||
# ifdef __INSTANCING__
|
||||
if(kernel_data.bvh.have_instancing)
|
||||
return bvh_intersect_volume_all_instancing(
|
||||
kg, ray, isect, max_hits, visibility);
|
||||
return bvh_intersect_volume_all_instancing(kg, ray, isect, max_hits, visibility);
|
||||
# endif /* __INSTANCING__ */
|
||||
return bvh_intersect_volume_all(kg, ray, isect, max_hits, visibility);
|
||||
}
|
||||
|
||||
@@ -71,9 +71,7 @@ public:
|
||||
CCLIntersectContext* userRayExt;
|
||||
};
|
||||
|
||||
ccl_device_inline void kernel_embree_setup_ray(const Ray& ray,
|
||||
RTCRay& rtc_ray,
|
||||
const uint visibility)
|
||||
ccl_device_inline void kernel_embree_setup_ray(const Ray& ray, RTCRay& rtc_ray, const uint visibility)
|
||||
{
|
||||
rtc_ray.org_x = ray.P.x;
|
||||
rtc_ray.org_y = ray.P.y;
|
||||
@@ -87,19 +85,14 @@ ccl_device_inline void kernel_embree_setup_ray(const Ray& ray,
|
||||
rtc_ray.mask = visibility;
|
||||
}
|
||||
|
||||
ccl_device_inline void kernel_embree_setup_rayhit(const Ray& ray,
|
||||
RTCRayHit& rayhit,
|
||||
const uint visibility)
|
||||
ccl_device_inline void kernel_embree_setup_rayhit(const Ray& ray, RTCRayHit& rayhit, const uint visibility)
|
||||
{
|
||||
kernel_embree_setup_ray(ray, rayhit.ray, visibility);
|
||||
rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
|
||||
rayhit.hit.primID = RTC_INVALID_GEOMETRY_ID;
|
||||
}
|
||||
|
||||
ccl_device_inline void kernel_embree_convert_hit(KernelGlobals *kg,
|
||||
const RTCRay *ray,
|
||||
const RTCHit *hit,
|
||||
Intersection *isect)
|
||||
ccl_device_inline void kernel_embree_convert_hit(KernelGlobals *kg, const RTCRay *ray, const RTCHit *hit, Intersection *isect)
|
||||
{
|
||||
bool is_hair = hit->geomID & 1;
|
||||
isect->u = is_hair ? hit->u : 1.0f - hit->v - hit->u;
|
||||
@@ -107,161 +100,27 @@ ccl_device_inline void kernel_embree_convert_hit(KernelGlobals *kg,
|
||||
isect->t = ray->tfar;
|
||||
isect->Ng = make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z);
|
||||
if(hit->instID[0] != RTC_INVALID_GEOMETRY_ID) {
|
||||
RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData(
|
||||
rtcGetGeometry(kernel_data.bvh.scene, hit->instID[0]));
|
||||
isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(
|
||||
rtcGetGeometry(inst_scene, hit->geomID)) +
|
||||
kernel_tex_fetch(__object_node, hit->instID[0]/2);
|
||||
RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData(rtcGetGeometry(kernel_data.bvh.scene, hit->instID[0]));
|
||||
isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID)) + kernel_tex_fetch(__object_node, hit->instID[0]/2);
|
||||
isect->object = hit->instID[0]/2;
|
||||
}
|
||||
else {
|
||||
isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(
|
||||
rtcGetGeometry(kernel_data.bvh.scene, hit->geomID));
|
||||
isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(kernel_data.bvh.scene, hit->geomID));
|
||||
isect->object = OBJECT_NONE;
|
||||
}
|
||||
isect->type = kernel_tex_fetch(__prim_type, isect->prim);
|
||||
}
|
||||
|
||||
ccl_device_inline void kernel_embree_convert_local_hit(KernelGlobals *kg,
|
||||
const RTCRay *ray,
|
||||
const RTCHit *hit,
|
||||
Intersection *isect,
|
||||
int local_object_id)
|
||||
ccl_device_inline void kernel_embree_convert_local_hit(KernelGlobals *kg, const RTCRay *ray, const RTCHit *hit, Intersection *isect, int local_object_id)
|
||||
{
|
||||
isect->u = 1.0f - hit->v - hit->u;
|
||||
isect->v = hit->u;
|
||||
isect->t = ray->tfar;
|
||||
isect->Ng = make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z);
|
||||
RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData(
|
||||
rtcGetGeometry(kernel_data.bvh.scene, local_object_id * 2));
|
||||
isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(
|
||||
rtcGetGeometry(inst_scene, hit->geomID)) +
|
||||
kernel_tex_fetch(__object_node, local_object_id);
|
||||
RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData(rtcGetGeometry(kernel_data.bvh.scene, local_object_id * 2));
|
||||
isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID)) + kernel_tex_fetch(__object_node, local_object_id);
|
||||
isect->object = local_object_id;
|
||||
isect->type = kernel_tex_fetch(__prim_type, isect->prim);
|
||||
}
|
||||
|
||||
ccl_device_inline bool embree_scene_intersect(KernelGlobals *kg,
|
||||
const Ray *ray,
|
||||
const uint visibility,
|
||||
Intersection *isect)
|
||||
{
|
||||
kernel_assert(kernel_data.bvh.scene != NULL);
|
||||
isect->t = ray->t;
|
||||
CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR);
|
||||
IntersectContext rtc_ctx(&ctx);
|
||||
RTCRayHit ray_hit;
|
||||
kernel_embree_setup_rayhit(*ray, ray_hit, visibility);
|
||||
rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit);
|
||||
if(ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID &&
|
||||
ray_hit.hit.primID != RTC_INVALID_GEOMETRY_ID)
|
||||
{
|
||||
kernel_embree_convert_hit(kg, &ray_hit.ray, &ray_hit.hit, isect);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __BVH_LOCAL__
|
||||
ccl_device_inline bool embree_scene_intersect_local(
|
||||
KernelGlobals *kg,
|
||||
const Ray ray,
|
||||
LocalIntersection *local_isect,
|
||||
int local_object,
|
||||
uint *lcg_state,
|
||||
int max_hits)
|
||||
{
|
||||
kernel_assert(kernel_data.bvh.scene != NULL);
|
||||
CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SSS);
|
||||
ctx.lcg_state = lcg_state;
|
||||
ctx.max_hits = max_hits;
|
||||
ctx.ss_isect = local_isect;
|
||||
local_isect->num_hits = 0;
|
||||
ctx.sss_object_id = local_object;
|
||||
IntersectContext rtc_ctx(&ctx);
|
||||
RTCRay rtc_ray;
|
||||
kernel_embree_setup_ray(ray, rtc_ray, PATH_RAY_ALL_VISIBILITY);
|
||||
/* Get the Embree scene for this intersection. */
|
||||
RTCGeometry geom = rtcGetGeometry(kernel_data.bvh.scene, local_object * 2);
|
||||
if(geom) {
|
||||
float3 P = ray.P;
|
||||
float3 dir = ray.D;
|
||||
float3 idir = ray.D;
|
||||
const int object_flag = kernel_tex_fetch(__object_flag, local_object);
|
||||
if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||
Transform ob_itfm;
|
||||
rtc_ray.tfar = bvh_instance_motion_push(kg,
|
||||
local_object,
|
||||
&ray,
|
||||
&P,
|
||||
&dir,
|
||||
&idir,
|
||||
ray.t,
|
||||
&ob_itfm);
|
||||
/* bvh_instance_motion_push() returns the inverse transform but
|
||||
* it's not needed here. */
|
||||
(void) ob_itfm;
|
||||
|
||||
rtc_ray.org_x = P.x;
|
||||
rtc_ray.org_y = P.y;
|
||||
rtc_ray.org_z = P.z;
|
||||
rtc_ray.dir_x = dir.x;
|
||||
rtc_ray.dir_y = dir.y;
|
||||
rtc_ray.dir_z = dir.z;
|
||||
}
|
||||
RTCScene scene = (RTCScene)rtcGetGeometryUserData(geom);
|
||||
if(scene) {
|
||||
rtcOccluded1(scene, &rtc_ctx.context, &rtc_ray);
|
||||
}
|
||||
}
|
||||
return local_isect->num_hits > 0;
|
||||
}
|
||||
#endif /* __BVH_LOCAL__ */
|
||||
|
||||
#ifdef __SHADOW_RECORD_ALL__
|
||||
ccl_device_inline bool embree_scene_intersect_shadow_all(
|
||||
KernelGlobals *kg,
|
||||
const Ray *ray,
|
||||
Intersection *isect,
|
||||
uint max_hits,
|
||||
uint *num_hits)
|
||||
{
|
||||
kernel_assert(kernel_data.bvh.scene != NULL);
|
||||
CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SHADOW_ALL);
|
||||
ctx.isect_s = isect;
|
||||
ctx.max_hits = max_hits;
|
||||
ctx.num_hits = 0;
|
||||
IntersectContext rtc_ctx(&ctx);
|
||||
RTCRay rtc_ray;
|
||||
kernel_embree_setup_ray(*ray, rtc_ray, PATH_RAY_SHADOW);
|
||||
rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
|
||||
if(ctx.num_hits > max_hits) {
|
||||
return true;
|
||||
}
|
||||
*num_hits = ctx.num_hits;
|
||||
return rtc_ray.tfar == -INFINITY;
|
||||
}
|
||||
#endif /* __SHADOW_RECORD_ALL__ */
|
||||
|
||||
#ifdef __VOLUME_RECORD_ALL__
|
||||
ccl_device_inline uint embree_scene_intersect_volume_all(
|
||||
KernelGlobals *kg,
|
||||
const Ray *ray,
|
||||
Intersection *isect,
|
||||
const uint max_hits,
|
||||
const uint visibility)
|
||||
{
|
||||
kernel_assert(kernel_data.bvh.scene != NULL);
|
||||
CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_VOLUME_ALL);
|
||||
ctx.isect_s = isect;
|
||||
ctx.max_hits = max_hits;
|
||||
ctx.num_hits = 0;
|
||||
IntersectContext rtc_ctx(&ctx);
|
||||
RTCRay rtc_ray;
|
||||
kernel_embree_setup_ray(*ray, rtc_ray, visibility);
|
||||
rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
|
||||
return rtc_ray.tfar == -INFINITY;
|
||||
}
|
||||
#endif /* __VOLUME_RECORD_ALL__ */
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
Reference in New Issue
Block a user