light: support embree4 in addition to 3
This commit is contained in:
parent
d5ffbd9d33
commit
db0951dc40
|
|
@ -145,6 +145,11 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
|
|||
|
||||
find_package(TBB REQUIRED)
|
||||
|
||||
find_package(embree REQUIRED)
|
||||
if (embree_VERSION_MAJOR EQUAL 4)
|
||||
add_compile_definitions(HAVE_EMBREE4)
|
||||
endif()
|
||||
|
||||
set(TEST_QUAKE_MAP_EXPORT_DIR "" CACHE PATH "When running unit tests, export Quake maps to this directory (useful for testing in game)")
|
||||
set(TEST_QUAKE2_MAP_EXPORT_DIR "" CACHE PATH "When running unit tests, export Quake 2 maps to this directory (useful for testing in game)")
|
||||
set(TEST_HEXEN2_MAP_EXPORT_DIR "" CACHE PATH "When running unit tests, export Hexen 2 maps to this directory (useful for testing in game)")
|
||||
|
|
|
|||
|
|
@ -100,8 +100,13 @@ public:
|
|||
inline void clearPushedRays() { _numrays = 0; }
|
||||
};
|
||||
|
||||
#ifdef HAVE_EMBREE4
|
||||
#include <embree4/rtcore.h>
|
||||
#include <embree4/rtcore_ray.h>
|
||||
#else
|
||||
#include <embree3/rtcore.h>
|
||||
#include <embree3/rtcore_ray.h>
|
||||
#endif
|
||||
|
||||
extern RTCScene scene;
|
||||
|
||||
|
|
@ -139,13 +144,22 @@ inline RTCRayHit SetupRay(unsigned rayindex, const qvec3d &start, const qvec3d &
|
|||
|
||||
class light_t;
|
||||
|
||||
struct ray_source_info : public RTCIntersectContext
|
||||
struct ray_source_info : public
|
||||
#ifdef HAVE_EMBREE4
|
||||
RTCRayQueryContext
|
||||
#else
|
||||
RTCIntersectContext
|
||||
#endif
|
||||
{
|
||||
raystream_embree_common_t *raystream; // may be null if this ray is not from a ray stream
|
||||
const modelinfo_t *self;
|
||||
int shadowmask;
|
||||
|
||||
ray_source_info(raystream_embree_common_t *raystream_, const modelinfo_t *self_, int shadowmask_);
|
||||
#ifdef HAVE_EMBREE4
|
||||
RTCIntersectArguments setup_intersection_arguments();
|
||||
RTCOccludedArguments setup_occluded_arguments();
|
||||
#endif
|
||||
};
|
||||
|
||||
struct triinfo
|
||||
|
|
@ -238,7 +252,14 @@ public:
|
|||
return;
|
||||
|
||||
ray_source_info ctx2(this, self, shadowmask);
|
||||
|
||||
#ifdef HAVE_EMBREE4
|
||||
RTCIntersectArguments embree4_args = ctx2.setup_intersection_arguments();
|
||||
for (int i = 0; i < _numrays; ++i)
|
||||
rtcIntersect1(scene, &_rays[i], &embree4_args);
|
||||
#else
|
||||
rtcIntersect1M(scene, &ctx2, _rays.data(), _numrays, sizeof(_rays[0]));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline qvec3d getPushedRayDir(size_t j) { return {_rays[j].ray.dir_x, _rays[j].ray.dir_y, _rays[j].ray.dir_z}; }
|
||||
|
|
@ -312,7 +333,13 @@ public:
|
|||
return;
|
||||
|
||||
ray_source_info ctx2(this, self, shadowmask);
|
||||
#ifdef HAVE_EMBREE4
|
||||
RTCOccludedArguments embree4_args = ctx2.setup_occluded_arguments();
|
||||
for (int i = 0; i < _numrays; ++i)
|
||||
rtcOccluded1(scene, &_rays[i], &embree4_args);
|
||||
#else
|
||||
rtcOccluded1M(scene, &ctx2, _rays.data(), _numrays, sizeof(_rays[0]));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool getPushedRayOccluded(size_t j) { return (_rays[j].tfar < 0.0f); }
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ set(LIGHT_SOURCES
|
|||
surflight.cc
|
||||
${LIGHT_INCLUDES})
|
||||
|
||||
FIND_PACKAGE(embree 3.0 REQUIRED)
|
||||
|
||||
if (embree_FOUND)
|
||||
MESSAGE(STATUS "Embree library found: ${EMBREE_LIBRARY}")
|
||||
INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRS})
|
||||
|
|
|
|||
|
|
@ -289,14 +289,13 @@ inline qvec3f Embree_RayEndpoint(RTCRayN *ray, const qvec3f &dir, size_t N, size
|
|||
return org + (dir * tfar);
|
||||
}
|
||||
|
||||
static void AddGlassToRay(RTCIntersectContext *context, unsigned rayIndex, float opacity, const qvec3d &glasscolor);
|
||||
static void AddDynamicOccluderToRay(RTCIntersectContext *context, unsigned rayIndex, int style);
|
||||
static void AddGlassToRay(ray_source_info *context, unsigned rayIndex, float opacity, const qvec3d &glasscolor);
|
||||
static void AddDynamicOccluderToRay(ray_source_info *context, unsigned rayIndex, int style);
|
||||
|
||||
// called to evaluate transparency
|
||||
static void Embree_FilterFuncN(const struct RTCFilterFunctionNArguments *args)
|
||||
{
|
||||
int *const valid = args->valid;
|
||||
RTCIntersectContext *const context = args->context;
|
||||
struct RTCRayN *const ray = args->ray;
|
||||
struct RTCHitN *const potentialHit = args->hit;
|
||||
const unsigned int N = args->N;
|
||||
|
|
@ -304,7 +303,7 @@ static void Embree_FilterFuncN(const struct RTCFilterFunctionNArguments *args)
|
|||
const int VALID = -1;
|
||||
const int INVALID = 0;
|
||||
|
||||
const ray_source_info *rsi = static_cast<const ray_source_info *>(context);
|
||||
ray_source_info *rsi = static_cast<ray_source_info *>(args->context);
|
||||
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
if (valid[i] != VALID) {
|
||||
|
|
@ -359,7 +358,7 @@ static void Embree_FilterFuncN(const struct RTCFilterFunctionNArguments *args)
|
|||
|
||||
const int style = hit_triinfo.switchshadstyle;
|
||||
|
||||
AddDynamicOccluderToRay(context, rayIndex, style);
|
||||
AddDynamicOccluderToRay(rsi, rayIndex, style);
|
||||
|
||||
// reject hit
|
||||
valid[i] = INVALID;
|
||||
|
|
@ -391,7 +390,7 @@ static void Embree_FilterFuncN(const struct RTCFilterFunctionNArguments *args)
|
|||
// only pick up the color of the glass on the _exiting_ side of the glass.
|
||||
// (we currently trace "backwards", from surface point --> light source)
|
||||
if (raySurfaceCosAngle < 0) {
|
||||
AddGlassToRay(context, rayIndex, alpha, sample.xyz() * (1.0 / 255.0));
|
||||
AddGlassToRay(rsi, rayIndex, alpha, sample.xyz() * (1.0 / 255.0));
|
||||
}
|
||||
|
||||
// reject hit
|
||||
|
|
@ -419,14 +418,13 @@ static void Embree_FilterFuncN(const struct RTCFilterFunctionNArguments *args)
|
|||
static void PerRay_FilterFuncN(const struct RTCFilterFunctionNArguments *args)
|
||||
{
|
||||
int *const valid = args->valid;
|
||||
RTCIntersectContext *const context = args->context;
|
||||
struct RTCHitN *const potentialHit = args->hit;
|
||||
const unsigned int N = args->N;
|
||||
|
||||
const int VALID = -1;
|
||||
const int INVALID = 0;
|
||||
|
||||
auto *rsi = static_cast<const ray_source_info *>(context);
|
||||
auto *rsi = static_cast<ray_source_info *>(args->context);
|
||||
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
if (valid[i] != VALID) {
|
||||
|
|
@ -656,9 +654,16 @@ void Embree_TraceInit(const mbsp_t *bsp)
|
|||
logging::funcprint("Embree version: {}.{}.{}\n", ver_maj, ver_min, ver_pat);
|
||||
|
||||
scene = rtcNewScene(device);
|
||||
#ifdef HAVE_EMBREE4
|
||||
// necessary for RTCOccludedArguments::filter and RTCIntersectArguments::filter
|
||||
// to work, which we use (see: ray_source_info::setup_intersection_arguments() and
|
||||
// ray_source_info::setup_occluded_arguments())
|
||||
rtcSetSceneFlags(scene, RTC_SCENE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS);
|
||||
#else
|
||||
// we're using RTCIntersectContext::filter so it's required that we set
|
||||
// RTC_SCENE_FLAG_CONTEXT_FILTER_FUNCTION
|
||||
rtcSetSceneFlags(scene, RTC_SCENE_FLAG_CONTEXT_FILTER_FUNCTION);
|
||||
#endif
|
||||
rtcSetSceneBuildQuality(scene, RTC_BUILD_QUALITY_HIGH);
|
||||
skygeom = CreateGeometry(bsp, device, scene, skyfaces);
|
||||
solidgeom = CreateGeometry(bsp, device, scene, solidfaces);
|
||||
|
|
@ -677,9 +682,8 @@ void Embree_TraceInit(const mbsp_t *bsp)
|
|||
logging::print("\t{} shadow-casting skip faces\n", skipwindings.size());
|
||||
}
|
||||
|
||||
static void AddGlassToRay(RTCIntersectContext *context, unsigned rayIndex, float opacity, const qvec3d &glasscolor)
|
||||
static void AddGlassToRay(ray_source_info *ctx, unsigned rayIndex, float opacity, const qvec3d &glasscolor)
|
||||
{
|
||||
ray_source_info *ctx = static_cast<ray_source_info *>(context);
|
||||
raystream_embree_common_t *rs = ctx->raystream;
|
||||
|
||||
if (rs == nullptr) {
|
||||
|
|
@ -698,9 +702,8 @@ static void AddGlassToRay(RTCIntersectContext *context, unsigned rayIndex, float
|
|||
rs->_ray_glass_opacity[rayIndex] = opacity;
|
||||
}
|
||||
|
||||
static void AddDynamicOccluderToRay(RTCIntersectContext *context, unsigned rayIndex, int style)
|
||||
static void AddDynamicOccluderToRay(ray_source_info *ctx, unsigned rayIndex, int style)
|
||||
{
|
||||
ray_source_info *ctx = static_cast<ray_source_info *>(context);
|
||||
raystream_embree_common_t *rs = ctx->raystream;
|
||||
|
||||
if (rs != nullptr) {
|
||||
|
|
@ -713,12 +716,51 @@ ray_source_info::ray_source_info(raystream_embree_common_t *raystream_, const mo
|
|||
self(self_),
|
||||
shadowmask(shadowmask_)
|
||||
{
|
||||
#ifdef HAVE_EMBREE4
|
||||
rtcInitRayQueryContext(this);
|
||||
#else
|
||||
rtcInitIntersectContext(this);
|
||||
|
||||
flags = RTC_INTERSECT_CONTEXT_FLAG_COHERENT;
|
||||
|
||||
if (shadowmask != CHANNEL_MASK_DEFAULT) {
|
||||
// non-default shadow mask means we have to use the slow path
|
||||
filter = PerRay_FilterFuncN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_EMBREE4
|
||||
RTCIntersectArguments ray_source_info::setup_intersection_arguments()
|
||||
{
|
||||
RTCIntersectArguments result;
|
||||
|
||||
rtcInitIntersectArguments(&result);
|
||||
if (shadowmask != CHANNEL_MASK_DEFAULT) {
|
||||
// non-default shadow mask means we have to use the slow path
|
||||
result.filter = PerRay_FilterFuncN;
|
||||
result.flags = static_cast<RTCRayQueryFlags>(result.flags |
|
||||
RTC_RAY_QUERY_FLAG_INVOKE_ARGUMENT_FILTER);
|
||||
}
|
||||
|
||||
result.context = this;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
RTCOccludedArguments ray_source_info::setup_occluded_arguments()
|
||||
{
|
||||
RTCOccludedArguments result;
|
||||
|
||||
rtcInitOccludedArguments(&result);
|
||||
if (shadowmask != CHANNEL_MASK_DEFAULT) {
|
||||
// non-default shadow mask means we have to use the slow path
|
||||
result.filter = PerRay_FilterFuncN;
|
||||
result.flags = static_cast<RTCRayQueryFlags>(result.flags |
|
||||
RTC_RAY_QUERY_FLAG_INVOKE_ARGUMENT_FILTER);
|
||||
}
|
||||
|
||||
result.context = this;
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -19,7 +19,6 @@ add_executable(lightpreview
|
|||
|
||||
set_target_properties(lightpreview PROPERTIES WIN32_EXECUTABLE YES)
|
||||
|
||||
find_package(embree 3.0 REQUIRED)
|
||||
INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRS})
|
||||
|
||||
# HACK: Windows embree .dll's from https://github.com/embree/embree/releases ship with a tbb12.dll
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ add_executable(tests
|
|||
benchmark.cc
|
||||
test_bsputil.cc)
|
||||
|
||||
find_package(embree 3.0 REQUIRED)
|
||||
INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRS})
|
||||
|
||||
# HACK: Windows embree .dll's from https://github.com/embree/embree/releases ship with a tbb12.dll
|
||||
|
|
|
|||
Loading…
Reference in New Issue