From 91fcfe5b9a20db92d42e61cc5bf30a51a25d7ca7 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Thu, 3 Nov 2016 02:26:53 -0600 Subject: [PATCH] light: use glass texture colors to tint rays --- include/light/light.hh | 1 + light/light.cc | 10 +++++++++- light/trace_embree.cc | 33 +++++++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/include/light/light.hh b/include/light/light.hh index 05591fc5..2cefe84c 100644 --- a/include/light/light.hh +++ b/include/light/light.hh @@ -405,6 +405,7 @@ const vec_t *GetSurfaceVertexNormal(const bsp2_t *bsp, const bsp2_dface_t *f, co const bsp2_dface_t *Face_EdgeIndexSmoothed(const bsp2_t *bsp, const bsp2_dface_t *f, const int edgeindex); const std::vector &BounceLights(); std::vector BounceLightsForFaceNum(int facenum); +void Palette_GetColor(int i, vec3_t samplecolor); bool Leaf_HasSky(const bsp2_t *bsp, const bsp2_dleaf_t *leaf); int light_main(int argc, const char **argv); diff --git a/light/light.cc b/light/light.cc index 9c6e8e6b..c0e2fa96 100644 --- a/light/light.cc +++ b/light/light.cc @@ -949,6 +949,13 @@ std::vector BounceLightsForFaceNum(int facenum) return {}; } +void Palette_GetColor(int i, vec3_t samplecolor) +{ + samplecolor[0] = (float)thepalette[3*i]; + samplecolor[1] = (float)thepalette[3*i + 1]; + samplecolor[2] = (float)thepalette[3*i + 2]; +} + // Returns color in [0,1] static void Texture_AvgColor (const bsp2_t *bsp, const miptex_t *miptex, vec3_t color) @@ -962,7 +969,8 @@ Texture_AvgColor (const bsp2_t *bsp, const miptex_t *miptex, vec3_t color) for (int x=0; xwidth; x++) { const int i = data[(miptex->width * y) + x]; - vec3_t samplecolor = { (float)thepalette[3*i], (float)thepalette[3*i + 1], (float)thepalette[3*i + 2] }; + vec3_t samplecolor; + Palette_GetColor(i, samplecolor); VectorAdd(color, samplecolor, color); } } diff --git a/light/trace_embree.cc b/light/trace_embree.cc index 592c5f51..84bec19a 100644 --- a/light/trace_embree.cc +++ b/light/trace_embree.cc @@ -241,7 +241,7 @@ enum class filtertype_t { INTERSECTION, OCCLUSION }; -void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float opacity); +void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float opacity, const vec3_t glasscolor); // called to evaluate transparency template @@ -282,12 +282,20 @@ Embree_FilterFuncN(int* valid, const bsp2_dface_t *face = Embree_LookupFace(geomID, primID); const modelinfo_t *modelinfo = Embree_LookupModelinfo(geomID, primID); + vec3_t hitpoint; + Embree_RayEndpoint(ray, potentialHit, N, i, hitpoint); + const int sample = SampleTexture(face, bsp_static, hitpoint); + float alpha = 1.0f; if (modelinfo != nullptr) { alpha = modelinfo->alpha.floatValue(); if (alpha < 1.0f) { + vec3_t samplecolor; + Palette_GetColor(sample, samplecolor); + VectorScale(samplecolor, 1/255.0, samplecolor); + // FIXME: Occluding twice (once for each side of the glass brush) - AddGlassToRay(context, rayIndex, alpha); + AddGlassToRay(context, rayIndex, alpha, samplecolor); // reject hit valid[i] = INVALID; @@ -297,10 +305,6 @@ Embree_FilterFuncN(int* valid, const char *name = Face_TextureName(bsp_static, face); if (name[0] == '{') { - vec3_t hitpoint; - Embree_RayEndpoint(ray, potentialHit, N, i, hitpoint); - const int sample = SampleTexture(face, bsp_static, hitpoint); - if (sample == 255) { // reject hit valid[i] = INVALID; @@ -870,10 +874,23 @@ raystream_t *Embree_MakeRayStream(int maxrays) return new raystream_embree_t{maxrays}; } -void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float opacity) { +void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float opacity, const vec3_t glasscolor) { raystream_embree_t *rs = static_cast(context->userRayExt); Q_assert(rayIndex < rs->_numrays); - VectorScale(rs->_ray_colors[rayIndex], 1.0 - opacity, rs->_ray_colors[rayIndex]); + //multiply ray color by glass color + vec3_t tinted; + for (int i=0; i<3; i++) { + tinted[i] = rs->_ray_colors[rayIndex][i] * glasscolor[i]; + } + + // lerp between original ray color and fully tinted, based on opacity + + vec3_t lerped = {0.0, 0.0, 0.0}; + VectorMA(lerped, opacity, tinted, lerped); + VectorMA(lerped, 1.0-opacity, rs->_ray_colors[rayIndex], lerped); + + // save out the lerped value as the new ray color + VectorCopy(lerped, rs->_ray_colors[rayIndex]); }