|
@@ -33,6 +33,7 @@
|
|
|
#include "gfx/gfxOcclusionQuery.h"
|
|
|
#include "gfx/gfxDrawUtil.h"
|
|
|
#include "gfx/gfxTextureManager.h"
|
|
|
+#include "gfx/sim/debugDraw.h"
|
|
|
#include "renderInstance/renderPassManager.h"
|
|
|
#include "T3D/gameBase/gameConnection.h"
|
|
|
#include "T3D/gameBase/processList.h"
|
|
@@ -275,12 +276,10 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt
|
|
|
// is on scren at all... if not then return
|
|
|
// the last result.
|
|
|
const Point3F &lightPos = flareState->lightMat.getPosition();
|
|
|
- const RectI &viewport = GFX->getViewport();
|
|
|
- MatrixF projMatrix;
|
|
|
- state->getCameraFrustum().getProjectionMatrix(&projMatrix);
|
|
|
- if( state->isReflectPass() )
|
|
|
- projMatrix = state->getSceneManager()->getNonClipProjection();
|
|
|
- bool onScreen = MathUtils::mProjectWorldToScreen( lightPos, outLightPosSS, viewport, GFX->getWorldMatrix(), projMatrix );
|
|
|
+ const RectI &viewport = RectI(Point2I(0, 0), GFX->getViewport().extent);
|
|
|
+
|
|
|
+ MatrixF camProjMatrix = projMatrix = state->getSceneManager()->getNonClipProjection();
|
|
|
+ bool onScreen = MathUtils::mProjectWorldToScreen( lightPos, outLightPosSS, viewport, GFX->getWorldMatrix(), camProjMatrix );
|
|
|
|
|
|
// It is onscreen, so raycast as a simple occlusion test.
|
|
|
const LightInfo *lightInfo = flareState->lightInfo;
|
|
@@ -297,7 +296,7 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt
|
|
|
// Always treat light as onscreen if using HOQ
|
|
|
// it will be faded out if offscreen anyway.
|
|
|
onScreen = true;
|
|
|
- needsRaycast = false;
|
|
|
+ needsRaycast = false;
|
|
|
|
|
|
// Test the hardware queries for rendered pixels.
|
|
|
U32 pixels = 0, fullPixels = 0;
|
|
@@ -400,63 +399,75 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt
|
|
|
return lightVisible;
|
|
|
}
|
|
|
|
|
|
-void LightFlareData::prepRender( SceneRenderState *state, LightFlareState *flareState )
|
|
|
+void LightFlareData::prepRender(SceneRenderState *state, LightFlareState *flareState)
|
|
|
{
|
|
|
- PROFILE_SCOPE( LightFlareData_prepRender );
|
|
|
+ PROFILE_SCOPE(LightFlareData_prepRender);
|
|
|
|
|
|
const LightInfo *lightInfo = flareState->lightInfo;
|
|
|
|
|
|
- if ( mIsZero( flareState->fullBrightness ) ||
|
|
|
- mIsZero( lightInfo->getBrightness() ) )
|
|
|
- return;
|
|
|
+ if (mIsZero(flareState->fullBrightness) ||
|
|
|
+ mIsZero(lightInfo->getBrightness()))
|
|
|
+ return;
|
|
|
|
|
|
// Figure out the element count to render.
|
|
|
U32 elementCount = mElementCount;
|
|
|
const bool isReflectPass = state->isReflectPass();
|
|
|
- if ( isReflectPass )
|
|
|
+ if (isReflectPass)
|
|
|
{
|
|
|
// Then we don't render anything this pass.
|
|
|
- if ( !mRenderReflectPass )
|
|
|
+ if (!mRenderReflectPass)
|
|
|
return;
|
|
|
|
|
|
// Find the zero distance elements which make
|
|
|
// up the corona of the light flare.
|
|
|
elementCount = 0.0f;
|
|
|
- for ( U32 i=0; i < mElementCount; i++ )
|
|
|
- if ( mIsZero( mElementDist[i] ) )
|
|
|
- elementCount++;
|
|
|
+ for (U32 i = 0; i < mElementCount; i++)
|
|
|
+ if (mIsZero(mElementDist[i]))
|
|
|
+ elementCount++;
|
|
|
}
|
|
|
|
|
|
// Better have something to render.
|
|
|
- if ( elementCount == 0 )
|
|
|
+ if (elementCount == 0)
|
|
|
return;
|
|
|
-
|
|
|
+
|
|
|
U32 visDelta = U32_MAX;
|
|
|
F32 occlusionFade = 1.0f;
|
|
|
Point3F lightPosSS;
|
|
|
- bool lightVisible = _testVisibility( state, flareState, &visDelta, &occlusionFade, &lightPosSS );
|
|
|
-
|
|
|
+ bool lightVisible = _testVisibility(state, flareState, &visDelta, &occlusionFade, &lightPosSS);
|
|
|
+
|
|
|
+ //DebugDrawer::get()->drawBox(flareState->lightMat.getPosition() + Point3F(-0.5, -0.5, -0.5) * 4, flareState->lightMat.getPosition() + Point3F(0.5, 0.5, 0.5) * 4, ColorI::BLUE);
|
|
|
+
|
|
|
// We can only skip rendering if the light is not
|
|
|
// visible, and it has elapsed the fade out time.
|
|
|
- if ( mIsZero( occlusionFade ) ||
|
|
|
- !lightVisible && visDelta > FadeOutTime )
|
|
|
+ if (mIsZero(occlusionFade) ||
|
|
|
+ !lightVisible && visDelta > FadeOutTime)
|
|
|
return;
|
|
|
|
|
|
const RectI &viewport = GFX->getViewport();
|
|
|
- Point3F oneOverViewportExtent( 1.0f / (F32)viewport.extent.x, 1.0f / (F32)viewport.extent.y, 0.0f );
|
|
|
+ Point3F oneOverViewportExtent(1.0f / (F32)viewport.extent.x, 1.0f / (F32)viewport.extent.y, 0.0f);
|
|
|
|
|
|
- // Really convert it to screen space.
|
|
|
- lightPosSS.x -= viewport.point.x;
|
|
|
- lightPosSS.y -= viewport.point.y;
|
|
|
lightPosSS *= oneOverViewportExtent;
|
|
|
- lightPosSS = ( lightPosSS * 2.0f ) - Point3F::One;
|
|
|
+ lightPosSS = (lightPosSS * 2.0f) - Point3F::One;
|
|
|
lightPosSS.y = -lightPosSS.y;
|
|
|
lightPosSS.z = 0.0f;
|
|
|
|
|
|
+ // Determine the center of the current projection so we can converge there
|
|
|
+ Point3F centerProj(0);
|
|
|
+ {
|
|
|
+ MatrixF camProjMatrix = state->getSceneManager()->getNonClipProjection();
|
|
|
+ Point3F outCenterPos;
|
|
|
+ RectI centerViewport = RectI(Point2I(0, 0), viewport.extent);
|
|
|
+ MathUtils::mProjectWorldToScreen(Point3F(0,state->getSceneManager()->getNearClip(),0), &outCenterPos, centerViewport, MatrixF::Identity, camProjMatrix);
|
|
|
+ centerProj = outCenterPos;
|
|
|
+ centerProj *= oneOverViewportExtent;
|
|
|
+ centerProj = (centerProj * 2.0f) - Point3F::One;
|
|
|
+ centerProj.y = -centerProj.y;
|
|
|
+ centerProj.z = 0.0f;
|
|
|
+ }
|
|
|
+
|
|
|
// Take any projection offset into account so that the point where the flare's
|
|
|
// elements converge is at the 'eye' point rather than the center of the viewport.
|
|
|
- const Point2F& projOffset = state->getCameraFrustum().getProjectionOffset();
|
|
|
- Point3F flareVec( -lightPosSS + Point3F(projOffset.x, projOffset.y, 0.0f) );
|
|
|
+ Point3F flareVec( centerProj - lightPosSS );
|
|
|
const F32 flareLength = flareVec.len();
|
|
|
if ( flareLength > 0.0f )
|
|
|
flareVec *= 1.0f / flareLength;
|