light: remove 65536 ray limit, fixes #276

This commit is contained in:
Eric Wasylishen 2019-10-28 01:12:23 -06:00
parent d7d797b898
commit 4456020b30
5 changed files with 81 additions and 199 deletions

View File

@ -62,10 +62,10 @@ class modelinfo_t;
class raystream_t {
public:
virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const modelinfo_t *modelinfo, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) = 0;
virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) = 0;
virtual size_t numPushedRays() = 0;
virtual void tracePushedRaysOcclusion() = 0;
virtual void tracePushedRaysIntersection() = 0;
virtual void tracePushedRaysOcclusion(const modelinfo_t *self) = 0;
virtual void tracePushedRaysIntersection(const modelinfo_t *self) = 0;
virtual bool getPushedRayOccluded(size_t j) = 0;
virtual float getPushedRayDist(size_t j) = 0;
virtual float getPushedRayHitDist(size_t j) = 0;
@ -79,11 +79,11 @@ public:
virtual void clearPushedRays() = 0;
virtual ~raystream_t() {};
void pushRay(int i, const qvec3f &origin, const qvec3f &dir, float dist, const modelinfo_t *modelinfo) {
void pushRay(int i, const qvec3f &origin, const qvec3f &dir, float dist) {
vec3_t originTemp, dirTemp;
glm_to_vec3_t(origin, originTemp);
glm_to_vec3_t(dir, dirTemp);
this->pushRay(i, originTemp, dirTemp, dist, modelinfo);
this->pushRay(i, originTemp, dirTemp, dist);
}
qvec3f getPushedRayDir(size_t j) {

View File

@ -1248,11 +1248,11 @@ void EstimateVisibleBoundsAtPoint(const vec3_t point, vec3_t mins, vec3_t maxs)
vec3_t dir;
UniformPointOnSphere(dir, u1, u2);
rs->pushRay(0, point, dir, 65536.0f, nullptr);
rs->pushRay(0, point, dir, 65536.0f);
}
}
rs->tracePushedRaysIntersection();
rs->tracePushedRaysIntersection(nullptr);
for (int i=0; i<N2; i++) {
const float dist = rs->getPushedRayHitDist(i);

View File

@ -1491,10 +1491,10 @@ LightFace_Entity(const mbsp_t *bsp,
continue;
}
rs->pushRay(i, surfpoint, surfpointToLightDir, surfpointToLightDist, modelinfo, color, normalcontrib);
rs->pushRay(i, surfpoint, surfpointToLightDir, surfpointToLightDist, color, normalcontrib);
}
rs->tracePushedRaysOcclusion();
rs->tracePushedRaysOcclusion(modelinfo);
total_light_rays += rs->numPushedRays();
int cached_style = entity->style.intValue();
@ -1594,10 +1594,10 @@ LightFace_Sky(const sun_t *sun, const lightsurf_t *lightsurf, lightmapdict_t *li
continue;
}
rs->pushRay(i, surfpoint, incoming, MAX_SKY_DIST, modelinfo, color, normalcontrib);
rs->pushRay(i, surfpoint, incoming, MAX_SKY_DIST, color, normalcontrib);
}
rs->tracePushedRaysIntersection();
rs->tracePushedRaysIntersection(modelinfo);
/* if sunlight is set, use a style 0 light map */
int cached_style = sun->style;
@ -1718,11 +1718,11 @@ LightFace_Min(const mbsp_t *bsp, const bsp2_dface_t *face,
vec3_t surfpointToLightDir;
const vec_t surfpointToLightDist = GetDir(surfpoint, *entity.origin.vec3Value(), surfpointToLightDir);
rs->pushRay(i, surfpoint, surfpointToLightDir, surfpointToLightDist, modelinfo);
rs->pushRay(i, surfpoint, surfpointToLightDir, surfpointToLightDist);
}
}
rs->tracePushedRaysOcclusion();
rs->tracePushedRaysOcclusion(modelinfo);
total_light_rays += rs->numPushedRays();
const int N = rs->numPushedRays();
@ -2002,14 +2002,14 @@ LightFace_Bounce(const mbsp_t *bsp, const bsp2_dface_t *face, const lightsurf_t
glm_to_vec3_t(dir, vplDir);
glm_to_vec3_t(indirect, vplColor);
rs->pushRay(i, vplPos, vplDir, dist, lightsurf->modelinfo, vplColor);
rs->pushRay(i, vplPos, vplDir, dist, vplColor);
}
if (!rs->numPushedRays())
continue;
total_bounce_rays += rs->numPushedRays();
rs->tracePushedRaysOcclusion();
rs->tracePushedRaysOcclusion(lightsurf->modelinfo);
lightmap_t *lightmap = Lightmap_ForStyle(lightmaps, style, lightsurf);
@ -2072,10 +2072,10 @@ LightFace_Bounce(const mbsp_t *bsp, const bsp2_dface_t *face, const lightsurf_t
//printf("bad dot\n");
}
rs->pushRay(i, surfpoint, rayDir, 8192, lightsurf->modelinfo);
rs->pushRay(i, surfpoint, rayDir, 8192);
}
rs->tracePushedRaysIntersection();
rs->tracePushedRaysIntersection(lightsurf->modelinfo);
qvec3f colorAvg(0);
int Nhits = 0;
@ -2200,14 +2200,14 @@ LightFace_SurfaceLight(const lightsurf_t *lightsurf, lightmapdict_t *lightmaps)
glm_to_vec3_t(dir, vplDir);
glm_to_vec3_t(indirect, vplColor);
rs->pushRay(i, vplPos, vplDir, dist, lightsurf->modelinfo, vplColor);
rs->pushRay(i, vplPos, vplDir, dist, vplColor);
}
if (!rs->numPushedRays())
continue;
total_surflight_rays += rs->numPushedRays();
rs->tracePushedRaysOcclusion();
rs->tracePushedRaysOcclusion(lightsurf->modelinfo);
const int lightmapstyle = 0;
lightmap_t *lightmap = Lightmap_ForStyle(lightmaps, lightmapstyle, lightsurf);
@ -2466,13 +2466,13 @@ DirtAtPoint(const globalconfig_t &cfg, raystream_t *rs, const vec3_t point, cons
vec3_t dir;
TransformToTangentSpace(normal, myUp, myRt, dirtvec, dir);
rs->pushRay(j, point, dir, cfg.dirtDepth.floatValue(), selfshadow);
rs->pushRay(j, point, dir, cfg.dirtDepth.floatValue());
}
Q_assert(rs->numPushedRays() == numDirtVectors);
// trace the batch
rs->tracePushedRaysIntersection();
rs->tracePushedRaysIntersection(selfshadow);
// accumulate hitdists
for (int j=0; j<numDirtVectors; j++) {
@ -2533,11 +2533,11 @@ LightFace_CalculateDirt(lightsurf_t *lightsurf)
vec3_t dir;
TransformToTangentSpace(lightsurf->normals[i], myUps[i], myRts[i], dirtvec, dir);
rs->pushRay(i, lightsurf->points[i], dir, cfg.dirtDepth.floatValue(), lightsurf->modelinfo);
rs->pushRay(i, lightsurf->points[i], dir, cfg.dirtDepth.floatValue());
}
// trace the batch
rs->tracePushedRaysIntersection();
rs->tracePushedRaysIntersection(lightsurf->modelinfo);
// accumulate hitdists
for (int k = 0; k < rs->numPushedRays(); k++) {

View File

@ -791,131 +791,9 @@ hittype_t DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const mod
throw; //mxd. Silences compiler warning
}
class bsp_ray_t {
public:
int _pointindex;
vec3_t _origin, _dir;
float _maxdist;
const dmodel_t *_selfshadow;
vec3_t _color;
vec3_t _normalcontrib;
// hit info
float _hitdist;
hittype_t _hittype;
const bsp2_dface_t *_hitface;
bool _hit_occluded;
bsp_ray_t(int i, const vec_t *origin, const vec3_t dir, float dist, const modelinfo_t *modelinfo, const vec_t *color, const vec_t *normalcontrib) :
_pointindex{i},
_maxdist{dist},
_selfshadow{ modelinfo != nullptr ? (modelinfo->shadowself.boolValue() ? modelinfo->model : nullptr) : nullptr },
_hitdist{dist},
_hittype{hittype_t::NONE},
_hitface(nullptr),
_hit_occluded{false} {
VectorCopy(origin, _origin);
VectorCopy(dir, _dir);
if (color != nullptr) {
VectorCopy(color, _color);
}
if (normalcontrib != nullptr) {
VectorCopy(normalcontrib, _normalcontrib);
}
}
};
class raystream_bsp_t : public raystream_t {
private:
std::vector<bsp_ray_t> _rays;
int _maxrays;
public:
raystream_bsp_t(int maxRays) :
_maxrays { maxRays } {}
raystream_bsp_t() {}
virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const modelinfo_t *modelinfo, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) {
bsp_ray_t r { i, origin, dir, dist, modelinfo, color, normalcontrib };
_rays.push_back(r);
Q_assert(_rays.size() <= _maxrays);
}
virtual size_t numPushedRays() {
return _rays.size();
}
virtual void tracePushedRaysOcclusion() {
if (!_rays.size())
return;
for (bsp_ray_t &ray : _rays) {
vec3_t stop;
VectorMA(ray._origin, ray._maxdist, ray._dir, stop);
ray._hit_occluded = !BSP_TestLight(ray._origin, stop, ray._selfshadow);
}
}
virtual void tracePushedRaysIntersection() {
if (!_rays.size())
return;
for (bsp_ray_t &ray : _rays) {
ray._hittype = BSP_DirtTrace(ray._origin, ray._dir, ray._maxdist, ray._selfshadow, &ray._hitdist, nullptr, &ray._hitface);
}
}
virtual bool getPushedRayOccluded(size_t j) {
return _rays.at(j)._hit_occluded;
}
virtual float getPushedRayDist(size_t j) {
return _rays.at(j)._maxdist;
}
virtual float getPushedRayHitDist(size_t j) {
return _rays.at(j)._hitdist;
}
virtual hittype_t getPushedRayHitType(size_t j) {
return _rays.at(j)._hittype;
}
virtual const bsp2_dface_t *getPushedRayHitFace(size_t j) {
return _rays.at(j)._hitface;
}
virtual void getPushedRayDir(size_t j, vec3_t out) {
for (int i=0; i<3; i++) {
out[i] = _rays.at(j)._dir[i];
}
}
virtual int getPushedRayPointIndex(size_t j) {
return _rays.at(j)._pointindex;
}
virtual void getPushedRayColor(size_t j, vec3_t out) {
VectorCopy(_rays.at(j)._color, out);
}
virtual void getPushedRayNormalContrib(size_t j, vec3_t out) {
VectorCopy(_rays.at(j)._normalcontrib, out);
}
virtual int getPushedRayDynamicStyle(size_t j) {
return 0; // not supported
}
virtual void clearPushedRays() {
_rays.clear();
}
};
raystream_t *BSP_MakeRayStream(int maxrays)
{
return new raystream_bsp_t{maxrays};
return nullptr;
}
raystream_t *MakeRayStream(int maxrays)

View File

@ -45,6 +45,18 @@ public:
std::vector<const modelinfo_t *> triToModelinfo;
};
class raystream_embree_t;
struct ray_source_info {
raystream_embree_t *raystream; // may be null if this ray is not from a ray stream
const modelinfo_t *self;
ray_source_info(raystream_embree_t *raystream_,
const modelinfo_t *self_) :
raystream(raystream_),
self(self_) {}
};
sceneinfo
CreateGeometry(const mbsp_t *bsp, RTCScene scene, const std::vector<const bsp2_dface_t *> &faces)
{
@ -224,15 +236,6 @@ void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float
void AddDynamicOccluderToRay(const RTCIntersectContext* context, unsigned rayIndex, int style);
static const unsigned RAYMASK_HASMODEL_SHIFT = 0;
static const unsigned RAYMASK_HASMODEL_MASK = (1 << RAYMASK_HASMODEL_SHIFT);
static const unsigned RAYMASK_MODELINDEX_SHIFT = 1;
static const unsigned RAYMASK_MODELINDEX_MASK = (0xffff << RAYMASK_MODELINDEX_SHIFT);
static const unsigned RAYMASK_RAYINDEX_SHIFT = 17;
static const unsigned RAYMASK_RAYINDEX_MASK = (0x7fff << RAYMASK_RAYINDEX_SHIFT);
// called to evaluate transparency
template<filtertype_t filtertype>
static void
@ -245,7 +248,9 @@ Embree_FilterFuncN(int* valid,
{
const int VALID = -1;
const int INVALID = 0;
const ray_source_info *rsi = static_cast<const ray_source_info *>(context->userRayExt);
for (size_t i=0; i<N; i++) {
if (valid[i] != VALID) {
// we only need to handle valid rays
@ -257,11 +262,9 @@ Embree_FilterFuncN(int* valid,
const unsigned &primID = RTCHitN_primID(potentialHit, N, i);
// unpack ray index
const bool hasmodel = static_cast<bool>((mask & RAYMASK_HASMODEL_MASK) >> RAYMASK_HASMODEL_SHIFT);
const unsigned raySourceModelindex = (mask & RAYMASK_MODELINDEX_MASK) >> RAYMASK_MODELINDEX_SHIFT;
const unsigned rayIndex = (mask & RAYMASK_RAYINDEX_MASK) >> RAYMASK_RAYINDEX_SHIFT;
const unsigned rayIndex = mask;
const modelinfo_t *source_modelinfo = hasmodel ? ModelInfoForModel(bsp_static, raySourceModelindex) : nullptr;
const modelinfo_t *source_modelinfo = rsi->self;
const modelinfo_t *hit_modelinfo = Embree_LookupModelinfo(geomID, primID);
Q_assert(hit_modelinfo != nullptr);
@ -686,7 +689,7 @@ Embree_TraceInit(const mbsp_t *bsp)
FreeWindings(skipwindings);
}
static RTCRay SetupRay(unsigned rayindex, const vec3_t start, const vec3_t dir, vec_t dist, const modelinfo_t *modelinfo)
static RTCRay SetupRay(unsigned rayindex, const vec3_t start, const vec3_t dir, vec_t dist)
{
RTCRay ray;
VectorCopy(start, ray.org);
@ -698,41 +701,26 @@ static RTCRay SetupRay(unsigned rayindex, const vec3_t start, const vec3_t dir,
ray.instID = RTC_INVALID_GEOMETRY_ID;
// NOTE: we are not using the ray masking feature of embree, but just using
// this field to store whether the ray is coming from self-shadow geometry
ray.mask = 0;
if (modelinfo) {
ray.mask |= RAYMASK_HASMODEL_MASK;
// Hacky..
const int modelindex = (modelinfo->model - bsp_static->dmodels);
Q_assert(modelindex >= 0 && modelindex < bsp_static->nummodels);
Q_assert(modelindex <= 65535);
ray.mask |= (static_cast<unsigned>(modelindex) << RAYMASK_MODELINDEX_SHIFT);
}
// pack the ray index into the rest of the mask
Q_assert(rayindex <= 32767);
ray.mask |= (rayindex << RAYMASK_RAYINDEX_SHIFT);
// this field to store the ray index
ray.mask = rayindex;
ray.time = 0.f;
return ray;
}
static RTCRay SetupRay_StartStop(const vec3_t start, const vec3_t stop, const modelinfo_t *self)
static RTCRay SetupRay_StartStop(const vec3_t start, const vec3_t stop)
{
vec3_t dir;
VectorSubtract(stop, start, dir);
vec_t dist = VectorNormalize(dir);
return SetupRay(0, start, dir, dist, self);
return SetupRay(0, start, dir, dist);
}
//public
qboolean Embree_TestLight(const vec3_t start, const vec3_t stop, const modelinfo_t *self)
{
RTCRay ray = SetupRay_StartStop(start, stop, self);
RTCRay ray = SetupRay_StartStop(start, stop);
rtcOccluded(scene, ray);
if (ray.geomID != RTC_INVALID_GEOMETRY_ID)
@ -752,8 +740,14 @@ qboolean Embree_TestSky(const vec3_t start, const vec3_t dirn, const modelinfo_t
VectorCopy(dirn, dir_normalized);
VectorNormalize(dir_normalized);
RTCRay ray = SetupRay(0, start, dir_normalized, MAX_SKY_DIST, self);
rtcIntersect(scene, ray);
RTCRay ray = SetupRay(0, start, dir_normalized, MAX_SKY_DIST);
ray_source_info ctx2(nullptr, self);
const RTCIntersectContext ctx = {
RTC_INTERSECT_COHERENT,
static_cast<void *>(&ctx2)
};
rtcIntersect1Ex(scene, &ctx, ray);
qboolean hit_sky = (ray.geomID == skygeom.geomID);
@ -772,8 +766,13 @@ qboolean Embree_TestSky(const vec3_t start, const vec3_t dirn, const modelinfo_t
//public
hittype_t Embree_DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const modelinfo_t *self, vec_t *hitdist_out, plane_t *hitplane_out, const bsp2_dface_t **face_out)
{
RTCRay ray = SetupRay(0, start, dirn, dist, self);
rtcIntersect(scene, ray);
RTCRay ray = SetupRay(0, start, dirn, dist);
ray_source_info ctx2(nullptr, self);
const RTCIntersectContext ctx = {
RTC_INTERSECT_COHERENT,
static_cast<void *>(&ctx2)
};
rtcIntersect1Ex(scene, &ctx, ray);
if (ray.geomID == RTC_INVALID_GEOMETRY_ID)
return hittype_t::NONE;
@ -870,9 +869,9 @@ public:
delete[] _ray_dynamic_styles;
}
virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const modelinfo_t *modelinfo, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) {
virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) {
Q_assert(_numrays<_maxrays);
_rays[_numrays] = SetupRay(_numrays, origin, dir, dist, modelinfo);
_rays[_numrays] = SetupRay(_numrays, origin, dir, dist);
_rays_maxdist[_numrays] = dist;
_point_indices[_numrays] = i;
if (color) {
@ -889,27 +888,29 @@ public:
return _numrays;
}
virtual void tracePushedRaysOcclusion() {
virtual void tracePushedRaysOcclusion(const modelinfo_t *self) {
//Q_assert(_state == streamstate_t::READY);
if (!_numrays)
return;
ray_source_info ctx2(this, self);
const RTCIntersectContext ctx = {
RTC_INTERSECT_COHERENT,
static_cast<void *>(this)
RTC_INTERSECT_COHERENT,
static_cast<void *>(&ctx2)
};
rtcOccluded1M(scene, &ctx, _rays, _numrays, sizeof(RTCRay));
}
virtual void tracePushedRaysIntersection() {
virtual void tracePushedRaysIntersection(const modelinfo_t *self) {
if (!_numrays)
return;
ray_source_info ctx2(this, self);
const RTCIntersectContext ctx = {
RTC_INTERSECT_COHERENT,
static_cast<void *>(this)
RTC_INTERSECT_COHERENT,
static_cast<void *>(&ctx2)
};
rtcIntersect1M(scene, &ctx, _rays, _numrays, sizeof(RTCRay));
@ -997,14 +998,15 @@ raystream_t *Embree_MakeRayStream(int maxrays)
}
void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float opacity, const vec3_t glasscolor) {
if (context == nullptr) {
// FIXME: remove this..
ray_source_info *ctx = static_cast<ray_source_info *>(context->userRayExt);
raystream_embree_t *rs = ctx->raystream;
if (rs == nullptr) {
// FIXME: remove this.. once all ray casts use raystreams
// happens for bounce lights, e.g. Embree_TestSky
return;
}
raystream_embree_t *rs = static_cast<raystream_embree_t *>(context->userRayExt);
// clamp opacity
opacity = qmin(qmax(0.0f, opacity), 1.0f);
@ -1034,6 +1036,8 @@ void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float
void AddDynamicOccluderToRay(const RTCIntersectContext* context, unsigned rayIndex, int style)
{
raystream_embree_t *rs = static_cast<raystream_embree_t *>(context->userRayExt);
ray_source_info *ctx = static_cast<ray_source_info *>(context->userRayExt);
raystream_embree_t *rs = ctx->raystream;
rs->_ray_dynamic_styles[rayIndex] = style;
}