Shifted to the static-list arrangement for probe instance tracking to help performance as well as drastically streamline the data submission/material instance flow for probe rendering.

This commit is contained in:
Areloch 2018-10-07 17:32:23 -05:00
parent 9e88e9feca
commit 57f8549abe
22 changed files with 901 additions and 1250 deletions

View file

@ -54,7 +54,6 @@
extern bool gEditingMission;
extern ColorI gCanvasClearColor;
bool ReflectionProbe::smRenderReflectionProbes = true;
bool ReflectionProbe::smRenderPreviewProbes = true;
IMPLEMENT_CO_NETOBJECT_V1(ReflectionProbe);
@ -73,8 +72,8 @@ ConsoleDocClass(ReflectionProbe,
ImplementEnumType(ReflectProbeType,
"Type of mesh data available in a shape.\n"
"@ingroup gameObjects")
{ ProbeInfo::Sphere, "Sphere", "Sphere shaped" },
{ ProbeInfo::Box, "Box", "Box shape" }
{ ProbeRenderInst::Sphere, "Sphere", "Sphere shaped" },
{ ProbeRenderInst::Box, "Box", "Box shape" }
EndImplementEnumType;
ImplementEnumType(IndrectLightingModeEnum,
@ -105,7 +104,7 @@ ReflectionProbe::ReflectionProbe()
mTypeMask = LightObjectType | MarkerObjectType;
mProbeShapeType = ProbeInfo::Box;
mProbeShapeType = ProbeRenderInst::Box;
mIndrectLightingModeType = NoIndirect;
@ -132,7 +131,7 @@ ReflectionProbe::ReflectionProbe()
mResourcesCreated = false;
mProbeInfo = new ProbeInfo();
mProbeInfo = nullptr;
mPrefilterSize = 64;
mPrefilterMipLevels = mLog2(F32(mPrefilterSize));
@ -148,6 +147,9 @@ ReflectionProbe::~ReflectionProbe()
if (mEditorShapeInst)
SAFE_DELETE(mEditorShapeInst);
if (mProbeInfo)
SAFE_DELETE(mProbeInfo);
if (mReflectionModeType != StaticCubemap && mStaticCubemap)
mStaticCubemap->deleteObject();
}
@ -183,7 +185,7 @@ void ReflectionProbe::initPersistFields()
&_doBake, &defaultProtectedGetFn, "Regenerate Voxel Grid", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
endGroup("Reflection");
Con::addVariable("$Light::renderReflectionProbes", TypeBool, &ReflectionProbe::smRenderReflectionProbes,
Con::addVariable("$Light::renderReflectionProbes", TypeBool, &ProbeManager::smRenderReflectionProbes,
"Toggles rendering of light frustums when the light is selected in the editor.\n\n"
"@note Only works for shadow mapped lights.\n\n"
"@ingroup Lighting");
@ -377,10 +379,10 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
if (stream->readFlag()) // ShapeTypeMask
{
U32 shapeType = ProbeInfo::Sphere;
U32 shapeType = ProbeRenderInst::Sphere;
stream->read(&shapeType);
mProbeShapeType = (ProbeInfo::ProbeShapeType)shapeType;
mProbeShapeType = (ProbeRenderInst::ProbeShapeType)shapeType;
createGeometry();
}
@ -457,7 +459,10 @@ void ReflectionProbe::createGeometry()
void ReflectionProbe::updateProbeParams()
{
if (mProbeInfo == nullptr)
return;
{
mProbeInfo = new ProbeRenderInst();
mProbeInfo->mIsEnabled = false;
}
updateMaterial();
@ -465,13 +470,16 @@ void ReflectionProbe::updateProbeParams()
mProbeInfo->mProbeShapeType = mProbeShapeType;
//mProbeInfo->mTransform = getWorldTransform();
mProbeInfo->setPosition(getPosition());
//Point3F pos = mProbeInfo->mTransform.getPosition();
//Update the bounds
//mObjBox.minExtents.set(-1, -1, -1);
//mObjBox.maxExtents.set(1, 1, 1);
//mObjScale.set(mRadius / 2, mRadius / 2, mRadius / 2);
mObjScale.set(mRadius, mRadius, mRadius);
// Skip our transform... it just dirties mask bits.
Parent::setTransform(mObjToWorld);
@ -484,6 +492,8 @@ void ReflectionProbe::updateProbeParams()
mProbeInfo->mIsSkylight = false;
mProbeInfo->mProbePosOffset = mProbePosOffset;
mProbeInfo->mDirty = true;
}
void ReflectionProbe::updateMaterial()
@ -518,6 +528,12 @@ void ReflectionProbe::updateMaterial()
{
mProbeInfo->mCubemap = &mDynamicCubemap;
}
//Make us ready to render
if (mEnabled)
mProbeInfo->mIsEnabled = true;
else
mProbeInfo->mIsEnabled = false;
}
bool ReflectionProbe::createClientResources()
@ -583,7 +599,7 @@ void ReflectionProbe::generateTextures()
void ReflectionProbe::prepRenderImage(SceneRenderState *state)
{
if (!mEnabled || !ReflectionProbe::smRenderReflectionProbes)
if (!mEnabled || !ProbeManager::smRenderReflectionProbes)
return;
Point3F distVec = getRenderPosition() - state->getCameraPosition();
@ -612,7 +628,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
mProbeInfo->mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
//Register
PROBEMGR->registerProbe(mProbeInfo, this);
//PROBEMGR->registerProbe(mProbeInfo, this);
if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
{
@ -694,7 +710,7 @@ void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri,
SceneRenderState *state,
BaseMatInstance *overrideMat)
{
if (!ReflectionProbe::smRenderReflectionProbes)
if (!ProbeManager::smRenderReflectionProbes)
return;
GFXDrawUtil *draw = GFX->getDrawUtil();
@ -708,7 +724,7 @@ void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri,
ColorI color = ColorI::WHITE;
color.alpha = 25;
if (mProbeShapeType == ProbeInfo::Sphere)
if (mProbeShapeType == ProbeRenderInst::Sphere)
{
draw->drawSphere(desc, mRadius, getPosition(), color);
}
@ -844,8 +860,8 @@ void ReflectionProbe::bake(String outputPath, S32 resolution)
//gEditingMission = false;
//Set this to true to use the prior method where it goes through the SPT_Reflect path for the bake
bool probeRenderState = ReflectionProbe::smRenderReflectionProbes;
ReflectionProbe::smRenderReflectionProbes = false;
bool probeRenderState = ProbeManager::smRenderReflectionProbes;
ProbeManager::smRenderReflectionProbes = false;
for (U32 i = 0; i < 6; ++i)
{
GFXTexHandle blendTex;
@ -996,7 +1012,7 @@ void ReflectionProbe::bake(String outputPath, S32 resolution)
Con::errorf("ReflectionProbe::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!");
}
ReflectionProbe::smRenderReflectionProbes = probeRenderState;
ProbeManager::smRenderReflectionProbes = probeRenderState;
setMaskBits(-1);
if (preCapture)

View file

@ -109,9 +109,9 @@ protected:
//--------------------------------------------------------------------------
// Rendering variables
//--------------------------------------------------------------------------
ProbeInfo::ProbeShapeType mProbeShapeType;
ProbeRenderInst::ProbeShapeType mProbeShapeType;
ProbeInfo* mProbeInfo;
ProbeRenderInst* mProbeInfo;
//Indirect Lighting Contribution stuff
IndrectLightingModeType mIndrectLightingModeType;
@ -154,7 +154,6 @@ protected:
U32 mSpherePrimitiveCount;
//Debug rendering
static bool smRenderReflectionProbes;
static bool smRenderPreviewProbes;
U32 mDynamicLastBakeMS;
@ -221,7 +220,7 @@ public:
// Get the Material instance
void updateMaterial();
void updateProbeParams();
virtual void updateProbeParams();
bool createClientResources();
void generateTextures();
@ -241,7 +240,7 @@ public:
void bake(String outputPath, S32 resolution);
};
typedef ProbeInfo::ProbeShapeType ReflectProbeType;
typedef ProbeRenderInst::ProbeShapeType ReflectProbeType;
DefineEnumType(ReflectProbeType);
typedef ReflectionProbe::IndrectLightingModeType IndrectLightingModeEnum;

View file

@ -150,12 +150,9 @@ void Skylight::unpackUpdate(NetConnection *conn, BitStream *stream)
void Skylight::updateProbeParams()
{
if (mProbeInfo == nullptr)
return;
Parent::updateProbeParams();
mProbeInfo->mProbeShapeType = ProbeInfo::Sphere;
mProbeInfo->mProbeShapeType = ProbeRenderInst::Sphere;
mProbeInfo->setPosition(getPosition());
@ -199,7 +196,7 @@ void Skylight::prepRenderImage(SceneRenderState *state)
// Get a handy pointer to our RenderPassmanager
//RenderPassManager *renderPass = state->getRenderPass();
PROBEMGR->registerSkylight(mProbeInfo, this);
//PROBEMGR->registerSkylight(mProbeInfo, this);
if (Skylight::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
{

View file

@ -109,7 +109,7 @@ public:
// minimizing texture, state, and shader switching by grouping objects that
// use the same Materials.
//--------------------------------------------------------------------------
void updateProbeParams();
virtual void updateProbeParams();
// This is the function that allows this object to submit itself for rendering
void prepRenderImage(SceneRenderState *state);

View file

@ -1,30 +0,0 @@
#pragma once
#include "console/engineAPI.h"
template<typename T>
class SystemInterface
{
public:
bool mIsEnabled;
bool mIsServer;
static Vector<T*> all;
SystemInterface()
{
all.push_back((T*)this);
}
virtual ~SystemInterface()
{
for (U32 i = 0; i < all.size(); i++)
{
if (all[i] == (T*)this)
{
all.erase(i);
return;
}
}
}
};
template<typename T> Vector<T*> SystemInterface<T>::all(0);

View file

@ -1,6 +1,6 @@
#pragma once
#include "scene/sceneRenderState.h"
#include "T3D/systems/componentSystem.h"
#include "core/util/SystemInterfaceList.h"
#include "ts/tsShape.h"
#include "ts/tsShapeInstance.h"
#include "T3D/assets/ShapeAsset.h"

View file

@ -1,5 +1,5 @@
#pragma once
#include "componentSystem.h"
#include "core/util/SystemInterfaceList.h"
class UpdateSystemInterface : public SystemInterface<UpdateSystemInterface>
{

View file

@ -0,0 +1,30 @@
#pragma once
#include "console/engineAPI.h"
template<typename T>
class SystemInterface
{
public:
bool mIsEnabled;
bool mIsServer;
static Vector<T*> all;
SystemInterface()
{
all.push_back((T*)this);
}
virtual ~SystemInterface()
{
for (U32 i = 0; i < all.size(); i++)
{
if (all[i] == (T*)this)
{
all.erase(i);
return;
}
}
}
};
template<typename T> Vector<T*> SystemInterface<T>::all(0);

View file

@ -39,14 +39,18 @@
#include "renderInstance/renderDeferredMgr.h"
#include "shaderGen/shaderGenVars.h"
#include "math/util/sphereMesh.h"
Signal<void(const char*,bool)> ProbeManager::smActivateSignal;
ProbeManager *ProbeManager::smProbeManager = NULL;
bool ProbeManager::smRenderReflectionProbes = true;
//
//
ProbeInfo::ProbeInfo()
: mTransform(true),
ProbeRenderInst::ProbeRenderInst() : SystemInterface(),
mTransform(true),
mDirty(false),
mAmbient(0.0f, 0.0f, 0.0f, 1.0f),
mPriority(1.0f),
mScore(0.0f),
@ -56,7 +60,8 @@ ProbeInfo::ProbeInfo()
mBRDFTexture(NULL),
mRadius(1.0f),
mIntensity(1.0f),
mProbePosOffset(0,0,0)
mProbePosOffset(0,0,0),
numPrims(0)
{
for (U32 i = 0; i < 5; ++i)
{
@ -64,12 +69,26 @@ ProbeInfo::ProbeInfo()
}
}
ProbeInfo::~ProbeInfo()
ProbeRenderInst::~ProbeRenderInst()
{
SAFE_DELETE(mCubemap);
if (mCubemap && !mCubemap->isNull())
{
mCubemap->getPointer()->destroySelf();
mCubemap->free();
}
if (mIrradianceCubemap && !mIrradianceCubemap->isNull())
{
mIrradianceCubemap->getPointer()->destroySelf();
mIrradianceCubemap->free();
}
if (mBRDFTexture && !mBRDFTexture->isNull())
{
mBRDFTexture->getPointer()->destroySelf();
mBRDFTexture->free();
}
}
void ProbeInfo::set(const ProbeInfo *probeInfo)
void ProbeRenderInst::set(const ProbeRenderInst *probeInfo)
{
mTransform = probeInfo->mTransform;
mAmbient = probeInfo->mAmbient;
@ -95,38 +114,12 @@ void ProbeInfo::set(const ProbeInfo *probeInfo)
}
}
void ProbeInfo::getWorldToLightProj(MatrixF *outMatrix) const
void ProbeRenderInst::getWorldToLightProj(MatrixF *outMatrix) const
{
*outMatrix = getTransform();
outMatrix->inverse();
}
void ProbeInfoList::registerProbe(ProbeInfo *light)
{
if (!light)
return;
// just add the light, we'll try to scan for dupes later...
push_back(light);
}
void ProbeInfoList::unregisterProbe(ProbeInfo *light)
{
// remove all of them...
ProbeInfoList &list = *this;
for (U32 i = 0; i<list.size(); i++)
{
if (list[i] != light)
continue;
// this moves last to i, which allows
// the search to continue forward...
list.erase_fast(i);
// want to check this location again...
i--;
}
}
ProbeShaderConstants::ProbeShaderConstants()
: mInit(false),
mShader(NULL),
@ -182,23 +175,23 @@ void ProbeShaderConstants::_onShaderReload()
}
ProbeManager::ProbeManager()
: mDefaultProbe( NULL ),
mSceneManager( NULL ),
: mSceneManager( NULL ),
mCullPos( Point3F::Zero )
{
dMemset( &mSpecialProbes, 0, sizeof(mSpecialProbes) );
mLastShader = NULL;
mLastConstants = NULL;
mSkylightMaterial = nullptr;
mReflectProbeMaterial = nullptr;
}
ProbeManager::~ProbeManager()
{
}
ProbeInfo* ProbeManager::createProbeInfo(ProbeInfo* probe /* = NULL */)
ProbeRenderInst* ProbeManager::createProbeInfo(ProbeRenderInst* probe /* = NULL */)
{
ProbeInfo *outProbe = (probe != NULL) ? probe : new ProbeInfo;
ProbeRenderInst *outProbe = (probe != NULL) ? probe : new ProbeRenderInst;
/*ProbeManagerMap &ProbeManagers = _getProbeManagers();
ProbeManagerMap::Iterator iter = ProbeManagers.begin();
@ -254,182 +247,6 @@ void ProbeManager::deactivate()
//mIsActive = false;
mSceneManager = NULL;
smProbeManager = NULL;
// Just in case... make sure we're all clear.
unregisterAllProbes();
}
ProbeInfo* ProbeManager::getDefaultLight()
{
// The sun is always our default light when
// when its registered.
if ( mSpecialProbes[ ProbeManager::SkylightProbeType ] )
return mSpecialProbes[ ProbeManager::SkylightProbeType ];
// Else return a dummy special light.
//if ( !mDefaultLight )
// mDefaultLight = createLightInfo();
return NULL;
}
ProbeInfo* ProbeManager::getSpecialProbe( ProbeManager::SpecialProbeTypesEnum type, bool useDefault )
{
//if ( mSpecialLights[type] )
// return mSpecialLights[type];
if ( useDefault )
return getDefaultLight();
return NULL;
}
void ProbeManager::setSpecialProbe( ProbeManager::SpecialProbeTypesEnum type, ProbeInfo *probe )
{
if (probe && type == SkylightProbeType )
{
// The sun must be specially positioned and ranged
// so that it can be processed like a point light
// in the stock light shader used by Basic Lighting.
probe->setPosition( mCullPos - (probe->getDirection() * 10000.0f ) );
probe->mRadius = 2000000.0f;
}
mSpecialProbes[type] = probe;
registerProbe(probe, NULL );
}
void ProbeManager::registerProbes( const Frustum *frustum, bool staticLighting )
{
PROFILE_SCOPE( ProbeManager_RegisterProbes );
// TODO: We need to work this out...
//
// 1. Why do we register and unregister lights on every
// render when they don't often change... shouldn't we
// just register once and keep them?
//
// 2. If we do culling of lights should this happen as part
// of registration or somewhere else?
//
// Grab the lights to process.
Vector<SceneObject*> activeLights;
const U32 lightMask = LightObjectType;
if ( staticLighting || !frustum )
{
// We're processing static lighting or want all the lights
// in the container registerd... so no culling.
getSceneManager()->getContainer()->findObjectList( lightMask, &activeLights );
}
else
{
// Cull the lights using the frustum.
getSceneManager()->getContainer()->findObjectList( *frustum, lightMask, &activeLights );
/* supress light culling filter until we can sort out why that's misbehaving with dynamic cube mapping
for (U32 i = 0; i < activeLights.size(); ++i)
{
if (!getSceneManager()->mRenderedObjectsList.contains(activeLights[i]))
{
activeLights.erase(i);
--i;
}
}
*/
// Store the culling position for sun placement
// later... see setSpecialLight.
mCullPos = frustum->getPosition();
// HACK: Make sure the control object always gets
// processed as lights mounted to it don't change
// the shape bounds and can often get culled.
GameConnection *conn = GameConnection::getConnectionToServer();
if ( conn->getControlObject() )
{
GameBase *conObject = conn->getControlObject();
activeLights.push_back_unique( conObject );
}
}
// Let the lights register themselves.
/*for ( U32 i = 0; i < activeLights.size(); i++ )
{
ISceneLight *lightInterface = dynamic_cast<ISceneLight*>( activeLights[i] );
if ( lightInterface )
lightInterface->submitLights( this, staticLighting );
}*/
}
void ProbeManager::registerSkylight(ProbeInfo *probe, SimObject *obj)
{
mSkylight = probe;
if (String("Advanced Lighting").equal(LIGHTMGR->getName(), String::NoCase))
{
SceneRenderState* state = mSceneManager->getCurrentRenderState();
RenderPassManager *renderPass = state->getRenderPass();
// Allocate an MeshRenderInst so that we can submit it to the RenderPassManager
ProbeRenderInst *probeInst = renderPass->allocInst<ProbeRenderInst>();
probeInst->set(probe);
probeInst->type = RenderPassManager::RIT_Probes;
// Submit our RenderInst to the RenderPassManager
state->getRenderPass()->addInst(probeInst);
}
}
void ProbeManager::registerProbe(ProbeInfo *probe, SimObject *obj )
{
// AssertFatal( !mRegisteredProbes.contains(probe),
//"ProbeManager::registerGlobalLight - This light is already registered!" );
if (!mRegisteredProbes.contains(probe))
mRegisteredProbes.push_back(probe);
if (String("Advanced Lighting").equal(LIGHTMGR->getName(), String::NoCase))
{
SceneRenderState* state = mSceneManager->getCurrentRenderState();
RenderPassManager *renderPass = state->getRenderPass();
// Allocate an MeshRenderInst so that we can submit it to the RenderPassManager
ProbeRenderInst *probeInst = renderPass->allocInst<ProbeRenderInst>();
probeInst->set(probe);
probeInst->type = RenderPassManager::RIT_Probes;
// Submit our RenderInst to the RenderPassManager
state->getRenderPass()->addInst(probeInst);
}
}
void ProbeManager::unregisterProbe(ProbeInfo *probe )
{
mRegisteredProbes.unregisterProbe(probe);
// If this is the sun... clear the special light too.
if (probe == mSpecialProbes[SkylightProbeType] )
dMemset(mSpecialProbes, 0, sizeof(mSpecialProbes) );
}
void ProbeManager::unregisterAllProbes()
{
//dMemset(mSpecialProbes, 0, sizeof(mSpecialProbes) );
mRegisteredProbes.clear();
mSkylight = nullptr;
}
void ProbeManager::getAllUnsortedProbes( Vector<ProbeInfo*> *list ) const
{
list->merge( mRegisteredProbes );
}
ProbeShaderConstants* ProbeManager::getProbeShaderConstants(GFXShaderConstBuffer* buffer)
@ -489,7 +306,7 @@ void ProbeManager::_update4ProbeConsts( const SceneData &sgData,
probeRadiusSC->isValid() ||
probeBoxMinSC->isValid() ||
probeBoxMaxSC->isValid() ||
probeCubemapSC->isValid() && (!mRegisteredProbes.empty() || mSkylight))
probeCubemapSC->isValid() && (!ProbeRenderInst::all.empty()))
{
PROFILE_SCOPE(ProbeManager_Update4ProbeConsts_setProbes);
@ -517,21 +334,13 @@ void ProbeManager::_update4ProbeConsts( const SceneData &sgData,
const MatrixF &worldToCameraXfm = matSet.getWorldToCamera();
// Gather the data for the first 4 probes.
const ProbeInfo *probe;
const ProbeRenderInst *probe;
for (U32 i = 0; i < 4; i++)
{
if (i >= mRegisteredProbes.size())
if (i >= ProbeRenderInst::all.size())
break;
if (i == 0 && mSkylight)
{
//quickly try and see if we have a skylight, and set that to always be probe 0
probe = mSkylight;
}
else
{
probe = mRegisteredProbes[i];
}
probe = ProbeRenderInst::all[i];
if (!probe)
continue;
@ -555,7 +364,7 @@ void ProbeManager::_update4ProbeConsts( const SceneData &sgData,
probeBoxMaxs[i].y = maxExt.y;
probeBoxMaxs[i].z = maxExt.z;
probeIsSphere[i] = probe->mProbeShapeType == ProbeInfo::Sphere ? 1.0 : 0.0;
probeIsSphere[i] = probe->mProbeShapeType == ProbeRenderInst::Sphere ? 1.0 : 0.0;
Point3F localProbePos;
worldToCameraXfm.mulP(probe->getPosition(), &localProbePos);
@ -743,6 +552,469 @@ AvailableSLInterfaces* ProbeManager::getSceneLightingInterface()
return NULL;
}
void ProbeManager::updateDirtyProbes()
{
for (U32 i = 0; i < ProbeRenderInst::all.size(); i++)
{
ProbeRenderInst* probe = ProbeRenderInst::all[i];
if (probe->mDirty)
{
//make sure we have a fill-out on our primitives, materials, etc
//so we don't have to always force an update when it's not needed
if (probe->mIsSkylight)
{
setupSkylightProbe(probe);
}
else
{
if (probe->mProbeShapeType == ProbeRenderInst::Sphere)
{
setupSphereReflectionProbe(probe);
}
else if(probe->mProbeShapeType == ProbeRenderInst::Box)
{
setupConvexReflectionProbe(probe);
}
}
probe->mDirty = false;
}
}
}
ProbeManager::SkylightMaterialInfo* ProbeManager::getSkylightMaterial()
{
PROFILE_SCOPE(AdvancedLightBinManager_getSkylightMaterial);
//ReflectProbeMaterialInfo *info = NULL;
if (!mSkylightMaterial)
// Now create the material info object.
mSkylightMaterial = new SkylightMaterialInfo("SklyightMaterial",
getGFXVertexFormat<GFXVertexPC>());
return mSkylightMaterial;
}
ProbeManager::ReflectProbeMaterialInfo* ProbeManager::getReflectProbeMaterial()
{
PROFILE_SCOPE(AdvancedLightBinManager_getReflectProbeMaterial);
//ReflectProbeMaterialInfo *info = NULL;
if (!mReflectProbeMaterial)
// Now create the material info object.
mReflectProbeMaterial = new ReflectProbeMaterialInfo("ReflectionProbeMaterial",
getGFXVertexFormat<GFXVertexPC>());
return mReflectProbeMaterial;
}
void ProbeManager::setupSkylightProbe(ProbeRenderInst *probeInfo)
{
probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer);
if (!mSkylightMaterial)
mSkylightMaterial = getSkylightMaterial();
}
void ProbeManager::setupSphereReflectionProbe(ProbeRenderInst *probeInfo)
{
probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer);
if (!mReflectProbeMaterial)
mReflectProbeMaterial = getReflectProbeMaterial();
}
void ProbeManager::setupConvexReflectionProbe(ProbeRenderInst *probeInfo)
{
static const Point3F cubePoints[8] =
{
Point3F(1, -1, -1), Point3F(1, -1, 1), Point3F(1, 1, -1), Point3F(1, 1, 1),
Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1)
};
/*static const Point3F cubeNormals[6] =
{
Point3F(1, 0, 0), Point3F(-1, 0, 0), Point3F(0, 1, 0),
Point3F(0, -1, 0), Point3F(0, 0, 1), Point3F(0, 0, -1)
};*/
/*static const Point2F cubeTexCoords[4] =
{
Point2F(0, 0), Point2F(0, -1),
Point2F(1, 0), Point2F(1, -1)
};*/
static const U32 cubeFaces[36][3] =
{
{ 3, 0, 3 },{ 0, 0, 0 },{ 1, 0, 1 },
{ 2, 0, 2 },{ 0, 0, 0 },{ 3, 0, 3 },
{ 7, 1, 1 },{ 4, 1, 2 },{ 5, 1, 0 },
{ 6, 1, 3 },{ 4, 1, 2 },{ 7, 1, 1 },
{ 3, 2, 1 },{ 5, 2, 2 },{ 2, 2, 0 },
{ 7, 2, 3 },{ 5, 2, 2 },{ 3, 2, 1 },
{ 1, 3, 3 },{ 4, 3, 0 },{ 6, 3, 1 },
{ 0, 3, 2 },{ 4, 3, 0 },{ 1, 3, 3 },
{ 3, 4, 3 },{ 6, 4, 0 },{ 7, 4, 1 },
{ 1, 4, 2 },{ 6, 4, 0 },{ 3, 4, 3 },
{ 2, 5, 1 },{ 4, 5, 2 },{ 0, 5, 0 },
{ 5, 5, 3 },{ 4, 5, 2 },{ 2, 5, 1 }
};
// Fill the vertex buffer
GFXVertexPC *pVert = NULL;
probeInfo->numVerts = 36;
probeInfo->vertBuffer.set(GFX, 36, GFXBufferTypeStatic);
pVert = probeInfo->vertBuffer.lock();
Point3F halfSize = Point3F(probeInfo->mRadius, probeInfo->mRadius, probeInfo->mRadius);
for (U32 i = 0; i < 36; i++)
{
const U32& vdx = cubeFaces[i][0];
pVert[i].point = cubePoints[vdx] * halfSize;
}
probeInfo->vertBuffer.unlock();
// Fill the primitive buffer
U16 *pIdx = NULL;
probeInfo->primBuffer.set(GFX, 36, 12, GFXBufferTypeStatic);
probeInfo->primBuffer.lock(&pIdx);
for (U16 i = 0; i < 36; i++)
pIdx[i] = i;
probeInfo->primBuffer.unlock();
probeInfo->numPrims = 12;
if (!mReflectProbeMaterial)
mReflectProbeMaterial = getReflectProbeMaterial();
//
// mReflectProbeBin.push_back(pEntry);
}
GFXVertexBufferHandle<GFXVertexPC> ProbeManager::getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives)
{
static SphereMesh sSphereMesh;
if (mSphereGeometry.isNull())
{
const SphereMesh::TriangleMesh * sphereMesh = sSphereMesh.getMesh(3);
S32 numPoly = sphereMesh->numPoly;
mSpherePrimitiveCount = 0;
mSphereGeometry.set(GFX, numPoly * 3, GFXBufferTypeStatic);
mSphereGeometry.lock();
S32 vertexIndex = 0;
for (S32 i = 0; i<numPoly; i++)
{
mSpherePrimitiveCount++;
mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[0];
mSphereGeometry[vertexIndex].color = ColorI::WHITE;
vertexIndex++;
mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[1];
mSphereGeometry[vertexIndex].color = ColorI::WHITE;
vertexIndex++;
mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[2];
mSphereGeometry[vertexIndex].color = ColorI::WHITE;
vertexIndex++;
}
mSphereGeometry.unlock();
}
outNumPrimitives = mSpherePrimitiveCount;
outPrimitives = NULL; // For now
return mSphereGeometry;
}
//
//
bool ReflectProbeMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat)
{
bool success = Parent::init(features, vertexFormat);
// If the initialization failed don't continue.
if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0)
return false;
return true;
}
bool ReflectProbeMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData)
{
// Go no further if the material failed to initialize properly.
if (!mProcessedMaterial ||
mProcessedMaterial->getNumPasses() == 0)
return false;
bool bRetVal = Parent::setupPass(state, sgData);;
AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes");
const RenderPassData *rpd = mProcessedMaterial->getPass(0);
AssertFatal(rpd, "No render pass data!");
AssertFatal(rpd->mRenderStates[0], "No render state 0!");
if (!mProjectionState)
{
GFXStateBlockDesc desc;
desc.setZReadWrite(false);
desc.zWriteEnable = false;
desc.setCullMode(GFXCullNone);
desc.setBlend(true, GFXBlendOne, GFXBlendOne);
mProjectionState = GFX->createStateBlock(desc);
}
// Now override stateblock with our own
GFX->setStateBlock(mProjectionState);
return bRetVal;
}
//
//
ProbeManager::ReflectProbeMaterialInfo::ReflectProbeMaterialInfo(const String &matName,
const GFXVertexFormat *vertexFormat)
: matInstance(NULL),
zNearFarInvNearFar(NULL),
farPlane(NULL),
vsFarPlane(NULL),
negFarPlaneDotEye(NULL),
probeWSPos(NULL),
attenuation(NULL),
radius(NULL),
invViewMat(NULL),
cubeMips(NULL)
{
Material *mat = MATMGR->getMaterialDefinitionByName(matName);
if (!mat)
return;
matInstance = new ReflectProbeMatInstance(*mat);
const Vector<GFXShaderMacro> &macros = Vector<GFXShaderMacro>();
for (U32 i = 0; i < macros.size(); i++)
matInstance->addShaderMacro(macros[i].name, macros[i].value);
matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat);
attenuation = matInstance->getMaterialParameterHandle("$attenuation");
radius = matInstance->getMaterialParameterHandle("$radius");
probeLSPos = matInstance->getMaterialParameterHandle("$probeLSPos");
probeWSPos = matInstance->getMaterialParameterHandle("$probeWSPos");
farPlane = matInstance->getMaterialParameterHandle("$farPlane");
vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane");
negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye");
zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar");
invViewMat = matInstance->getMaterialParameterHandle("$invViewMat");
useCubemap = matInstance->getMaterialParameterHandle("$useCubemap");
cubemap = matInstance->getMaterialParameterHandle("$cubeMap");
cubeMips = matInstance->getMaterialParameterHandle("$cubeMips");
eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
bbMin = matInstance->getMaterialParameterHandle("$bbMin");
bbMax = matInstance->getMaterialParameterHandle("$bbMax");
useSphereMode = matInstance->getMaterialParameterHandle("$useSphereMode");
for (U32 i = 0; i < 9; i++)
shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i));
for (U32 i = 0; i < 5; i++)
shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));
}
ProbeManager::ReflectProbeMaterialInfo::~ReflectProbeMaterialInfo()
{
SAFE_DELETE(matInstance);
}
void ProbeManager::ReflectProbeMaterialInfo::setViewParameters(const F32 _zNear,
const F32 _zFar,
const Point3F &_eyePos,
const PlaneF &_farPlane,
const PlaneF &_vsFarPlane, const MatrixF &_inverseViewMatrix)
{
MaterialParameters *matParams = matInstance->getMaterialParameters();
matParams->setSafe(farPlane, *((const Point4F *)&_farPlane));
matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane));
if (negFarPlaneDotEye->isValid())
{
// -dot( farPlane, eyePos )
const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal);
}
matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar));
matParams->setSafe(invViewMat, _inverseViewMatrix);
Point4F frPlane = *((const Point4F *)&_farPlane);
Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane);
Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar);
const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
}
void ProbeManager::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly)
{
//Set up the params
MaterialParameters *matParams = matInstance->getMaterialParameters();
matParams->setSafe(radius, probeInfo->mRadius);
Point3F probePos = probeInfo->getPosition() + probeInfo->mProbePosOffset;
//worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
matParams->setSafe(probeWSPos, probePos);
worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
matParams->setSafe(probeLSPos, probePos);
// Get the attenuation falloff ratio and normalize it.
Point3F attenRatio = Point3F(0.0f, 1.0f, 1.0f);
F32 total = attenRatio.x + attenRatio.y + attenRatio.z;
if (total > 0.0f)
attenRatio /= total;
F32 radius = probeInfo->mRadius;
Point2F attenParams((1.0f / radius) * attenRatio.y,
(1.0f / (radius * radius)) * attenRatio.z);
matParams->setSafe(attenuation, attenParams);
NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred");
GFXTextureObject *deferredTexObject = deferredTexTarget->getTexture();
if (!deferredTexObject) return;
GFX->setTexture(0, deferredTexObject);
NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo");
GFXTextureObject *matInfoTexObject = matInfoTexTarget->getTexture();
if (!matInfoTexObject) return;
GFX->setTexture(1, matInfoTexObject);
if (probeInfo->mCubemap && !probeInfo->mCubemap->isNull())
{
GFX->setCubeTexture(2, probeInfo->mCubemap->getPointer());
}
else
{
GFX->setCubeTexture(2, NULL);
}
if (probeInfo->mIrradianceCubemap && !probeInfo->mIrradianceCubemap->isNull())
{
GFX->setCubeTexture(3, probeInfo->mIrradianceCubemap->getPointer());
}
else
{
GFX->setCubeTexture(3, NULL);
}
if (probeInfo->mBRDFTexture && !probeInfo->mBRDFTexture->isNull())
{
GFX->setTexture(4, probeInfo->mBRDFTexture->getPointer());
}
else
{
GFX->setTexture(4, NULL);
}
if (probeInfo->mCubemap->isValid())
matParams->setSafe(cubeMips, mPow(probeInfo->mCubemap->getPointer()->getMipMapLevels(), 2.0f));
else
matParams->setSafe(cubeMips, F32(0.0));
matParams->setSafe(eyePosWorld, renderState->getCameraPosition());
matParams->setSafe(bbMin, probeInfo->mBounds.minExtents);
matParams->setSafe(bbMax, probeInfo->mBounds.maxExtents);
matParams->setSafe(useSphereMode, probeInfo->mProbeShapeType == ProbeRenderInst::Sphere ? 1.0f : 0.0f);
//SH Terms
//static AlignedArray<Point3F> shTermsArray(9, sizeof(Point3F));
//dMemset(shTermsArray.getBuffer(), 0, shTermsArray.getBufferSize());
for (U32 i = 0; i < 9; i++)
{
matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]);
}
for (U32 i = 0; i < 5; i++)
{
matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]);
}
const MatrixF worldToObjectXfm = probeInfo->mTransform;
MaterialParameterHandle *worldToObjMat = matInstance->getMaterialParameterHandle("$worldToObj");
matParams->setSafe(worldToObjMat, worldToObjectXfm);
}
//
//
//
ProbeManager::SkylightMaterialInfo::SkylightMaterialInfo(const String &matName,
const GFXVertexFormat *vertexFormat)
: ReflectProbeMaterialInfo(matName, vertexFormat)
{
Material *mat = MATMGR->getMaterialDefinitionByName(matName);
if (!mat)
return;
matInstance = new SkylightMatInstance(*mat);
const Vector<GFXShaderMacro> &macros = Vector<GFXShaderMacro>();
for (U32 i = 0; i < macros.size(); i++)
matInstance->addShaderMacro(macros[i].name, macros[i].value);
matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat);
farPlane = matInstance->getMaterialParameterHandle("$farPlane");
vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane");
negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye");
zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar");
invViewMat = matInstance->getMaterialParameterHandle("$invViewMat");
useCubemap = matInstance->getMaterialParameterHandle("$useCubemap");
cubemap = matInstance->getMaterialParameterHandle("$cubeMap");
eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
for (U32 i = 0; i < 9; i++)
shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i));
for (U32 i = 0; i < 5; i++)
shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));
}
ProbeManager::SkylightMaterialInfo::~SkylightMaterialInfo()
{
SAFE_DELETE(matInstance);
}
/*bool ProbeManager::lightScene( const char* callback, const char* param )
{
BitSet32 flags = 0;

View file

@ -41,6 +41,20 @@
#ifndef _CUBEMAPDATA_H_
#include "gfx/sim/cubemapData.h"
#endif
#ifndef _MATINSTANCE_H_
#include "materials/matInstance.h"
#endif
#ifndef _MATTEXTURETARGET_H_
#include "materials/matTextureTarget.h"
#endif
#ifndef _GFXPRIMITIVEBUFFER_H_
#include "gfx/gfxPrimitiveBuffer.h"
#endif
#ifndef _GFXVERTEXBUFFER_H_
#include "gfx/gfxVertexBuffer.h"
#endif
#include "core/util/SystemInterfaceList.h"
class SimObject;
class ProbeManager;
@ -58,7 +72,7 @@ class SceneRenderState;
class RenderDeferredMgr;
class Frustum;
struct ProbeInfo
struct ProbeRenderInst : public SystemInterface<ProbeRenderInst>
{
LinearColorF mAmbient;
@ -67,6 +81,8 @@ struct ProbeInfo
F32 mRadius;
F32 mIntensity;
bool mDirty;
Box3F mBounds;
Point3F mProbePosOffset;
@ -90,8 +106,8 @@ struct ProbeInfo
/// for this light.
bool mDebugRender;
//GFXPrimitiveBufferHandle primBuffer;
//GFXVertexBufferHandle<GFXVertexPC> vertBuffer;
GFXPrimitiveBufferHandle primBuffer;
GFXVertexBufferHandle<GFXVertexPC> vertBuffer;
U32 numPrims;
U32 numVerts;
Vector< U32 > numIndicesForPoly;
@ -110,11 +126,11 @@ struct ProbeInfo
public:
ProbeInfo();
~ProbeInfo();
ProbeRenderInst();
~ProbeRenderInst();
// Copies data passed in from another probe
void set(const ProbeInfo *probe);
// Copies data passed in from light
void set(const ProbeRenderInst *probeInfo);
// Accessors
const MatrixF& getTransform() const { return mTransform; }
@ -145,13 +161,6 @@ public:
void clear();
};
class ProbeInfoList : public Vector<ProbeInfo*>
{
public:
void registerProbe(ProbeInfo *probe);
void unregisterProbe(ProbeInfo *probe);
};
struct ProbeShaderConstants
{
bool mInit;
@ -179,9 +188,92 @@ struct ProbeShaderConstants
typedef Map<GFXShader*, ProbeShaderConstants*> ProbeConstantMap;
class ReflectProbeMatInstance : public MatInstance
{
typedef MatInstance Parent;
protected:
MaterialParameterHandle * mProbeParamsSC;
bool mInternalPass;
GFXStateBlockRef mProjectionState;
public:
ReflectProbeMatInstance(Material &mat) : Parent(mat), mProbeParamsSC(NULL), mInternalPass(false), mProjectionState(NULL) {}
virtual bool init(const FeatureSet &features, const GFXVertexFormat *vertexFormat);
virtual bool setupPass(SceneRenderState *state, const SceneData &sgData);
};
class SkylightMatInstance : public ReflectProbeMatInstance
{
typedef ReflectProbeMatInstance Parent;
public:
SkylightMatInstance(Material &mat) : Parent(mat) {}
};
class ProbeManager
{
public:
struct ReflectProbeMaterialInfo
{
ReflectProbeMatInstance *matInstance;
// { zNear, zFar, 1/zNear, 1/zFar }
MaterialParameterHandle *zNearFarInvNearFar;
// Far frustum plane (World Space)
MaterialParameterHandle *farPlane;
// Far frustum plane (View Space)
MaterialParameterHandle *vsFarPlane;
// -dot( farPlane, eyePos )
MaterialParameterHandle *negFarPlaneDotEye;
// Inverse View matrix
MaterialParameterHandle *invViewMat;
// Light Parameters
MaterialParameterHandle *probeLSPos;
MaterialParameterHandle *probeWSPos;
MaterialParameterHandle *attenuation;
MaterialParameterHandle *radius;
MaterialParameterHandle *useCubemap;
MaterialParameterHandle *cubemap;
MaterialParameterHandle *cubeMips;
MaterialParameterHandle *eyePosWorld;
MaterialParameterHandle *bbMin;
MaterialParameterHandle *bbMax;
MaterialParameterHandle *useSphereMode;
MaterialParameterHandle *shTerms[9];
MaterialParameterHandle *shConsts[5];
ReflectProbeMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat);
virtual ~ReflectProbeMaterialInfo();
void setViewParameters(const F32 zNear,
const F32 zFar,
const Point3F &eyePos,
const PlaneF &farPlane,
const PlaneF &_vsFarPlane,
const MatrixF &_inverseViewMatrix);
void setProbeParameters(const ProbeRenderInst *probe, const SceneRenderState* renderState, const MatrixF &worldViewOnly);
};
struct SkylightMaterialInfo : public ReflectProbeMaterialInfo
{
SkylightMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat);
virtual ~SkylightMaterialInfo();
};
enum SpecialProbeTypesEnum
{
@ -193,11 +285,8 @@ public:
~ProbeManager();
///
static void initProbeFields();
///
static ProbeInfo* createProbeInfo(ProbeInfo* light = NULL);
static ProbeRenderInst* createProbeInfo(ProbeRenderInst* light = NULL);
/// The light manager activation signal.
static Signal<void(const char*,bool)> smActivateSignal;
@ -217,7 +306,9 @@ public:
// Returns the active scene lighting interface for this light manager.
virtual AvailableSLInterfaces* getSceneLightingInterface();
// Returns a "default" light info that callers should not free. Used for instances where we don't actually care about
void updateDirtyProbes();
/*// Returns a "default" light info that callers should not free. Used for instances where we don't actually care about
// the light (for example, setting default data for SceneData)
virtual ProbeInfo* getDefaultLight();
@ -227,9 +318,9 @@ public:
bool useDefault = true );
/// Set a special light type.
virtual void setSpecialProbe(SpecialProbeTypesEnum type, ProbeInfo *light );
virtual void setSpecialProbe(SpecialProbeTypesEnum type, ProbeInfo *light );*/
void registerSkylight(ProbeInfo *probe, SimObject *obj);
/*void registerSkylight(ProbeInfo *probe, SimObject *obj);
// registered before scene traversal...
virtual void registerProbe(ProbeInfo *light, SimObject *obj );
@ -239,7 +330,7 @@ public:
virtual void unregisterAllProbes();
/// Returns all unsorted and un-scored lights (both global and local).
void getAllUnsortedProbes( Vector<ProbeInfo*> *list ) const;
void getAllUnsortedProbes( Vector<ProbeInfo*> *list ) const;*/
/// Sets shader constants / textures for light infos
virtual void setProbeInfo( ProcessedMaterial *pmat,
@ -255,6 +346,10 @@ public:
const U32 textureSlot,
GFXShaderConstBuffer *shaderConsts,
ShaderConstHandles *handles );
ReflectProbeMaterialInfo* getReflectProbeMaterial();
SkylightMaterialInfo* getSkylightMaterial();
protected:
/// The current active light manager.
@ -265,6 +360,15 @@ protected:
public:
ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer);
// Add a reflection probe to the bin
void setupSkylightProbe(ProbeRenderInst *probeInfo);
void setupSphereReflectionProbe(ProbeRenderInst *probeInfo);
void setupConvexReflectionProbe(ProbeRenderInst *probeInfo);
/// Debug rendering
static bool smRenderReflectionProbes;
protected:
/// This helper function sets the shader constansts
/// for the stock 4 light forward lighting code.
@ -279,19 +383,6 @@ protected:
GFXShaderConstHandle *probeLocalPosSC,
GFXShaderConstBuffer *shaderConsts );
/// A dummy default light used when no lights
/// happen to be registered with the manager.
ProbeInfo *mDefaultProbe;
/// The list of global registered lights which is
/// initialized before the scene is rendered.
ProbeInfoList mRegisteredProbes;
ProbeInfo* mSkylight;
/// The registered special light list.
ProbeInfo *mSpecialProbes[SpecialProbeTypesCount];
/// The root culling position used for
/// special sun light placement.
/// @see setSpecialLight
@ -308,6 +399,19 @@ protected:
GFXShaderRef mLastShader;
ProbeShaderConstants* mLastConstants;
// Convex geometry for lights
GFXVertexBufferHandle<GFXVertexPC> mSphereGeometry;
GFXPrimitiveBufferHandle mSphereIndices;
U32 mSpherePrimitiveCount;
ReflectProbeMaterialInfo* mReflectProbeMaterial;
SkylightMaterialInfo* mSkylightMaterial;
GFXVertexBufferHandle<GFXVertexPC> getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives);;
};
ProbeManager* ProbeManager::getProbeManager()

View file

@ -477,86 +477,4 @@ struct OccluderRenderInst : public RenderInst
void clear();
};
struct ProbeRenderInst : public RenderInst
{
LinearColorF mAmbient;
MatrixF mTransform;
F32 mRadius;
F32 mIntensity;
Box3F mBounds;
Point3F mProbePosOffset;
GFXCubemapHandle *mCubemap;
GFXCubemapHandle *mIrradianceCubemap;
GFXTexHandle *mBRDFTexture;
/// The priority of this light used for
/// light and shadow scoring.
F32 mPriority;
/// A temporary which holds the score used
/// when prioritizing lights for rendering.
F32 mScore;
bool mIsSkylight;
/// Whether to render debugging visualizations
/// for this light.
bool mDebugRender;
GFXPrimitiveBufferHandle primBuffer;
GFXVertexBufferHandle<GFXVertexPC> vertBuffer;
U32 numPrims;
U32 numVerts;
Vector< U32 > numIndicesForPoly;
ProbeInfo::ProbeShapeType mProbeShapeType;
//Spherical Harmonics data
LinearColorF mSHTerms[9];
F32 mSHConstants[5];
public:
ProbeRenderInst();
~ProbeRenderInst();
// Copies data passed in from light
void set(const ProbeRenderInst *probeInfo);
void set(const ProbeInfo *probeInfo);
// Accessors
const MatrixF& getTransform() const { return mTransform; }
void setTransform(const MatrixF &xfm) { mTransform = xfm; }
Point3F getPosition() const { return mTransform.getPosition(); }
void setPosition(const Point3F &pos) { mTransform.setPosition(pos); }
VectorF getDirection() const { return mTransform.getForwardVector(); }
void setDirection(const VectorF &val);
const LinearColorF& getAmbient() const { return mAmbient; }
void setAmbient(const LinearColorF &val) { mAmbient = val; }
void setPriority(F32 priority) { mPriority = priority; }
F32 getPriority() const { return mPriority; }
void setScore(F32 score) { mScore = score; }
F32 getScore() const { return mScore; }
bool isDebugRenderingEnabled() const { return mDebugRender; }
void enableDebugRendering(bool value) { mDebugRender = value; }
// Builds the world to light view projection used for
// shadow texture and cookie lookups.
void getWorldToLightProj(MatrixF *outMatrix) const;
void clear();
};
#endif // _RENDERPASSMANAGER_H_

View file

@ -46,7 +46,7 @@ S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b)
PROFILE_SCOPE(AdvancedLightBinManager_AscendingReflectProbeInfluence);
// Fetch asset definitions.
const ProbeRenderInst* pReflectProbeA = static_cast<ProbeRenderInst*>(((RenderBinManager::MainSortElem*)(a))->inst);
/*const ProbeRenderInst* pReflectProbeA = static_cast<ProbeRenderInst*>(((RenderBinManager::MainSortElem*)(a))->inst);
const ProbeRenderInst* pReflectProbeB = static_cast<ProbeRenderInst*>(((RenderBinManager::MainSortElem*)(b))->inst);
// Sort.
@ -59,22 +59,18 @@ S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b)
if (pReflectProbeA->mScore > pReflectProbeB->mScore)
return 1;
else if (pReflectProbeA->mScore < pReflectProbeB->mScore)
return -1;
return -1;*/
return 0;
}
RenderProbeMgr::RenderProbeMgr()
: RenderBinManager(RenderPassManager::RIT_Probes, 1.0f, 1.0f)
{
mReflectProbeMaterial = nullptr;
mSkylightMaterial = nullptr;
}
RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder)
: RenderBinManager(riType, renderOrder, processAddOrder)
{
mReflectProbeMaterial = nullptr;
mSkylightMaterial = nullptr;
}
void RenderProbeMgr::initPersistFields()
@ -85,12 +81,12 @@ void RenderProbeMgr::initPersistFields()
void RenderProbeMgr::addElement(RenderInst *inst)
{
// If this instance is translucent handle it in RenderTranslucentMgr
if (inst->translucentSort)
//if (inst->translucentSort)
return;
//AssertFatal(inst->defaultKey != 0, "RenderMeshMgr::addElement() - Got null sort key... did you forget to set it?");
internalAddElement(inst);
/*internalAddElement(inst);
ProbeRenderInst* probeInst = static_cast<ProbeRenderInst*>(inst);
@ -104,7 +100,7 @@ void RenderProbeMgr::addElement(RenderInst *inst)
addSphereReflectionProbe(probeInst);
else
addConvexReflectionProbe(probeInst);
}
}*/
}
//remove
@ -112,134 +108,6 @@ void RenderProbeMgr::addElement(RenderInst *inst)
//Con::setIntVariable("lightMetrics::culledReflectProbes", 0/*mNumLightsCulled*/);
//
GFXVertexBufferHandle<GFXVertexPC> RenderProbeMgr::getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives)
{
static SphereMesh sSphereMesh;
if (mSphereGeometry.isNull())
{
const SphereMesh::TriangleMesh * sphereMesh = sSphereMesh.getMesh(3);
S32 numPoly = sphereMesh->numPoly;
mSpherePrimitiveCount = 0;
mSphereGeometry.set(GFX, numPoly * 3, GFXBufferTypeStatic);
mSphereGeometry.lock();
S32 vertexIndex = 0;
for (S32 i = 0; i<numPoly; i++)
{
mSpherePrimitiveCount++;
mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[0];
mSphereGeometry[vertexIndex].color = ColorI::WHITE;
vertexIndex++;
mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[1];
mSphereGeometry[vertexIndex].color = ColorI::WHITE;
vertexIndex++;
mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[2];
mSphereGeometry[vertexIndex].color = ColorI::WHITE;
vertexIndex++;
}
mSphereGeometry.unlock();
}
outNumPrimitives = mSpherePrimitiveCount;
outPrimitives = NULL; // For now
return mSphereGeometry;
}
void RenderProbeMgr::addSkylightProbe(ProbeRenderInst *probeInfo)
{
probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer);
if (!mSkylightMaterial)
mSkylightMaterial = _getSkylightMaterial();
}
void RenderProbeMgr::addSphereReflectionProbe(ProbeRenderInst *probeInfo)
{
probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer);
if (!mReflectProbeMaterial)
mReflectProbeMaterial = _getReflectProbeMaterial();
}
void RenderProbeMgr::addConvexReflectionProbe(ProbeRenderInst *probeInfo)
{
static const Point3F cubePoints[8] =
{
Point3F(1, -1, -1), Point3F(1, -1, 1), Point3F(1, 1, -1), Point3F(1, 1, 1),
Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1)
};
/*static const Point3F cubeNormals[6] =
{
Point3F(1, 0, 0), Point3F(-1, 0, 0), Point3F(0, 1, 0),
Point3F(0, -1, 0), Point3F(0, 0, 1), Point3F(0, 0, -1)
};*/
/*static const Point2F cubeTexCoords[4] =
{
Point2F(0, 0), Point2F(0, -1),
Point2F(1, 0), Point2F(1, -1)
};*/
static const U32 cubeFaces[36][3] =
{
{ 3, 0, 3 },{ 0, 0, 0 },{ 1, 0, 1 },
{ 2, 0, 2 },{ 0, 0, 0 },{ 3, 0, 3 },
{ 7, 1, 1 },{ 4, 1, 2 },{ 5, 1, 0 },
{ 6, 1, 3 },{ 4, 1, 2 },{ 7, 1, 1 },
{ 3, 2, 1 },{ 5, 2, 2 },{ 2, 2, 0 },
{ 7, 2, 3 },{ 5, 2, 2 },{ 3, 2, 1 },
{ 1, 3, 3 },{ 4, 3, 0 },{ 6, 3, 1 },
{ 0, 3, 2 },{ 4, 3, 0 },{ 1, 3, 3 },
{ 3, 4, 3 },{ 6, 4, 0 },{ 7, 4, 1 },
{ 1, 4, 2 },{ 6, 4, 0 },{ 3, 4, 3 },
{ 2, 5, 1 },{ 4, 5, 2 },{ 0, 5, 0 },
{ 5, 5, 3 },{ 4, 5, 2 },{ 2, 5, 1 }
};
// Fill the vertex buffer
GFXVertexPC *pVert = NULL;
probeInfo->numVerts = 36;
probeInfo->vertBuffer.set(GFX, 36, GFXBufferTypeStatic);
pVert = probeInfo->vertBuffer.lock();
Point3F halfSize = Point3F(probeInfo->mRadius, probeInfo->mRadius, probeInfo->mRadius);
for (U32 i = 0; i < 36; i++)
{
const U32& vdx = cubeFaces[i][0];
pVert[i].point = cubePoints[vdx] * halfSize;
}
probeInfo->vertBuffer.unlock();
// Fill the primitive buffer
U16 *pIdx = NULL;
probeInfo->primBuffer.set(GFX, 36, 12, GFXBufferTypeStatic);
probeInfo->primBuffer.lock(&pIdx);
for (U16 i = 0; i < 36; i++)
pIdx[i] = i;
probeInfo->primBuffer.unlock();
probeInfo->numPrims = 12;
if (!mReflectProbeMaterial)
mReflectProbeMaterial = _getReflectProbeMaterial();
//
// mReflectProbeBin.push_back(pEntry);
}
void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)
{
PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters);
@ -298,18 +166,22 @@ void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)
//inverseViewMatrix = MatrixF::Identity;
// Parameters calculated, assign them to the materials
if (mSkylightMaterial != nullptr && mSkylightMaterial->matInstance != nullptr)
ProbeManager::SkylightMaterialInfo* skylightMat = PROBEMGR->getSkylightMaterial();
if (skylightMat != nullptr && skylightMat->matInstance != nullptr)
{
mSkylightMaterial->setViewParameters(frustum.getNearDist(),
skylightMat->setViewParameters(frustum.getNearDist(),
frustum.getFarDist(),
frustum.getPosition(),
farPlane,
vsFarPlane, inverseViewMatrix);
}
if (mReflectProbeMaterial != nullptr && mReflectProbeMaterial->matInstance != nullptr)
ProbeManager::ReflectProbeMaterialInfo* reflProbeMat = PROBEMGR->getReflectProbeMaterial();
if (reflProbeMat != nullptr && reflProbeMat->matInstance != nullptr)
{
mReflectProbeMaterial->setViewParameters(frustum.getNearDist(),
reflProbeMat->setViewParameters(frustum.getNearDist(),
frustum.getFarDist(),
frustum.getPosition(),
farPlane,
@ -325,7 +197,10 @@ void RenderProbeMgr::render( SceneRenderState *state )
PROFILE_SCOPE(RenderProbeMgr_render);
// Early out if nothing to draw.
if(!mElementList.size())
if (!ProbeRenderInst::all.size())
return;
if (!ProbeManager::smRenderReflectionProbes)
return;
GFXTransformSaver saver;
@ -345,6 +220,9 @@ void RenderProbeMgr::render( SceneRenderState *state )
if (probeLightingTargetRef.isNull())
return;
//Do a quick pass to update our probes if they're dirty
PROBEMGR->updateDirtyProbes();
probeLightingTargetRef->attachTexture(GFXTextureTarget::Color0, diffuseLightingTarget->getTexture());
probeLightingTargetRef->attachTexture(GFXTextureTarget::Color1, specularLightingTarget->getTexture());
@ -369,22 +247,28 @@ void RenderProbeMgr::render( SceneRenderState *state )
_setupPerFrameParameters(state);
//Order the probes by size, biggest to smallest
dQsort(mElementList.address(), mElementList.size(), sizeof(const MainSortElem), AscendingReflectProbeInfluence);
//dQsort(mElementList.address(), mElementList.size(), sizeof(const MainSortElem), AscendingReflectProbeInfluence);
//Specular
PROFILE_START(RenderProbeManager_ReflectProbeRender);
for (U32 i = 0; i<mElementList.size(); i++)
ProbeManager::SkylightMaterialInfo* skylightMat = PROBEMGR->getSkylightMaterial();
ProbeManager::ReflectProbeMaterialInfo* reflProbeMat = PROBEMGR->getReflectProbeMaterial();
for (U32 i = 0; i < ProbeRenderInst::all.size(); i++)
{
ProbeRenderInst *curEntry = static_cast<ProbeRenderInst*>(mElementList[i].inst);
ProbeRenderInst* curEntry = ProbeRenderInst::all[i];
if (!curEntry->mIsEnabled)
continue;
if (curEntry->numPrims == 0)
continue;
if (curEntry->mIsSkylight && (!mSkylightMaterial || !mSkylightMaterial->matInstance))
if (curEntry->mIsSkylight && (!skylightMat || !skylightMat->matInstance))
continue;
if (!curEntry->mIsSkylight && (!mReflectProbeMaterial || !mReflectProbeMaterial->matInstance))
if (!curEntry->mIsSkylight && (!reflProbeMat || !reflProbeMat->matInstance))
break;
//Setup
@ -392,7 +276,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
if (!curEntry->mIsSkylight)
{
if (curEntry->mProbeShapeType == ProbeInfo::Sphere)
if (curEntry->mProbeShapeType == ProbeRenderInst::Sphere)
probeTrans.scale(curEntry->mRadius * 1.01f);
}
else
@ -403,9 +287,9 @@ void RenderProbeMgr::render( SceneRenderState *state )
sgData.objTrans = &probeTrans;
if(curEntry->mIsSkylight)
mSkylightMaterial->setSkylightParameters(curEntry, state, worldToCameraXfm);
skylightMat->setProbeParameters(curEntry, state, worldToCameraXfm);
else
mReflectProbeMaterial->setProbeParameters(curEntry, state, worldToCameraXfm);
reflProbeMat->setProbeParameters(curEntry, state, worldToCameraXfm);
// Set geometry
GFX->setVertexBuffer(curEntry->vertBuffer);
@ -413,24 +297,24 @@ void RenderProbeMgr::render( SceneRenderState *state )
if (curEntry->mIsSkylight)
{
while (mSkylightMaterial->matInstance->setupPass(state, sgData))
while (skylightMat->matInstance->setupPass(state, sgData))
{
// Set transforms
matrixSet.setWorld(*sgData.objTrans);
mSkylightMaterial->matInstance->setTransforms(matrixSet, state);
mSkylightMaterial->matInstance->setSceneInfo(state, sgData);
skylightMat->matInstance->setTransforms(matrixSet, state);
skylightMat->matInstance->setSceneInfo(state, sgData);
GFX->drawPrimitive(GFXTriangleList, 0, curEntry->numPrims);
}
}
else
{
while (mReflectProbeMaterial->matInstance->setupPass(state, sgData))
while (reflProbeMat->matInstance->setupPass(state, sgData))
{
// Set transforms
matrixSet.setWorld(*sgData.objTrans);
mReflectProbeMaterial->matInstance->setTransforms(matrixSet, state);
mReflectProbeMaterial->matInstance->setSceneInfo(state, sgData);
reflProbeMat->matInstance->setTransforms(matrixSet, state);
reflProbeMat->matInstance->setSceneInfo(state, sgData);
GFX->drawPrimitive(GFXTriangleList, 0, curEntry->numPrims);
}
@ -440,7 +324,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
probeLightingTargetRef->resolve();
GFX->popActiveRenderTarget();
PROBEMGR->unregisterAllProbes();
//PROBEMGR->unregisterAllProbes();
PROFILE_END();
GFX->setVertexBuffer(NULL);
@ -448,514 +332,4 @@ void RenderProbeMgr::render( SceneRenderState *state )
// Fire off a signal to let others know that light-bin rendering is ending now
//getRenderSignal().trigger(state, this);
}
//
RenderProbeMgr::ReflectProbeMaterialInfo::ReflectProbeMaterialInfo(const String &matName,
const GFXVertexFormat *vertexFormat)
: matInstance(NULL),
zNearFarInvNearFar(NULL),
farPlane(NULL),
vsFarPlane(NULL),
negFarPlaneDotEye(NULL),
probeWSPos(NULL),
attenuation(NULL),
radius(NULL),
invViewMat(NULL)
{
Material *mat = MATMGR->getMaterialDefinitionByName(matName);
if (!mat)
return;
matInstance = new ReflectProbeMatInstance(*mat);
const Vector<GFXShaderMacro> &macros = Vector<GFXShaderMacro>();
for (U32 i = 0; i < macros.size(); i++)
matInstance->addShaderMacro(macros[i].name, macros[i].value);
matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat);
attenuation = matInstance->getMaterialParameterHandle("$attenuation");
radius = matInstance->getMaterialParameterHandle("$radius");
probeLSPos = matInstance->getMaterialParameterHandle("$probeLSPos");
probeWSPos = matInstance->getMaterialParameterHandle("$probeWSPos");
farPlane = matInstance->getMaterialParameterHandle("$farPlane");
vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane");
negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye");
zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar");
invViewMat = matInstance->getMaterialParameterHandle("$invViewMat");
useCubemap = matInstance->getMaterialParameterHandle("$useCubemap");
cubemap = matInstance->getMaterialParameterHandle("$cubeMap");
cubeMips = matInstance->getMaterialParameterHandle("$cubeMips");
eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
bbMin = matInstance->getMaterialParameterHandle("$bbMin");
bbMax = matInstance->getMaterialParameterHandle("$bbMax");
useSphereMode = matInstance->getMaterialParameterHandle("$useSphereMode");
for(U32 i=0; i < 9; i++)
shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d",i));
for (U32 i = 0; i < 5; i++)
shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));
}
RenderProbeMgr::ReflectProbeMaterialInfo::~ReflectProbeMaterialInfo()
{
SAFE_DELETE(matInstance);
}
void RenderProbeMgr::ReflectProbeMaterialInfo::setViewParameters(const F32 _zNear,
const F32 _zFar,
const Point3F &_eyePos,
const PlaneF &_farPlane,
const PlaneF &_vsFarPlane, const MatrixF &_inverseViewMatrix)
{
MaterialParameters *matParams = matInstance->getMaterialParameters();
matParams->setSafe(farPlane, *((const Point4F *)&_farPlane));
matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane));
if (negFarPlaneDotEye->isValid())
{
// -dot( farPlane, eyePos )
const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal);
}
matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar));
matParams->setSafe(invViewMat, _inverseViewMatrix);
Point4F frPlane = *((const Point4F *)&_farPlane);
Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane);
Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar);
const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
}
void RenderProbeMgr::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly)
{
//Set up the params
MaterialParameters *matParams = matInstance->getMaterialParameters();
matParams->setSafe(radius, probeInfo->mRadius);
Point3F probePos = probeInfo->getPosition() + probeInfo->mProbePosOffset;
//worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
matParams->setSafe(probeWSPos, probePos);
worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
matParams->setSafe(probeLSPos, probePos);
// Get the attenuation falloff ratio and normalize it.
Point3F attenRatio = Point3F(0.0f, 1.0f, 1.0f);
F32 total = attenRatio.x + attenRatio.y + attenRatio.z;
if (total > 0.0f)
attenRatio /= total;
F32 radius = probeInfo->mRadius;
Point2F attenParams((1.0f / radius) * attenRatio.y,
(1.0f / (radius * radius)) * attenRatio.z);
matParams->setSafe(attenuation, attenParams);
NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred");
GFXTextureObject *deferredTexObject = deferredTexTarget->getTexture();
if (!deferredTexObject) return;
GFX->setTexture(0, deferredTexObject);
NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo");
GFXTextureObject *matInfoTexObject = matInfoTexTarget->getTexture();
if (!matInfoTexObject) return;
GFX->setTexture(1, matInfoTexObject);
if (probeInfo->mCubemap && !probeInfo->mCubemap->isNull())
{
GFX->setCubeTexture(2, probeInfo->mCubemap->getPointer());
}
else
{
GFX->setCubeTexture(2, NULL);
}
if (probeInfo->mIrradianceCubemap && !probeInfo->mIrradianceCubemap->isNull())
{
GFX->setCubeTexture(3, probeInfo->mIrradianceCubemap->getPointer());
}
else
{
GFX->setCubeTexture(3, NULL);
}
if (probeInfo->mBRDFTexture && !probeInfo->mBRDFTexture->isNull())
{
GFX->setTexture(4, probeInfo->mBRDFTexture->getPointer());
}
else
{
GFX->setTexture(4, NULL);
}
if(probeInfo->mCubemap->isValid())
matParams->setSafe(cubeMips, mPow(probeInfo->mCubemap->getPointer()->getMipMapLevels(),2.0f));
else
matParams->setSafe(cubeMips, F32(0.0));
matParams->setSafe(eyePosWorld, renderState->getCameraPosition());
matParams->setSafe(bbMin, probeInfo->mBounds.minExtents);
matParams->setSafe(bbMax, probeInfo->mBounds.maxExtents);
matParams->setSafe(useSphereMode, probeInfo->mProbeShapeType == ProbeInfo::Sphere ? 1.0f : 0.0f);
//SH Terms
//static AlignedArray<Point3F> shTermsArray(9, sizeof(Point3F));
//dMemset(shTermsArray.getBuffer(), 0, shTermsArray.getBufferSize());
for (U32 i = 0; i < 9; i++)
{
matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]);
}
for (U32 i = 0; i < 5; i++)
{
matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]);
}
}
bool ReflectProbeMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat)
{
bool success = Parent::init(features, vertexFormat);
// If the initialization failed don't continue.
if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0)
return false;
return true;
}
bool ReflectProbeMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData)
{
// Go no further if the material failed to initialize properly.
if (!mProcessedMaterial ||
mProcessedMaterial->getNumPasses() == 0)
return false;
bool bRetVal = Parent::setupPass(state, sgData);;
AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes");
const RenderPassData *rpd = mProcessedMaterial->getPass(0);
AssertFatal(rpd, "No render pass data!");
AssertFatal(rpd->mRenderStates[0], "No render state 0!");
if (!mProjectionState)
{
GFXStateBlockDesc desc;
desc.setZReadWrite(false);
desc.zWriteEnable = false;
desc.setCullMode(GFXCullNone);
desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendOne);
mProjectionState = GFX->createStateBlock(desc);
}
// Now override stateblock with our own
GFX->setStateBlock(mProjectionState);
return bRetVal;
}
RenderProbeMgr::ReflectProbeMaterialInfo* RenderProbeMgr::_getReflectProbeMaterial()
{
PROFILE_SCOPE(AdvancedLightBinManager_getReflectProbeMaterial);
//ReflectProbeMaterialInfo *info = NULL;
if (!mReflectProbeMaterial)
// Now create the material info object.
mReflectProbeMaterial = new ReflectProbeMaterialInfo("ReflectionProbeMaterial",
getGFXVertexFormat<GFXVertexPC>());
return mReflectProbeMaterial;
}
//
RenderProbeMgr::SkylightMaterialInfo::SkylightMaterialInfo(const String &matName,
const GFXVertexFormat *vertexFormat)
: matInstance(NULL),
zNearFarInvNearFar(NULL),
farPlane(NULL),
vsFarPlane(NULL),
negFarPlaneDotEye(NULL),
invViewMat(NULL)
{
Material *mat = MATMGR->getMaterialDefinitionByName(matName);
if (!mat)
return;
matInstance = new SkylightMatInstance(*mat);
const Vector<GFXShaderMacro> &macros = Vector<GFXShaderMacro>();
for (U32 i = 0; i < macros.size(); i++)
matInstance->addShaderMacro(macros[i].name, macros[i].value);
matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat);
farPlane = matInstance->getMaterialParameterHandle("$farPlane");
vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane");
negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye");
zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar");
invViewMat = matInstance->getMaterialParameterHandle("$invViewMat");
useCubemap = matInstance->getMaterialParameterHandle("$useCubemap");
cubemap = matInstance->getMaterialParameterHandle("$cubeMap");
eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
for (U32 i = 0; i < 9; i++)
shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i));
for (U32 i = 0; i < 5; i++)
shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));
}
RenderProbeMgr::SkylightMaterialInfo::~SkylightMaterialInfo()
{
SAFE_DELETE(matInstance);
}
void RenderProbeMgr::SkylightMaterialInfo::setViewParameters(const F32 _zNear,
const F32 _zFar,
const Point3F &_eyePos,
const PlaneF &_farPlane,
const PlaneF &_vsFarPlane, const MatrixF &_inverseViewMatrix)
{
MaterialParameters *matParams = matInstance->getMaterialParameters();
matParams->setSafe(farPlane, *((const Point4F *)&_farPlane));
matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane));
if (negFarPlaneDotEye->isValid())
{
// -dot( farPlane, eyePos )
const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal);
}
matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar));
matParams->setSafe(invViewMat, _inverseViewMatrix);
Point4F frPlane = *((const Point4F *)&_farPlane);
Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane);
Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar);
const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
}
void RenderProbeMgr::SkylightMaterialInfo::setSkylightParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly)
{
//Set up the params
MaterialParameters *matParams = matInstance->getMaterialParameters();
NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred");
GFXTextureObject *deferredTexObject = deferredTexTarget->getTexture();
if (!deferredTexObject) return;
GFX->setTexture(0, deferredTexObject);
NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo");
GFXTextureObject *matInfoTexObject = matInfoTexTarget->getTexture();
if (!matInfoTexObject) return;
GFX->setTexture(1, matInfoTexObject);
if (probeInfo->mCubemap && !probeInfo->mCubemap->isNull())
{
GFX->setCubeTexture(2, probeInfo->mCubemap->getPointer());
}
else
{
GFX->setCubeTexture(2, NULL);
}
if (probeInfo->mIrradianceCubemap && !probeInfo->mIrradianceCubemap->isNull())
{
GFX->setCubeTexture(3, probeInfo->mIrradianceCubemap->getPointer());
}
else
{
GFX->setCubeTexture(3, NULL);
}
if (probeInfo->mBRDFTexture && !probeInfo->mBRDFTexture->isNull())
{
GFX->setTexture(4, probeInfo->mBRDFTexture->getPointer());
}
else
{
GFX->setTexture(4, NULL);
}
matParams->setSafe(eyePosWorld, renderState->getCameraPosition());
for (U32 i = 0; i < 9; i++)
{
matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]);
}
for (U32 i = 0; i < 5; i++)
{
matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]);
}
}
bool SkylightMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat)
{
bool success = Parent::init(features, vertexFormat);
// If the initialization failed don't continue.
if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0)
return false;
return true;
}
bool SkylightMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData)
{
// Go no further if the material failed to initialize properly.
if (!mProcessedMaterial ||
mProcessedMaterial->getNumPasses() == 0)
return false;
bool bRetVal = Parent::setupPass(state, sgData);;
AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes");
const RenderPassData *rpd = mProcessedMaterial->getPass(0);
AssertFatal(rpd, "No render pass data!");
AssertFatal(rpd->mRenderStates[0], "No render state 0!");
if (!mProjectionState)
{
GFXStateBlockDesc desc;
desc.setZReadWrite(false);
desc.zWriteEnable = false;
desc.setCullMode(GFXCullNone);
desc.setBlend(true, GFXBlendOne, GFXBlendOne);
mProjectionState = GFX->createStateBlock(desc);
}
// Now override stateblock with our own
GFX->setStateBlock(mProjectionState);
return bRetVal;
}
RenderProbeMgr::SkylightMaterialInfo* RenderProbeMgr::_getSkylightMaterial()
{
PROFILE_SCOPE(AdvancedLightBinManager_getSkylightMaterial);
//ReflectProbeMaterialInfo *info = NULL;
if (!mSkylightMaterial)
// Now create the material info object.
mSkylightMaterial = new SkylightMaterialInfo("SklyightMaterial",
getGFXVertexFormat<GFXVertexPC>());
return mSkylightMaterial;
}
//
//
ProbeRenderInst::ProbeRenderInst()
: mTransform(true),
mAmbient(0.0f, 0.0f, 0.0f, 1.0f),
mPriority(1.0f),
mScore(0.0f),
mDebugRender(false),
mCubemap(NULL),
mRadius(1.0f),
mIntensity(1.0f)
{
}
ProbeRenderInst::~ProbeRenderInst()
{
SAFE_DELETE(mCubemap);
}
void ProbeRenderInst::set(const ProbeRenderInst *probeInfo)
{
mTransform = probeInfo->mTransform;
mAmbient = probeInfo->mAmbient;
mCubemap = probeInfo->mCubemap;
mIrradianceCubemap = probeInfo->mIrradianceCubemap;
mBRDFTexture = probeInfo->mBRDFTexture;
mRadius = probeInfo->mRadius;
mIntensity = probeInfo->mIntensity;
mProbeShapeType = probeInfo->mProbeShapeType;
numPrims = probeInfo->numPrims;
numVerts = probeInfo->numVerts;
numIndicesForPoly = probeInfo->numIndicesForPoly;
mBounds = probeInfo->mBounds;
mScore = probeInfo->mScore;
mIsSkylight = probeInfo->mIsSkylight;
for (U32 i = 0; i < 9; i++)
{
mSHTerms[i] = probeInfo->mSHTerms[i];
}
for (U32 i = 0; i < 5; i++)
{
mSHConstants[i] = probeInfo->mSHConstants[i];
}
}
void ProbeRenderInst::set(const ProbeInfo *probeInfo)
{
mTransform = probeInfo->mTransform;
mAmbient = probeInfo->mAmbient;
mCubemap = probeInfo->mCubemap;
mIrradianceCubemap = probeInfo->mIrradianceCubemap;
mBRDFTexture = probeInfo->mBRDFTexture;
mRadius = probeInfo->mRadius;
mIntensity = probeInfo->mIntensity;
mProbeShapeType = probeInfo->mProbeShapeType;
numPrims = probeInfo->numPrims;
numVerts = probeInfo->numVerts;
numIndicesForPoly = probeInfo->numIndicesForPoly;
mBounds = probeInfo->mBounds;
mScore = probeInfo->mScore;
mIsSkylight = probeInfo->mIsSkylight;
for (U32 i = 0; i < 9; i++)
{
mSHTerms[i] = probeInfo->mSHTerms[i];
}
for (U32 i = 0; i < 5; i++)
{
mSHConstants[i] = probeInfo->mSHConstants[i];
}
}
void ProbeRenderInst::getWorldToLightProj(MatrixF *outMatrix) const
{
*outMatrix = getTransform();
outMatrix->inverse();
}
}

View file

@ -38,38 +38,6 @@
#include "gfx/gfxVertexBuffer.h"
#endif
class ReflectProbeMatInstance : public MatInstance
{
typedef MatInstance Parent;
protected:
MaterialParameterHandle *mProbeParamsSC;
bool mInternalPass;
GFXStateBlockRef mProjectionState;
public:
ReflectProbeMatInstance(Material &mat) : Parent(mat), mProbeParamsSC(NULL), mInternalPass(false), mProjectionState(NULL){}
virtual bool init(const FeatureSet &features, const GFXVertexFormat *vertexFormat);
virtual bool setupPass(SceneRenderState *state, const SceneData &sgData);
};
class SkylightMatInstance : public MatInstance
{
typedef MatInstance Parent;
protected:
MaterialParameterHandle * mSkylightParamsSC;
bool mInternalPass;
GFXStateBlockRef mProjectionState;
public:
SkylightMatInstance(Material &mat) : Parent(mat), mSkylightParamsSC(NULL), mInternalPass(false), mProjectionState(NULL) {}
virtual bool init(const FeatureSet &features, const GFXVertexFormat *vertexFormat);
virtual bool setupPass(SceneRenderState *state, const SceneData &sgData);
};
//**************************************************************************
// RenderObjectMgr
//**************************************************************************
@ -80,112 +48,9 @@ public:
typedef GFXVertexPNTT FarFrustumQuadVert;
protected:
struct ReflectProbeMaterialInfo
{
ReflectProbeMatInstance *matInstance;
// { zNear, zFar, 1/zNear, 1/zFar }
MaterialParameterHandle *zNearFarInvNearFar;
// Far frustum plane (World Space)
MaterialParameterHandle *farPlane;
// Far frustum plane (View Space)
MaterialParameterHandle *vsFarPlane;
// -dot( farPlane, eyePos )
MaterialParameterHandle *negFarPlaneDotEye;
// Inverse View matrix
MaterialParameterHandle *invViewMat;
// Light Parameters
MaterialParameterHandle *probeLSPos;
MaterialParameterHandle *probeWSPos;
MaterialParameterHandle *attenuation;
MaterialParameterHandle *radius;
MaterialParameterHandle *useCubemap;
MaterialParameterHandle *cubemap;
MaterialParameterHandle *cubeMips;
MaterialParameterHandle *eyePosWorld;
MaterialParameterHandle *bbMin;
MaterialParameterHandle *bbMax;
MaterialParameterHandle *useSphereMode;
MaterialParameterHandle *shTerms[9];
MaterialParameterHandle *shConsts[5];
ReflectProbeMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat);
virtual ~ReflectProbeMaterialInfo();
void setViewParameters(const F32 zNear,
const F32 zFar,
const Point3F &eyePos,
const PlaneF &farPlane,
const PlaneF &_vsFarPlane,
const MatrixF &_inverseViewMatrix);
void setProbeParameters(const ProbeRenderInst *probe, const SceneRenderState* renderState, const MatrixF &worldViewOnly);
};
struct SkylightMaterialInfo
{
SkylightMatInstance *matInstance;
// { zNear, zFar, 1/zNear, 1/zFar }
MaterialParameterHandle *zNearFarInvNearFar;
// Far frustum plane (World Space)
MaterialParameterHandle *farPlane;
// Far frustum plane (View Space)
MaterialParameterHandle *vsFarPlane;
// -dot( farPlane, eyePos )
MaterialParameterHandle *negFarPlaneDotEye;
// Inverse View matrix
MaterialParameterHandle *invViewMat;
MaterialParameterHandle *useCubemap;
MaterialParameterHandle *cubemap;
MaterialParameterHandle *eyePosWorld;
MaterialParameterHandle *shTerms[9];
MaterialParameterHandle *shConsts[5];
SkylightMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat);
virtual ~SkylightMaterialInfo();
void setViewParameters(const F32 zNear,
const F32 zFar,
const Point3F &eyePos,
const PlaneF &farPlane,
const PlaneF &_vsFarPlane,
const MatrixF &_inverseViewMatrix);
void setSkylightParameters(const ProbeRenderInst *probe, const SceneRenderState* renderState, const MatrixF &worldViewOnly);
};
GFXVertexBufferHandle<FarFrustumQuadVert> mFarFrustumQuadVerts;
GFXVertexBufferHandle<GFXVertexPC> getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives);
// Convex geometry for lights
GFXVertexBufferHandle<GFXVertexPC> mSphereGeometry;
GFXPrimitiveBufferHandle mSphereIndices;
U32 mSpherePrimitiveCount;
public:
RenderProbeMgr();
RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder);
@ -198,17 +63,6 @@ public:
// ConsoleObject
static void initPersistFields();
DECLARE_CONOBJECT(RenderProbeMgr);
ReflectProbeMaterialInfo* mReflectProbeMaterial;
ReflectProbeMaterialInfo* _getReflectProbeMaterial();
SkylightMaterialInfo* mSkylightMaterial;
SkylightMaterialInfo* _getSkylightMaterial();
// Add a reflection probe to the bin
void addSkylightProbe(ProbeRenderInst *probeInfo);
void addSphereReflectionProbe(ProbeRenderInst *probeInfo);
void addConvexReflectionProbe(ProbeRenderInst *probeInfo);
};
#endif // RENDER_PROBE_MGR_H

Binary file not shown.

View file

@ -0,0 +1,32 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
singleton CubemapData( HdrSkyCubemap )
{
cubeMap = "./hdrSky.dds";
};
singleton Material( HdrSky )
{
cubemap = HdrSkyCubemap;
materialTag0 = "Skies";
};

View file

@ -0,0 +1,32 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
singleton CubemapData( SkyNightHDRCubemap )
{
cubeMap = "./sky_night_hdr.dds";
};
singleton Material( SkyNightHDR )
{
cubemap = SkyNightHDRCubemap;
materialTag0 = "Skies";
};

View file

@ -0,0 +1,32 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
singleton CubemapData( sky_day_hdr_cubemap )
{
cubeMap = "./sky_day_hdr.dds";
};
singleton Material( sky_day_hdr )
{
cubemap = sky_day_hdr_cubemap;
materialTag0 = "Skies";
};

View file

@ -32,6 +32,12 @@ singleton Material( Grid512_Blue_Mat )
mapTo = "Grid512_Blue_Mat";
diffuseMap[0] = "512_blue";
materialTag0 = "TestMaterial";
smoothness[0] = "1";
metalness[0] = "0.803922";
translucent = "1";
translucentBlendOp = "Add";
diffuseColor[0] = "1 1 1 1";
effectColor[1] = "InvisibleBlack";
};
singleton Material( Grid512_ForestGreen_Mat )

View file

@ -119,18 +119,18 @@ float defineSphereSpaceInfluence(vec3 centroidPosVS, float rad, vec2 atten, vec3
float defineBoxSpaceInfluence(vec3 surfPosWS, vec3 probePos, float rad, vec2 atten) //atten currently unused
{
vec3 boxMin = probePos-(vec3(0.5,0.5,0.5)*rad);
vec3 boxMax = probePos+(vec3(0.5,0.5,0.5)*rad);
//Try to clip anything that falls outside our box as well
//TODO: Make it support rotated boxes as well
if(surfPosWS.x > boxMax.x || surfPosWS.y > boxMax.y || surfPosWS.z > boxMax.z ||
surfPosWS.x < boxMin.x || surfPosWS.y < boxMin.y || surfPosWS.z < boxMin.z)
return -1;
float blendVal = 1;
//vec3 atten = min(boxMax-surfPosWS,surfPosWS-boxMin);
//blendVal = min(min(atten.x,atten.y),atten.z);
return blendVal;
vec3 surfPosLS = mul( worldToObj, vec4(surfPosWS,1.0)).xyz;
vec3 lsBoxMin = mul(worldToObj, vec4(boxMin,1)).xyz;
vec3 lsBoxMax = mul(worldToObj, vec4(boxMax,1)).xyz;
float boxOuterRange = length(lsBoxMax - lsBoxMin);
float boxInnerRange = boxOuterRange / 3.5;
vec3 localDir = vec3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z));
localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange);
return max(localDir.x, max(localDir.y, localDir.z));
}
float defineDepthInfluence(vec3 probePosWS, vec3 surfPosWS, samplerCube radianceCube)
@ -190,7 +190,18 @@ void main()
}
else
{
blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, radius*2, attenuation);
if(worldPos.x > bbMax.x || worldPos.y > bbMax.y || worldPos.z > bbMax.z ||
worldPos.x < bbMin.x || worldPos.y < bbMin.y || worldPos.z < bbMin.z)
{
OUT_col = vec4(0.0);
OUT_col1 = vec4(0.0);
return;
}
blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, bbMin, bbMax, attenuation);
//flip it around
blendVal *= -1;
}
if (blendVal<0)
{

View file

@ -125,24 +125,20 @@ float defineSphereSpaceInfluence(float3 centroidPosVS, float rad, float2 atten,
return saturate( nDotL * attn );
}
float defineBoxSpaceInfluence(float3 surfPosWS, float3 probePos, float rad, float2 atten) //atten currently unused
float defineBoxSpaceInfluence(float3 surfPosWS, float3 probePos, float3 boxMin, float3 boxMax, float2 atten)
{
float3 boxMin = probePos-(float3(0.5,0.5,0.5)*rad);
float3 boxMax = probePos+(float3(0.5,0.5,0.5)*rad);
//rotated boxes
float3 surfPosLS = mul( worldToObj, float4(surfPosWS,1.0)).xyz;
//Try to clip anything that falls outside our box as well
//was surfPosWS
if(surfPosLS.x > boxMax.x || surfPosLS.y > boxMax.y || surfPosLS.z > boxMax.z ||
surfPosLS.x < boxMin.x || surfPosLS.y < boxMin.y || surfPosLS.z < boxMin.z)
return -1;
float blendVal = 1;
//float3 atten = min(boxMax-surfPosWS,surfPosWS-boxMin);
//blendVal = min(min(atten.x,atten.y),atten.z);
return blendVal;
float3 surfPosLS = mul( worldToObj, float4(surfPosWS,1.0)).xyz;
float3 lsBoxMin = mul(worldToObj, float4(boxMin,1)).xyz;
float3 lsBoxMax = mul(worldToObj, float4(boxMax,1)).xyz;
float boxOuterRange = length(lsBoxMax - lsBoxMin);
float boxInnerRange = boxOuterRange / 3.5;
float3 localDir = float3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z));
localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange);
return max(localDir.x, max(localDir.y, localDir.z));
}
float defineDepthInfluence(float3 probePosWS, float3 surfPosWS, TORQUE_SAMPLERCUBE(radianceCube))
@ -196,7 +192,15 @@ PS_OUTPUT main( ConvexConnectP IN )
}
else
{
blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, radius*2, attenuation);
if(worldPos.x > bbMax.x || worldPos.y > bbMax.y || worldPos.z > bbMax.z ||
worldPos.x < bbMin.x || worldPos.y < bbMin.y || worldPos.z < bbMin.z)
clip(-1);
blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, bbMin, bbMax, attenuation);
//flip it around
blendVal *= -1;
//blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, radius*2, attenuation);
}
clip(blendVal);