mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 16:14:38 +00:00
Merge pull request #1024 from eightyeight/scattersky-flare-fix
Fix ScatterSky flare occlusion
This commit is contained in:
commit
e5cd80ac87
5 changed files with 105 additions and 40 deletions
|
|
@ -26,16 +26,18 @@
|
||||||
#include "core/stream/bitStream.h"
|
#include "core/stream/bitStream.h"
|
||||||
#include "console/engineAPI.h"
|
#include "console/engineAPI.h"
|
||||||
#include "lighting/lightInfo.h"
|
#include "lighting/lightInfo.h"
|
||||||
|
#include "lighting/lightQuery.h"
|
||||||
#include "math/mathUtils.h"
|
#include "math/mathUtils.h"
|
||||||
#include "math/mathIO.h"
|
#include "math/mathIO.h"
|
||||||
#include "scene/sceneRenderState.h"
|
#include "scene/sceneRenderState.h"
|
||||||
#include "gfx/gfxOcclusionQuery.h"
|
#include "gfx/gfxOcclusionQuery.h"
|
||||||
#include "gfx/gfxDrawUtil.h"
|
#include "gfx/gfxDrawUtil.h"
|
||||||
|
#include "gfx/gfxTextureManager.h"
|
||||||
#include "renderInstance/renderPassManager.h"
|
#include "renderInstance/renderPassManager.h"
|
||||||
#include "T3D/gameBase/gameConnection.h"
|
#include "T3D/gameBase/gameConnection.h"
|
||||||
#include "T3D/gameBase/processList.h"
|
#include "T3D/gameBase/processList.h"
|
||||||
#include "collision/collision.h"
|
#include "collision/collision.h"
|
||||||
|
#include "lighting/lightManager.h"
|
||||||
|
|
||||||
const U32 LightFlareData::LosMask = STATIC_COLLISION_TYPEMASK |
|
const U32 LightFlareData::LosMask = STATIC_COLLISION_TYPEMASK |
|
||||||
ShapeBaseObjectType |
|
ShapeBaseObjectType |
|
||||||
|
|
@ -45,8 +47,6 @@ const U32 LightFlareData::LosMask = STATIC_COLLISION_TYPEMASK |
|
||||||
|
|
||||||
LightFlareState::~LightFlareState()
|
LightFlareState::~LightFlareState()
|
||||||
{
|
{
|
||||||
delete occlusionQuery;
|
|
||||||
delete fullPixelQuery;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightFlareState::clear()
|
void LightFlareState::clear()
|
||||||
|
|
@ -59,8 +59,6 @@ void LightFlareState::clear()
|
||||||
lightInfo = NULL;
|
lightInfo = NULL;
|
||||||
worldRadius = -1.0f;
|
worldRadius = -1.0f;
|
||||||
occlusion = -1.0f;
|
occlusion = -1.0f;
|
||||||
occlusionQuery = NULL;
|
|
||||||
fullPixelQuery = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Point3F LightFlareData::sBasePoints[] =
|
Point3F LightFlareData::sBasePoints[] =
|
||||||
|
|
@ -296,47 +294,39 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt
|
||||||
// for one-shot initialization of LightFlareState
|
// for one-shot initialization of LightFlareState
|
||||||
if ( useOcclusionQuery )
|
if ( useOcclusionQuery )
|
||||||
{
|
{
|
||||||
if ( flareState->occlusionQuery == NULL )
|
|
||||||
flareState->occlusionQuery = GFX->createOcclusionQuery();
|
|
||||||
if ( flareState->fullPixelQuery == NULL )
|
|
||||||
flareState->fullPixelQuery = GFX->createOcclusionQuery();
|
|
||||||
|
|
||||||
// Always treat light as onscreen if using HOQ
|
// Always treat light as onscreen if using HOQ
|
||||||
// it will be faded out if offscreen anyway.
|
// it will be faded out if offscreen anyway.
|
||||||
onScreen = true;
|
onScreen = true;
|
||||||
|
needsRaycast = false;
|
||||||
// NOTE: These queries frame lock us as we block to get the
|
|
||||||
// results. This is ok as long as long as we're not too GPU
|
|
||||||
// bound... else we waste CPU time here waiting for it when
|
|
||||||
// we could have been doing other CPU work instead.
|
|
||||||
|
|
||||||
// Test the hardware queries for rendered pixels.
|
// Test the hardware queries for rendered pixels.
|
||||||
U32 pixels = 0, fullPixels = 0;
|
U32 pixels = 0, fullPixels = 0;
|
||||||
GFXOcclusionQuery::OcclusionQueryStatus status = flareState->occlusionQuery->getStatus( true, &pixels );
|
GFXOcclusionQuery::OcclusionQueryStatus status;
|
||||||
flareState->fullPixelQuery->getStatus( true, &fullPixels );
|
flareState->occlusionQuery.getLastStatus( false, &status, &pixels );
|
||||||
if ( status != GFXOcclusionQuery::Occluded && fullPixels != 0 )
|
flareState->fullPixelQuery.getLastStatus( false, NULL, &fullPixels );
|
||||||
|
|
||||||
|
if ( status == GFXOcclusionQuery::NotOccluded && fullPixels != 0 )
|
||||||
*outOcclusionFade = mClampF( (F32)pixels / (F32)fullPixels, 0.0f, 1.0f );
|
*outOcclusionFade = mClampF( (F32)pixels / (F32)fullPixels, 0.0f, 1.0f );
|
||||||
|
|
||||||
// If we got a result then we don't need to fallback to the raycast.
|
if( !flareState->occlusionQuery.isWaiting() )
|
||||||
if ( status != GFXOcclusionQuery::Unset )
|
{
|
||||||
needsRaycast = false;
|
// Setup the new queries.
|
||||||
|
RenderPassManager *rpm = state->getRenderPass();
|
||||||
// Setup the new queries.
|
OccluderRenderInst *ri = rpm->allocInst<OccluderRenderInst>();
|
||||||
RenderPassManager *rpm = state->getRenderPass();
|
ri->type = RenderPassManager::RIT_Occluder;
|
||||||
OccluderRenderInst *ri = rpm->allocInst<OccluderRenderInst>();
|
ri->query = flareState->occlusionQuery.getQuery();
|
||||||
ri->type = RenderPassManager::RIT_Occluder;
|
ri->query2 = flareState->fullPixelQuery.getQuery();
|
||||||
ri->query = flareState->occlusionQuery;
|
ri->isSphere = true;
|
||||||
ri->query2 = flareState->fullPixelQuery;
|
ri->position = lightPos;
|
||||||
ri->isSphere = true;
|
if ( isVectorLight && flareState->worldRadius > 0.0f )
|
||||||
ri->position = lightPos;
|
ri->scale.set( flareState->worldRadius );
|
||||||
if ( isVectorLight && flareState->worldRadius > 0.0f )
|
else
|
||||||
ri->scale.set( flareState->worldRadius );
|
ri->scale.set( mOcclusionRadius );
|
||||||
else
|
ri->orientation = rpm->allocUniqueXform( lightInfo->getTransform() );
|
||||||
ri->scale.set( mOcclusionRadius );
|
|
||||||
ri->orientation = rpm->allocUniqueXform( lightInfo->getTransform() );
|
|
||||||
|
|
||||||
// Submit the queries.
|
// Submit the queries.
|
||||||
state->getRenderPass()->addInst( ri );
|
state->getRenderPass()->addInst( ri );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Point3F &camPos = state->getCameraPosition();
|
const Point3F &camPos = state->getCameraPosition();
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,14 @@
|
||||||
#ifndef _GFXSTATEBLOCK_H_
|
#ifndef _GFXSTATEBLOCK_H_
|
||||||
#include "gfx/gfxStateBlock.h"
|
#include "gfx/gfxStateBlock.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef _GFXOCCLUSIONQUERY_H_
|
||||||
|
#include "gfx/gfxOcclusionQuery.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class LightInfo;
|
class LightInfo;
|
||||||
struct ObjectRenderInst;
|
struct ObjectRenderInst;
|
||||||
class SceneRenderState;
|
class SceneRenderState;
|
||||||
class BaseMatInstance;
|
class BaseMatInstance;
|
||||||
class GFXOcclusionQuery;
|
|
||||||
|
|
||||||
struct LightFlareState
|
struct LightFlareState
|
||||||
{
|
{
|
||||||
|
|
@ -65,8 +67,8 @@ struct LightFlareState
|
||||||
bool visible;
|
bool visible;
|
||||||
F32 occlusion;
|
F32 occlusion;
|
||||||
GFXVertexBufferHandle<GFXVertexPCT> vertBuffer;
|
GFXVertexBufferHandle<GFXVertexPCT> vertBuffer;
|
||||||
GFXOcclusionQuery *occlusionQuery;
|
GFXOcclusionQueryHandle occlusionQuery;
|
||||||
GFXOcclusionQuery *fullPixelQuery;
|
GFXOcclusionQueryHandle fullPixelQuery;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LightFlareData : public SimDataBlock
|
class LightFlareData : public SimDataBlock
|
||||||
|
|
|
||||||
|
|
@ -658,6 +658,11 @@ void ScatterSky::prepRenderImage( SceneRenderState *state )
|
||||||
mFlareState.lightMat.identity();
|
mFlareState.lightMat.identity();
|
||||||
mFlareState.lightMat.setPosition( lightPos );
|
mFlareState.lightMat.setPosition( lightPos );
|
||||||
|
|
||||||
|
F32 dist = ( lightPos - state->getCameraPosition( ) ).len( );
|
||||||
|
F32 coronaScale = 0.5f;
|
||||||
|
F32 screenRadius = GFX->getViewport( ).extent.y * coronaScale * 0.5f;
|
||||||
|
mFlareState.worldRadius = screenRadius * dist / state->getWorldToScreenScale( ).y;
|
||||||
|
|
||||||
mFlareData->prepRender( state, &mFlareState );
|
mFlareData->prepRender( state, &mFlareState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ GFXD3D9OcclusionQuery::OcclusionQueryStatus GFXD3D9OcclusionQuery::getStatus( bo
|
||||||
//If we're stalled out, proceed with worst-case scenario -BJR
|
//If we're stalled out, proceed with worst-case scenario -BJR
|
||||||
if(GFX->mFrameTime->getElapsedMs()>4)
|
if(GFX->mFrameTime->getElapsedMs()>4)
|
||||||
{
|
{
|
||||||
|
this->begin();
|
||||||
this->end();
|
this->end();
|
||||||
return NotOccluded;
|
return NotOccluded;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,4 +82,71 @@ public:
|
||||||
virtual const String describeSelf() const = 0;
|
virtual const String describeSelf() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Handle for GFXOcclusionQuery than store last valid state
|
||||||
|
class GFXOcclusionQueryHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
GFXOcclusionQueryHandle()
|
||||||
|
: mLastStatus(GFXOcclusionQuery::Unset), mLastData(0), mQuery(NULL), mWaiting(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~GFXOcclusionQueryHandle()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(mQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getLastStatus( bool block, GFXOcclusionQuery::OcclusionQueryStatus *statusPtr = NULL, U32 *data = NULL );
|
||||||
|
GFXOcclusionQuery* getQuery() const { return mQuery; }
|
||||||
|
|
||||||
|
void clearLastStatus()
|
||||||
|
{
|
||||||
|
mLastStatus = GFXOcclusionQuery::Unset;
|
||||||
|
mLastData = 0;
|
||||||
|
mWaiting = false;
|
||||||
|
|
||||||
|
if( !mQuery )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mQuery->begin();
|
||||||
|
mQuery->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWaiting() const { return mWaiting; }
|
||||||
|
protected:
|
||||||
|
GFXOcclusionQuery::OcclusionQueryStatus mLastStatus;
|
||||||
|
U32 mLastData;
|
||||||
|
bool mWaiting;
|
||||||
|
GFXOcclusionQuery *mQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool GFXOcclusionQueryHandle::getLastStatus( bool block, GFXOcclusionQuery::OcclusionQueryStatus *statusPtr, U32 *data )
|
||||||
|
{
|
||||||
|
if( !mQuery )
|
||||||
|
mQuery = GFX->createOcclusionQuery();
|
||||||
|
|
||||||
|
GFXOcclusionQuery::OcclusionQueryStatus status = mQuery->getStatus( block, data );
|
||||||
|
|
||||||
|
if( status == GFXOcclusionQuery::Waiting )
|
||||||
|
{
|
||||||
|
mWaiting = true;
|
||||||
|
if( statusPtr )
|
||||||
|
*statusPtr = mLastStatus;
|
||||||
|
if( data )
|
||||||
|
*data = mLastData;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( statusPtr )
|
||||||
|
*statusPtr = status;
|
||||||
|
|
||||||
|
mWaiting = false;
|
||||||
|
mLastStatus = status;
|
||||||
|
mLastData = *data;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // _GFXOCCLUSIONQUERY_H_
|
#endif // _GFXOCCLUSIONQUERY_H_
|
||||||
Loading…
Add table
Add a link
Reference in a new issue