Skip to content

Commit

Permalink
Refactor|Shadow Bias: Moved bias source affection updates out of Bias…
Browse files Browse the repository at this point in the history
…Surface

Affection is the contribution of light from source to "surface" in
the same map. To determine affection demands knowledge of the origin
of the both source and surface. BiasSurface lacks map surface origin
knowledge therefore it cannot perform affection determination itself
unaided.

Source affection is now performed using the half-edge geometry and by
the map surface which owns the BiasSource.

Also, bias sources are now correctly occluded when in the void and no
longer result in severe performance degredation (caused by performing
unnecessary lighting calculations vs every map surface in range).

A few bugs were fixed and the implementation cleaned of all residual
aftermath from previous development/refactoring efforts.

Note that the present mechanisms for storing light contributions and
affections have been replaced with the simplest mechanism that works
for the sake of clarity. A future implementation of the bias lighting
model will most probably need to replace these in any case.
  • Loading branch information
danij-deng committed Jul 29, 2013
1 parent 58c1f37 commit 47c0930
Show file tree
Hide file tree
Showing 9 changed files with 375 additions and 333 deletions.
8 changes: 7 additions & 1 deletion doomsday/client/include/render/biassource.h
Expand Up @@ -103,7 +103,7 @@ class BiasSource : public Grabbable, public de::ISerializable
BspLeaf &bspLeafAtOrigin() const;

/**
* Returns the light intensity multiplier for the source. The
* Returns the "primary" light intensity multiplier for the source. The
* IntensityChange audience is notified whenever the intensity changes.
*
* @see setIntensity()
Expand All @@ -122,6 +122,12 @@ class BiasSource : public Grabbable, public de::ISerializable
*/
BiasSource &setIntensity(float newIntensity);

/**
* Determine the effective light intensity for the source and factoring in
* sector light level multipliers/scale-factors.
*/
float evaluateIntensity() const;

/**
* Returns the light color strength factors for the source. The ColorChange
* audience is notified whenever the color changes.
Expand Down
33 changes: 19 additions & 14 deletions doomsday/client/include/render/biassurface.h
Expand Up @@ -24,6 +24,7 @@

#include "MapElement"

class BiasSource;
class BiasTracker;

/**
Expand All @@ -36,33 +37,37 @@ class BiasSurface
/**
* Construct a new surface.
*
* @param owner Map element which will own the surface (either a
* BspLeaf or a Segment).
* @param subElemIndex Index for the subelement of @a owner.
* @param size Number of vertices.
*/
BiasSurface(de::MapElement &owner, int subElemIndex, int size);
BiasSurface(int size);

/**
* To be called to register the commands and variables of this module.
*/
static void consoleRegister();

uint lastUpdateOnFrame() const;

void setLastUpdateOnFrame(uint newLastUpdateFrameNumber);

void clearAffected();

void addAffected(float intensity, BiasSource *source);

void updateAffection(BiasTracker &changes);

void updateAfterMove();

/**
* Perform lighting for the supplied geometry. It is assumed that this
* geometry has the @em same number of vertices as the bias surface.
*
* @param colors Array of colors to be written to.
* @param verts Array of vertices to be lit.
* @param vertCount Number of vertices (in the array) to be lit.
* @param sectorLightLevel Sector light level.
* @param vertCount Number of vertices to be lit.
* @param positions World coordinates for each vertex.
* @param colors Final lighting values will be written here.
*/
void lightPoly(struct ColorRawf_s *colors, struct rvertex_s const *verts,
int vertCount, float sectorLightLevel);

void updateAfterMove();

void updateAffection(BiasTracker &changes);
void lightPoly(de::Vector3f const &surfaceNormal, int vertCount,
struct rvertex_s const *positions, struct ColorRawf_s *colors);

private:
DENG2_PRIVATE(d)
Expand Down
3 changes: 3 additions & 0 deletions doomsday/client/include/world/bspleaf.h
Expand Up @@ -285,6 +285,9 @@ class BspLeaf : public de::MapElement
*/
void updateBiasAffection(BiasTracker &changes);

void lightPoly(int group, int vertCount, struct rvertex_s const *positions,
struct ColorRawf_s *colors);

/**
* Returns a pointer to the first ShadowLink; otherwise @c 0.
*/
Expand Down
9 changes: 9 additions & 0 deletions doomsday/client/include/world/segment.h
Expand Up @@ -77,6 +77,12 @@ class Segment : public de::MapElement

inline Vertex &to() const { return hedge().twin().vertex(); }

/**
* Returns the point on the line segment which lies at the exact center of
* the two vertexes.
*/
inline de::Vector2d center() const { return (from().origin() + to().origin()) / 2; }

/**
* Returns @c true iff a polygon attributed to a BSP leaf is associated
* with the line segment.
Expand Down Expand Up @@ -243,6 +249,9 @@ class Segment : public de::MapElement
*/
void updateBiasAffection(BiasTracker &changes);

void lightPoly(int group, int vertCount, struct rvertex_s const *positions,
struct ColorRawf_s *colors);

#endif // __CLIENT__

protected:
Expand Down
64 changes: 40 additions & 24 deletions doomsday/client/src/render/biassource.cpp
Expand Up @@ -36,8 +36,9 @@ DENG2_PIMPL(BiasSource)
/// Origin of the source in the map coordinate space.
Vector3d origin;

/// BSP leaf at this origin.
/// BSP leaf at the origin.
BspLeaf *bspLeaf;
bool inVoid; ///< Set to @c true if the origin is in the void.

/// Intensity of the emitted light.
float primaryIntensity;
Expand All @@ -62,6 +63,7 @@ DENG2_PIMPL(BiasSource)
: Base(i),
origin(origin),
bspLeaf(0),
inVoid(true),
primaryIntensity(intensity),
intensity(intensity),
color(color),
Expand All @@ -75,6 +77,7 @@ DENG2_PIMPL(BiasSource)
: Base(i),
origin(other.origin),
bspLeaf(other.bspLeaf),
inVoid(other.inVoid),
primaryIntensity(other.primaryIntensity),
intensity(other.intensity),
color(other.color),
Expand Down Expand Up @@ -115,6 +118,14 @@ DENG2_PIMPL(BiasSource)
i->biasSourceColorChanged(self, oldColor, changedComponents);
}
}

void updateBspLocation()
{
if(bspLeaf) return;
/// @todo Do not assume the current map.
bspLeaf = &App_World().map().bspLeafAt(origin);
inVoid = !(bspLeaf->pointInside(origin));
}
};

BiasSource::BiasSource(Vector3d const &origin, float intensity, Vector3f const &color,
Expand Down Expand Up @@ -156,11 +167,7 @@ void BiasSource::setOrigin(Vector3d const &newOrigin)

BspLeaf &BiasSource::bspLeafAtOrigin() const
{
if(!d->bspLeaf)
{
/// @todo Do not assume the current map.
d->bspLeaf = &App_World().map().bspLeafAt(d->origin);
}
d->updateBspLocation();
return *d->bspLeaf;
}

Expand All @@ -169,9 +176,15 @@ float BiasSource::intensity() const
return d->primaryIntensity;
}

float BiasSource::evaluateIntensity() const
{
d->updateBspLocation();
return d->inVoid? 0 : d->intensity;
}

BiasSource &BiasSource::setIntensity(float newIntensity)
{
if(!de::fequal(d->intensity, newIntensity))
if(!de::fequal(d->primaryIntensity, newIntensity))
{
float oldIntensity = d->primaryIntensity;

Expand Down Expand Up @@ -251,29 +264,32 @@ bool BiasSource::trackChanges(BiasTracker &changes, uint indexInTracker, uint cu
{
if(d->maxLight > 0 || d->minLight > 0)
{
float const oldIntensity = d->intensity;
float const oldIntensity = intensity();
float newIntensity = 0;

/// @todo Should observe Sector::LightLevelChange
Sector const &sector = bspLeafAtOrigin().sector();

// Lower intensities are useless for light emission.
if(sector.lightLevel() >= d->maxLight)
if(!d->inVoid)
{
d->intensity = d->primaryIntensity;
/// @todo Should observe Sector::LightLevelChange
Sector const &sector = d->bspLeaf->sector();

// Lower intensities are useless for light emission.
if(sector.lightLevel() >= d->maxLight)
{
newIntensity = d->primaryIntensity;
}

if(sector.lightLevel() >= d->minLight && d->minLight != d->maxLight)
{
newIntensity = d->primaryIntensity *
(sector.lightLevel() - d->minLight) / (d->maxLight - d->minLight);
}
}

if(sector.lightLevel() >= d->minLight && d->minLight != d->maxLight)
{
d->intensity = d->primaryIntensity *
(sector.lightLevel() - d->minLight) / (d->maxLight - d->minLight);
}
else
if(newIntensity != oldIntensity)
{
d->intensity = 0;
}

if(d->intensity != oldIntensity)
d->intensity = newIntensity;
d->changed = true;
}
}

if(!d->changed) return false;
Expand Down

0 comments on commit 47c0930

Please sign in to comment.