Cleaned and repacked work to update the probe bin and reflection probe behavior to clean and standardize it.

This commit is contained in:
JeffR 2022-02-12 15:53:40 -06:00
parent 68ae0ca96d
commit 79eebdd5f3
24 changed files with 1113 additions and 1012 deletions

View file

@ -77,7 +77,7 @@ ConsoleDocClass(BoxEnvironmentProbe,
BoxEnvironmentProbe::BoxEnvironmentProbe() : ReflectionProbe()
{
mCaptureMask = REFLECTION_PROBE_CAPTURE_TYPEMASK;
mProbeShapeType = ProbeRenderInst::Box;
mProbeShapeType = ProbeInfo::Box;
mAtten = 0.0;
}
@ -158,7 +158,7 @@ void BoxEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
void BoxEnvironmentProbe::updateProbeParams()
{
mProbeShapeType = ProbeRenderInst::Box;
mProbeShapeType = ProbeInfo::Box;
mProbeInfo.mAtten = mAtten;
Parent::updateProbeParams();

View file

@ -73,8 +73,8 @@ ConsoleDocClass(ReflectionProbe,
ImplementEnumType(ReflectProbeType,
"Type of mesh data available in a shape.\n"
"@ingroup gameObjects")
{ ProbeRenderInst::Sphere, "Sphere", "Sphere shaped" },
{ ProbeRenderInst::Box, "Box", "Box shape" }
{ ReflectionProbe::ProbeInfo::Sphere, "Sphere", "Sphere shaped" },
{ ReflectionProbe::ProbeInfo::Box, "Box", "Box shape" }
EndImplementEnumType;
ImplementEnumType(ReflectionModeEnum,
@ -97,7 +97,7 @@ ReflectionProbe::ReflectionProbe()
mTypeMask = LightObjectType | MarkerObjectType;
mProbeShapeType = ProbeRenderInst::Box;
mProbeShapeType = ProbeInfo::Box;
mReflectionModeType = BakedCubemap;
@ -121,8 +121,6 @@ ReflectionProbe::ReflectionProbe()
mRefreshRateMS = 200;
mDynamicLastBakeMS = 0;
mMaxDrawDistance = 75;
mResourcesCreated = false;
mPrefilterSize = 64;
mPrefilterMipLevels = mLog2(F32(mPrefilterSize));
@ -239,7 +237,7 @@ bool ReflectionProbe::_setRadius(void *object, const char *index, const char *da
{
ReflectionProbe* probe = reinterpret_cast<ReflectionProbe*>(object);
if (probe->mProbeShapeType != ProbeRenderInst::Sphere)
if (probe->mProbeShapeType != ProbeInfo::Sphere)
return false;
probe->mObjScale = Point3F(probe->mRadius, probe->mRadius, probe->mRadius);
@ -291,7 +289,7 @@ bool ReflectionProbe::onAdd()
if (!mPersistentId)
mPersistentId = getOrCreatePersistentId();
mProbeUniqueID = String::ToString(mPersistentId->getUUID().getHash());
mProbeUniqueID = mPersistentId->getUUID().toString();
}
// Refresh this object's material (if any)
@ -312,7 +310,7 @@ void ReflectionProbe::onRemove()
{
if (isClientObject())
{
PROBEMGR->unregisterProbe(mProbeInfo.mProbeIdx);
PROBEMGR->unregisterProbe(&mProbeInfo);
}
// Remove this object from the scene
@ -461,10 +459,10 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
if (stream->readFlag()) // StaticDataMask
{
U32 shapeType = ProbeRenderInst::Sphere;
U32 shapeType = ProbeInfo::Sphere;
stream->read(&shapeType);
mProbeShapeType = (ProbeRenderInst::ProbeShapeType)shapeType;
mProbeShapeType = (ProbeInfo::ProbeShapeType)shapeType;
stream->read(&mRadius);
@ -497,6 +495,8 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
//-----------------------------------------------------------------------------
void ReflectionProbe::updateProbeParams()
{
mProbeInfo.mObject = this;
if (!mResourcesCreated)
{
if (!createClientResources())
@ -507,12 +507,12 @@ void ReflectionProbe::updateProbeParams()
mProbeInfo.mProbeShapeType = mProbeShapeType;
if (mProbeShapeType == ProbeRenderInst::Sphere)
if (mProbeShapeType == ProbeInfo::Sphere)
mObjScale.set(mRadius, mRadius, mRadius);
Box3F bounds;
if (mProbeShapeType == ProbeRenderInst::Skylight)
if (mProbeShapeType == ProbeInfo::Skylight)
{
mProbeInfo.mPosition = Point3F::Zero;
mProbeInfo.mTransform = MatrixF::Identity;
@ -564,8 +564,6 @@ void ReflectionProbe::updateProbeParams()
else
processDynamicCubemap();
}
PROBEMGR->updateProbes();
}
void ReflectionProbe::processDynamicCubemap()
@ -575,7 +573,7 @@ void ReflectionProbe::processDynamicCubemap()
void ReflectionProbe::processBakedCubemap()
{
mProbeInfo.mIsEnabled = false;
//mProbeInfo.mIsEnabled = false;
if ((mReflectionModeType != BakedCubemap) || mProbeUniqueID.isEmpty())
return;
@ -611,7 +609,7 @@ void ReflectionProbe::processBakedCubemap()
if (mEnabled && mProbeInfo.mPrefilterCubemap->isInitialized() && mProbeInfo.mIrradianceCubemap->isInitialized())
{
mProbeInfo.mIsEnabled = true;
//mProbeInfo.mIsEnabled = true;
mCubemapDirty = false;
@ -622,6 +620,11 @@ void ReflectionProbe::processBakedCubemap()
mProbeInfo.mPrefilterCubemap.free();
mProbeInfo.mIrradianceCubemap.free();
}
else
{
//if we failed, disable
mProbeInfo.mIsEnabled = false;
}
}
void ReflectionProbe::processStaticCubemap()
@ -811,16 +814,16 @@ void ReflectionProbe::createEditorResources()
void ReflectionProbe::prepRenderImage(SceneRenderState *state)
{
if (!mEnabled || !RenderProbeMgr::smRenderReflectionProbes)
if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes && Con::getVariable("$Probes::Capturing", "0") == "0"))
return;
Point3F distVec = getRenderPosition() - state->getCameraPosition();
F32 dist = distVec.len();
//Culling distance. Can be adjusted for performance options considerations via the scalar
if (dist > mMaxDrawDistance * Con::getFloatVariable("$pref::GI::ProbeDrawDistScale", 1.0))
if (dist > RenderProbeMgr::smMaxProbeDrawDistance * Con::getFloatVariable("$pref::GI::ProbeDrawDistScale", 1.0))
{
mProbeInfo.mScore = mMaxDrawDistance;
mProbeInfo.mScore = RenderProbeMgr::smMaxProbeDrawDistance;
return;
}
@ -842,7 +845,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
//mProbeInfo.mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
PROBEMGR->submitProbe(mProbeInfo);
PROBEMGR->submitProbe(&mProbeInfo);
#ifdef TORQUE_TOOLS
if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mPrefilterMap != nullptr)
@ -938,7 +941,7 @@ void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri,
ColorI color = ColorI(255, 0, 255, 63);
const MatrixF worldToObjectXfm = mObjToWorld;
if (mProbeShapeType == ProbeRenderInst::Sphere)
if (mProbeShapeType == ProbeInfo::Sphere)
{
draw->drawSphere(desc, mRadius, getPosition(), color);
}

View file

@ -41,10 +41,6 @@
#include "renderInstance/renderPassManager.h"
#endif
#ifndef RENDER_PROBE_MGR_H
#include "renderInstance/renderProbeMgr.h"
#endif
class BaseMatInstance;
//-----------------------------------------------------------------------------
@ -74,6 +70,67 @@ public:
DynamicCubemap = 5,
};
/// <summary>
/// This contains all the important data the Probe uses for rendering.
/// </summary>
struct ProbeInfo
{
bool mIsEnabled;
MatrixF mTransform;
ReflectionProbe* mObject;
F32 mRadius;
bool mDirty;
Box3F mBounds;
Point3F mExtents;
Point3F mPosition;
Point3F mProbeRefOffset;
Point3F mProbeRefScale;
F32 mAtten;
F32 mScore;
GFXCubemapHandle mPrefilterCubemap;
GFXCubemapHandle mIrradianceCubemap;
/// The priority of this light used for
/// light and shadow scoring.
F32 mPriority;
enum ProbeShapeType
{
Box = 0,
Sphere = 1,
Skylight = 2
};
ProbeShapeType mProbeShapeType;
public:
ProbeInfo() : mScore(0) {}
~ProbeInfo() {}
// Copies data passed in from light
void set(const ProbeInfo* probeInfo);
// Accessors
const MatrixF& getTransform() const { return mTransform; }
void setTransform(const MatrixF& xfm) { mTransform = xfm; }
Point3F getPosition() const { return mPosition; }
void setPosition(const Point3F& pos) { mPosition = pos; }
void setPriority(F32 priority) { mPriority = priority; }
F32 getPriority() const { return mPriority; }
void clear();
};
protected:
// Networking masks
@ -124,7 +181,7 @@ protected:
/// <summary>
/// The shape of the probe
/// </summary>
ProbeRenderInst::ProbeShapeType mProbeShapeType;
ProbeInfo::ProbeShapeType mProbeShapeType;
/// <summary>
/// This is effectively a packed cache of the probe data actually utilized for rendering.
@ -132,7 +189,7 @@ protected:
/// When the manager goes to render it has the compacted data to read over more efficiently for setting up what probes should
/// Actually render in that frame
/// </summary>
ProbeRenderInst mProbeInfo;
ProbeInfo mProbeInfo;
/// <summary>
/// Used to dictate what sort of cubemap the probes use when using IBL
@ -166,14 +223,13 @@ protected:
CubemapData *mStaticCubemap;
GFXCubemapHandle mDynamicCubemap;
String cubeDescName;
U32 cubeDescId;
ReflectorDesc *reflectorDesc;
//String cubeDescName;
//U32 cubeDescId;
//ReflectorDesc *reflectorDesc;
//Utilized in dynamic reflections
//CubeReflector mCubeReflector;
///Prevents us from saving out the cubemaps(for now) but allows us the full HDR range on the in-memory cubemap captures
bool mUseHDRCaptures;
//irridiance resources
@ -196,7 +252,6 @@ protected:
U32 mDynamicLastBakeMS;
U32 mRefreshRateMS;
F32 mMaxDrawDistance;
bool mResourcesCreated;
U32 mCaptureMask;
@ -313,7 +368,7 @@ public:
void bake();
};
typedef ProbeRenderInst::ProbeShapeType ReflectProbeType;
typedef ReflectionProbe::ProbeInfo::ProbeShapeType ReflectProbeType;
DefineEnumType(ReflectProbeType);
typedef ReflectionProbe::ReflectionModeType ReflectionModeEnum;

View file

@ -148,7 +148,7 @@ void Skylight::unpackUpdate(NetConnection *conn, BitStream *stream)
void Skylight::updateProbeParams()
{
mProbeShapeType = ProbeRenderInst::Skylight;
mProbeShapeType = ProbeInfo::Skylight;
Parent::updateProbeParams();
}
@ -167,7 +167,7 @@ void Skylight::prepRenderImage(SceneRenderState *state)
// Get a handy pointer to our RenderPassmanager
//RenderPassManager *renderPass = state->getRenderPass();
PROBEMGR->submitProbe(mProbeInfo);
PROBEMGR->submitProbe(&mProbeInfo);
#ifdef TORQUE_TOOLS
if (Skylight::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)

View file

@ -77,7 +77,7 @@ ConsoleDocClass(SphereEnvironmentProbe,
SphereEnvironmentProbe::SphereEnvironmentProbe() : ReflectionProbe()
{
mCaptureMask = REFLECTION_PROBE_CAPTURE_TYPEMASK;
mProbeShapeType = ProbeRenderInst::Sphere;
mProbeShapeType = ProbeInfo::Sphere;
}
SphereEnvironmentProbe::~SphereEnvironmentProbe()
@ -144,83 +144,10 @@ void SphereEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream
void SphereEnvironmentProbe::updateProbeParams()
{
mProbeShapeType = ProbeRenderInst::Sphere;
mProbeShapeType = ProbeInfo::Sphere;
Parent::updateProbeParams();
}
void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state)
{
if (!mEnabled || !ReflectionProbe::smRenderPreviewProbes)
return;
#ifdef TORQUE_TOOLS
if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
{
GFXTransformSaver saver;
// Calculate the distance of this object from the camera
Point3F cameraOffset;
getRenderTransform().getColumn(3, &cameraOffset);
cameraOffset -= state->getDiffuseCameraPosition();
F32 dist = cameraOffset.len();
if (dist < 0.01f)
dist = 0.01f;
// Set up the LOD for the shape
F32 invScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
mEditorShapeInst->setDetailFromDistance(state, dist * invScale);
// Make sure we have a valid level of detail
if (mEditorShapeInst->getCurrentDetail() < 0)
return;
BaseMatInstance* probePrevMat = mEditorShapeInst->getMaterialList()->getMaterialInst(0);
setPreviewMatParameters(state, probePrevMat);
// GFXTransformSaver is a handy helper class that restores
// the current GFX matrices to their original values when
// it goes out of scope at the end of the function
// Set up our TS render state
TSRenderState rdata;
rdata.setSceneState(state);
rdata.setFadeOverride(1.0f);
// We might have some forward lit materials
// so pass down a query to gather lights.
LightQuery query;
query.init(getWorldSphere());
rdata.setLightQuery(&query);
// Set the world matrix to the objects render transform
MatrixF mat = getRenderTransform();
mat.scale(Point3F(1, 1, 1));
GFX->setWorldMatrix(mat);
// Animate the the shape
mEditorShapeInst->animate();
// Allow the shape to submit the RenderInst(s) for itself
mEditorShapeInst->render(rdata);
saver.restore();
}
// If the light is selected or light visualization
// is enabled then register the callback.
const bool isSelectedInEditor = (gEditingMission && isSelected());
if (isSelectedInEditor)
{
ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
ri->renderDelegate.bind(this, &ReflectionProbe::_onRenderViz);
ri->type = RenderPassManager::RIT_Editor;
state->getRenderPass()->addInst(ri);
}
#endif
}
void SphereEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat)
{
Parent::setPreviewMatParameters(renderState, mat);

View file

@ -98,10 +98,6 @@ public:
// use the same Materials.
//--------------------------------------------------------------------------
virtual void updateProbeParams();
// This is the function that allows this object to submit itself for rendering
void prepRenderImage(SceneRenderState *state);
void setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat);
};

View file

@ -970,14 +970,6 @@ void ScatterSky::_render( ObjectRenderInst *ri, SceneRenderState *state, BaseMat
xform *= GFX->getViewMatrix();
xform *= GFX->getWorldMatrix();
if(state->isReflectPass())
{
static MatrixF rotMat(EulerF(0.0, 0.0, M_PI_F));
xform.mul(rotMat);
rotMat.set(EulerF(M_PI_F, 0.0, 0.0));
xform.mul(rotMat);
}
mShaderConsts->setSafe( mModelViewProjSC, xform );
mShaderConsts->setSafe( mMiscSC, miscParams );
mShaderConsts->setSafe( mSphereRadiiSC, sphereRadii );

File diff suppressed because it is too large Load diff

View file

@ -39,7 +39,7 @@
#include "gfx/gfxVertexBuffer.h"
#endif
#include "core/util/systemInterfaceList.h"
//#include "core/util/systemInterfaceList.h"
#ifndef _MATERIALS_PROCESSEDSHADERMATERIAL_H_
#include "materials/processedShaderMaterial.h"
@ -52,52 +52,23 @@
#include "scene/reflector.h"
#endif
static U32 MAXPROBECOUNT = 50;
#ifndef REFLECTIONPROBE_H
#include "T3D/lighting/reflectionProbe.h"
#endif
class PostEffect;
class ReflectionProbe;
/// <summary>
/// A simple container for a ReflectionProbe's ProbeInfo and index for it's associated
/// cubemaps in the cubemap array pair
/// </summary>
struct ProbeRenderInst
{
bool mIsEnabled;
MatrixF mTransform;
F32 mRadius;
bool mDirty;
Box3F mBounds;
Point3F mExtents;
Point3F mPosition;
Point3F mProbeRefOffset;
Point3F mProbeRefScale;
F32 mAtten;
GFXCubemapHandle mPrefilterCubemap;
GFXCubemapHandle mIrradianceCubemap;
/// 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;
enum ProbeShapeType
{
Box = 0, ///< Sphere shaped
Sphere = 1, ///< Box-based shape
Skylight = 2
};
ProbeShapeType mProbeShapeType;
ReflectionProbe::ProbeInfo* mProbeInfo;
U32 mCubemapIndex;
U32 mProbeIdx;
public:
ProbeRenderInst();
@ -105,28 +76,11 @@ public:
// Copies data passed in from light
void set(const ProbeRenderInst *probeInfo);
// Accessors
const MatrixF& getTransform() const { return mTransform; }
void setTransform(const MatrixF &xfm) { mTransform = xfm; }
Point3F getPosition() const { return mPosition; }
void setPosition(const Point3F &pos) { mPosition = pos; }
void setPriority(F32 priority) { mPriority = priority; }
F32 getPriority() const { return mPriority; }
void setScore(F32 score) { mScore = score; }
F32 getScore() const { return mScore; }
void clear();
inline bool operator ==(const ProbeRenderInst& b) const
{
return mProbeIdx == b.mProbeIdx;
}
};
/// <summary>
/// A container for all the shader consts needed for rendering probes in forward mode
/// </summary>
struct ProbeShaderConstants
{
bool mInit;
@ -134,19 +88,21 @@ struct ProbeShaderConstants
GFXShaderRef mShader;
//Reflection Probes
GFXShaderConstHandle *mProbePositionSC;
GFXShaderConstHandle *mProbeRefPosSC;
GFXShaderConstHandle *mRefScaleSC;
GFXShaderConstHandle *mProbePositionArraySC;
GFXShaderConstHandle *mProbeRefPosArraySC;
GFXShaderConstHandle *mRefScaleArraySC;
GFXShaderConstHandle *mWorldToObjArraySC;
GFXShaderConstHandle *mProbeConfigDataSC;
GFXShaderConstHandle *mProbeSpecularCubemapSC;
GFXShaderConstHandle *mProbeIrradianceCubemapSC;
GFXShaderConstHandle *mProbeConfigDataArraySC;
GFXShaderConstHandle *mProbeSpecularCubemapArraySC;
GFXShaderConstHandle *mProbeIrradianceCubemapArraySC;
GFXShaderConstHandle *mProbeCountSC;
GFXShaderConstHandle *mBRDFTextureMap;
GFXShaderConstHandle *mSkylightCubemapIdxSC;
GFXShaderConstHandle* mMaxProbeDrawDistanceSC;
ProbeShaderConstants();
~ProbeShaderConstants();
@ -159,6 +115,10 @@ struct ProbeShaderConstants
typedef Map<GFXShader*, ProbeShaderConstants*> ProbeConstantMap;
/// <summary>
/// A container for processed and packed probe data. This is made when we get the frame's
/// best probes, and is passed to the shader for actual rendering.
/// </summary>
struct ProbeDataSet
{
Vector<Point4F> probePositionArray;
@ -198,18 +158,10 @@ struct ProbeDataSet
probeWorldToObjArray.setSize(maxProbeCount);
skyLightIdx = -1;
effectiveProbeCount = 0;
}
};
struct ProbeTextureArrayData
{
GFXTexHandle BRDFTexture;
GFXCubemapArrayHandle prefilterArray;
GFXCubemapArrayHandle irradianceArray;
};
//**************************************************************************
// RenderObjectMgr
//**************************************************************************
@ -217,11 +169,6 @@ class RenderProbeMgr : public RenderBinManager
{
typedef RenderBinManager Parent;
Vector<ProbeRenderInst*> mRegisteredProbes;
bool mProbesDirty;
Vector<ProbeRenderInst> mActiveProbes;
public:
//maximum number of allowed probes
static const U32 PROBE_MAX_COUNT = 250;
@ -230,51 +177,161 @@ public:
//number of slots to allocate at once in the cubemap array
static const U32 PROBE_ARRAY_SLOT_BUFFER_SIZE = 10;
static const U32 PROBE_IRRAD_SIZE = 64;
static const U32 PROBE_PREFILTER_SIZE = 64;
//These dictate the default resolution size for the probe arrays
static const GFXFormat PROBE_FORMAT = GFXFormatR16G16B16A16F;// GFXFormatR8G8B8A8;// when hdr fixed GFXFormatR16G16B16A16F; look into bc6h compression
static const U32 INVALID_CUBE_SLOT = U32_MAX;
static F32 smMaxProbeDrawDistance;
static S32 smMaxProbesPerFrame;
static S32 smProbeBakeResolution;
SceneRenderState *mState;
private:
//Array rendering
U32 mEffectiveProbeCount;
S32 mMipCount;
/// <summary>
/// List of registered probes. These are not necessarily rendered in a given frame
/// but the Probe Manager is aware of them and they have cubemap array slots allocated
/// </summary>
Vector<ProbeRenderInst> mRegisteredProbes;
/// <summary>
/// List of active probes. These are ones that are not only registered, but submitted by the probe itself as
/// ready to be rendered. Likely to be rendered in the current frame, settings-dependent.
/// </summary>
Vector<ProbeRenderInst> mActiveProbes;
/// <summary>
/// The PostEffect used to actually rendered the probes into the frame when in deferred mode
/// </summary>
SimObjectPtr<PostEffect> mProbeArrayEffect;
/// <summary>
/// Do we have a active skylight probe
/// </summary>
bool mHasSkylight;
/// <summary>
/// If we have a skylight, what's the array pair index for it?
/// </summary>
S32 mSkylightCubemapIdx;
//number of cubemaps
/// <summary>
/// The 'effective' probe count. This tracks the number of probes that are actually going to be rendered
/// </summary>
U32 mEffectiveProbeCount;
//
//Array rendering
/// <summary>
/// The number of mips the cubemap array has. Mips are used in the PBR calcs for handling roughness
/// </summary>
S32 mMipCount;
/// <summary>
/// The number of cubemaps registered in our array pair
/// </summary>
U32 mCubeMapCount;
//number of cubemap slots allocated
/// <summary>
/// The number of allocated slots for the array pair. Rather than adding slots one at a time to the arrays
/// We allocate in chunks so we don't have to resize/rebuild the arrays as often
/// </summary>
U32 mCubeSlotCount;
//array of cubemap slots, due to the editor these may be mixed around as probes are added and deleted
/// <summary>
/// List indicating if a given allocated slot is actually in use.
/// Due to the editor these may be mixed around as probes are added and deleted
/// </summary>
/// <returns></returns>
bool mCubeMapSlots[PROBE_MAX_COUNT];
/// <summary>
/// The prefilter cubemap array
/// </summary>
GFXCubemapArrayHandle mPrefilterArray;
/// <summary>
/// The irradiance cubemap array
/// </summary>
GFXCubemapArrayHandle mIrradianceArray;
//Utilized in forward rendering
/// <summary>
/// This is used to look up already-made ProbeShaderConsts for a given shader
/// This allows us to avoid having to rebuild the consts each frame if it's a shader
/// we've already handled before.
/// </summary>
ProbeConstantMap mConstantLookup;
/// <summary>
/// The last shader we rendered(in forward mode). With this, we can shortcut the constant
/// lookup if the shader being processed and the last one are the same.
/// </summary>
GFXShaderRef mLastShader;
/// <summary>
/// THe previous shader constants. When used in conjunction with the mLastShader, we can skip
/// having to do a lookup to find an existing ProbeShaderConstants, saving overhead on batched
/// rendering
/// </summary>
ProbeShaderConstants* mLastConstants;
//
SimObjectPtr<PostEffect> mProbeArrayEffect;
//Default skylight, used for shape editors, etc
ProbeRenderInst* mDefaultSkyLight;
/// <summary>
/// The BRDF texture used in PBR math calculations
/// </summary>
GFXTexHandle mBRDFTexture;
/// <summary>
/// Processed best probe selection list of the current frame when rendering in deferred mode.
/// </summary>
ProbeDataSet mProbeData;
///Prevents us from saving out the cubemaps(for now) but allows us the full HDR range on the in-memory cubemap captures
/// <summary>
/// Allows us the full HDR range on the in-memory cubemap captures
/// </summary>
bool mUseHDRCaptures;
U32 mPrefilterMipLevels;
U32 mPrefilterSize;
protected:
/// The current active light manager.
static RenderProbeMgr* smProbeManager;
//=============================================================================
// Internal Management/Utility Functions
//=============================================================================
/// <summary>
/// Simple utility function that finds the next free cubemap slot for the cubemap array
/// </summary>
/// <returns>U32 index of next available slot</returns>
U32 _findNextEmptyCubeSlot()
{
for (U32 i = 0; i < PROBE_MAX_COUNT; i++)
{
if (!mCubeMapSlots[i])
return i;
}
return INVALID_CUBE_SLOT;
}
/// <summary>
/// Utility function to quickly find a ProbeRenderInst in association to a
/// ReflectionProbe's ProbeInfo
/// </summary>
/// <param name="probeInfo"></param>
/// <returns>Associated ProbeRederInst to param's probeInfo. Null if no matches found</returns>
ProbeRenderInst* findProbeInst(ReflectionProbe::ProbeInfo* probeInfo)
{
for (U32 i = 0; i < mRegisteredProbes.size(); i++)
{
auto asd = mRegisteredProbes[i];
if (mRegisteredProbes[i].mProbeInfo == probeInfo)
{
return &mRegisteredProbes[i];
}
}
return nullptr;
}
public:
RenderProbeMgr();
RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder);
@ -286,75 +343,139 @@ public:
static void initPersistFields();
static void consoleInit();
virtual void addElement(RenderInst* inst) {};
DECLARE_CONOBJECT(RenderProbeMgr);
protected:
/// The current active light manager.
static RenderProbeMgr *smProbeManager;
/// This helper function sets the shader constansts
/// for the stock 4 light forward lighting code.
void _update4ProbeConsts(const SceneData &sgData,
MatrixSet &matSet,
ProbeShaderConstants *probeShaderConsts,
GFXShaderConstBuffer *shaderConsts);
void _setupStaticParameters();
void _setupPerFrameParameters(const SceneRenderState *state);
virtual void addElement(RenderInst* inst) {};
virtual void render(SceneRenderState * state);
ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer);
PostEffect* getProbeArrayEffect();
U32 _findNextEmptyCubeSlot()
{
for (U32 i = 0; i < PROBE_MAX_COUNT; i++)
{
if (!mCubeMapSlots[i])
return i;
}
return INVALID_CUBE_SLOT;
}
public:
// RenderBinMgr
void updateProbes();
/// Returns the active LM.
static inline RenderProbeMgr* getProbeManager();
void registerProbe(ProbeRenderInst* newProbe);
void unregisterProbe(U32 probeIdx);
void submitProbe(const ProbeRenderInst& newProbe);
static S32 QSORT_CALLBACK _probeScoreCmp(const ProbeRenderInst* a, const ProbeRenderInst* b);
virtual void setProbeInfo(ProcessedMaterial *pmat,
const Material *mat,
const SceneData &sgData,
const SceneRenderState *state,
U32 pass,
GFXShaderConstBuffer *shaderConsts);
void setupSGData(SceneData& data, const SceneRenderState* state, LightInfo* light);
void updateProbeTexture(ProbeRenderInst* probeInfo);
void reloadTextures();
/// Debug rendering
/// <summary>
/// Static flag used to indicate if probes should be rendered at all. Used for debugging
/// </summary>
static bool smRenderReflectionProbes;
void bakeProbe(ReflectionProbe *probeInfo);
//=============================================================================
// Utility functions for processing and setting up the probes for rendering
//=============================================================================
/// <summary>
/// Sorts probes based on their score values. These scores are calculated by the probes themselves based on size, distance from camera, etc
/// </summary>
static S32 QSORT_CALLBACK _probeScoreCmp(const ProbeRenderInst* a, const ProbeRenderInst* b);
/// <summary>
/// Builds a dataset of the best probes to be rendered this frame.
/// </summary>
/// <param name="objPosition"></param>
/// <param name="probeDataSet"></param>
void getBestProbes(const Point3F& objPosition, ProbeDataSet* probeDataSet);
/// <summary>
/// This function adds a ReflectionProbe to the registered list and also allocates
/// a slot in the cubemap array pair for its use
/// </summary>
/// <param name="probeInfo">The probe info to be registered to the bin</param>
void registerProbe(ReflectionProbe::ProbeInfo* probeInfo);
/// <summary>
/// This function removes the ReflectionProbe from the registered list, and marks it's cubemap
/// array slots as unused, allowing them to be freed.
/// </summary>
/// <param name="probeInfo">The probe info to be un-registered to the bin</param>
void unregisterProbe(ReflectionProbe::ProbeInfo* probeInfo);
/// <summary>
/// This function is for registering a ReflectionProbe's probe info
/// as being rendered in the current frame. This is distinct from
/// registered probes in that registered probes are any 'real' probe
/// in the scene, but they may not necessarily render
/// Active(submmitted) probes are intended to actual be rendered this frame
/// </summary>
/// <param name="probe">The ProbeInfo being submitted to be rendered</param>
void submitProbe(ReflectionProbe::ProbeInfo* probe);
/// <summary>
/// Gets the PostEffect used by the bin for rendering the probe array in deferred
/// </summary>
/// <returns>the PostEffect object</returns>
PostEffect* getProbeArrayEffect();
/// <summary>
/// Finds the associated cubemap array slot for the incoming ProbeInfo and updates the array's texture(s) from it
/// </summary>
/// <param name="probeInfo"></param>
void updateProbeTexture(ReflectionProbe::ProbeInfo* probeInfo);
/// <summary>
/// Forces an update for all registered probes' cubemaps
/// </summary>
void reloadTextures();
/// <summary>
/// Takes a reflection probe and runs the cubemap bake process on it, outputting the resulting files to disk
/// </summary>
void bakeProbe(ReflectionProbe* probe);
/// <summary>
/// Runs the cubemap bake on all probes in the current scene
/// </summary>
void bakeProbes();
void getProbeTextureData(ProbeTextureArrayData* probeTextureSet);
S32 getSkylightIndex() { return mSkylightCubemapIdx; }
//accumulates the best fit of probes given the object position
void getBestProbes(const Point3F& objPosition, ProbeDataSet* probeDataSet);
/// <summary>
/// Returns the active Probe Manager.
/// </summary>
static inline RenderProbeMgr* getProbeManager();
//=============================================================================
// Forward Rendering functions
//=============================================================================
/// <summary>
/// This function returns or builds a ProbeShaderConsts containing needed data for
/// rendering probes in forward mode
/// </summary>
/// <param name="buffer">The GFXShaderConstBuffer used to build or fetch the Probe Consts</param>
ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer);
/// <summary>
/// Sets up the probe data required for doing a render in forward mode.
/// </summary>
virtual void setProbeInfo(ProcessedMaterial* pmat,
const Material* mat,
const SceneData& sgData,
const SceneRenderState* state,
U32 pass,
GFXShaderConstBuffer* shaderConsts);
/// <summary>
/// Invoked as part of the setup in preperation to render an object in forward mode. Used to ensure the probes are
/// sorted ahead of render.
/// </summary>
/// <param name="state"></param>
void setupSGData(SceneData& data, const SceneRenderState* state, LightInfo* light);
/// <summary>
/// Sets up and binds all the shader const data required for rendering probes/IBL for a forward-rendered material.
/// </summary>
/// <returns></returns>
void _update4ProbeConsts(const SceneData& sgData,
MatrixSet& matSet,
ProbeShaderConstants* probeShaderConsts,
GFXShaderConstBuffer* shaderConsts);
//=============================================================================
// Deferred Rendering Functions
//=============================================================================
/// <summary>
/// Ensures the probes are properly sorted before we render them in deferred mode
/// </summary>
void _setupPerFrameParameters(const SceneRenderState *state);
/// <summary>
/// Renders the sorted probes list via a PostEffect to draw them into the buffer data in deferred mode.
/// </summary>
virtual void render(SceneRenderState * state);
virtual void clear() { mActiveProbes.clear(); Parent::clear(); }
};
RenderProbeMgr* RenderProbeMgr::getProbeManager()

View file

@ -758,7 +758,7 @@ Var* ShaderFeatureGLSL::getWsView( Var *wsPosition, MultiLine *meta )
eyePos->constSortPos = cspPass;
}
meta->addStatement( new GenOp( " @ = normalize( @ - @ );\r\n",
meta->addStatement( new GenOp( " @ = @ - @;\r\n",
new DecOp( wsView ), eyePos, wsPosition ) );
}
@ -838,79 +838,66 @@ Var* ShaderFeatureGLSL::addOutDetailTexCoord( Vector<ShaderComponent*> &compon
Var* ShaderFeatureGLSL::getSurface(Vector<ShaderComponent*>& componentList, MultiLine* meta, const MaterialFeatureData& fd)
{
ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(componentList[C_CONNECTOR]);
Var* diffuseColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
Var* ormConfig = (Var*)LangElement::find("ORMConfig");
if (!ormConfig)
{
Var* metalness = (Var*)LangElement::find("metalness");
if (!metalness)
{
metalness = new Var("metalness", "float");
metalness->uniform = true;
metalness->constSortPos = cspPotentialPrimitive;
}
Var* roughness = (Var*)LangElement::find("roughness");
if (!roughness)
{
roughness = new Var("roughness", "float");
roughness->uniform = true;
roughness->constSortPos = cspPotentialPrimitive;
}
ormConfig = new Var("ORMConfig", "vec4");
LangElement* colorDecl = new DecOp(ormConfig);
meta->addStatement(new GenOp(" @ = vec4(0.0,1.0,@,@);\r\n", colorDecl, roughness, metalness)); //reconstruct ormConfig, no ao darkening
}
Var* normal = (Var*)LangElement::find("normal");
if (!normal)
{
normal = new Var("normal", "vec3");
meta->addStatement(new GenOp(" @;\r\n\n", new DecOp(normal)));
Var* wsNormal = (Var*)LangElement::find("wsNormal");
if (!fd.features[MFT_NormalMap])
{
if (!wsNormal)
wsNormal = getInWorldNormal(componentList);
meta->addStatement(new GenOp(" @ = normalize( @ );\r\n\n", normal, wsNormal));
}
else
{
meta->addStatement(new GenOp(" @ = normalize( @ );\r\n", normal, wsNormal));
}
}
Var* wsEyePos = (Var*)LangElement::find("eyePosWorld");
if (!wsEyePos)
{
wsEyePos = new Var("eyePosWorld", "vec3");
wsEyePos->uniform = true;
wsEyePos->constSortPos = cspPass;
}
Var* wsPosition = getInWsPosition(componentList);
Var* wsView = getWsView(wsPosition, meta);
Var* surface = (Var*)LangElement::find("surface");
Var *surface = (Var *)LangElement::find("surface");
if (!surface)
{
Var* diffuseColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
Var* ormConfig = (Var*)LangElement::find("ORMConfig");
if (!ormConfig)
{
Var* metalness = (Var*)LangElement::find("metalness");
if (!metalness)
{
metalness = new Var("metalness", "float");
metalness->uniform = true;
metalness->constSortPos = cspPotentialPrimitive;
}
Var* roughness = (Var*)LangElement::find("roughness");
if (!roughness)
{
roughness = new Var("roughness", "float");
roughness->uniform = true;
roughness->constSortPos = cspPotentialPrimitive;
}
ormConfig = new Var("ORMConfig", "vec4");
LangElement* colorDecl = new DecOp(ormConfig);
meta->addStatement(new GenOp(" @ = vec4(0.0,1.0,@,@);\r\n", colorDecl, roughness, metalness)); //reconstruct ormConfig, no ao darkening
}
Var* normal = (Var*)LangElement::find("normal");
if (!normal)
{
normal = new Var("normal", "vec3");
meta->addStatement(new GenOp(" @;\r\n\n", new DecOp(normal)));
Var *wsNormal = (Var *)LangElement::find("wsNormal");
if (!wsNormal)
wsNormal = getInWorldNormal(componentList);
meta->addStatement(new GenOp(" @ = normalize( @ );\r\n", normal, wsNormal));
}
Var* wsEyePos = (Var*)LangElement::find("eyePosWorld");
if (!wsEyePos)
{
wsEyePos = new Var("eyePosWorld", "vec3");
wsEyePos->uniform = true;
wsEyePos->constSortPos = cspPass;
}
Var* wsPosition = getInWsPosition(componentList);
Var* wsView = getWsView(wsPosition, meta);
surface = new Var("surface", "Surface");
meta->addStatement(new GenOp(" @ = createForwardSurface(@,@,@,@,@,@);\r\n\n", new DecOp(surface), diffuseColor, normal, ormConfig,
meta->addStatement(new GenOp(" @ = createForwardSurface(@,normalize(@),@,@,@,@);\r\n\n", new DecOp(surface), diffuseColor, normal, ormConfig,
wsPosition, wsEyePos, wsView));
}
/*Var* surface = (Var*)LangElement::find("surface");
if (!surface)
{
surface = new Var("surface", "float");
}*/
return surface;
}
//****************************************************************************
@ -3003,12 +2990,12 @@ void ReflectionProbeFeatGLSL::processPix(Vector<ShaderComponent*>& componentList
inRefPosArray->uniform = true;
inRefPosArray->constSortPos = cspPotentialPrimitive;
Var * refScaleArray = new Var("inRefScale", "vec4");
Var * refScaleArray = new Var("inRefScaleArray", "vec4");
refScaleArray->arraySize = MAX_FORWARD_PROBES;
refScaleArray->uniform = true;
refScaleArray->constSortPos = cspPotentialPrimitive;
Var * probeConfigData = new Var("inProbeConfigData", "vec4");
Var * probeConfigData = new Var("inProbeConfigDataArray", "vec4");
probeConfigData->arraySize = MAX_FORWARD_PROBES;
probeConfigData->uniform = true;
probeConfigData->constSortPos = cspPotentialPrimitive;
@ -3026,12 +3013,12 @@ void ReflectionProbeFeatGLSL::processPix(Vector<ShaderComponent*>& componentList
BRDFTexture->sampler = true;
BRDFTexture->constNum = Var::getTexUnitNum(); // used as texture unit num here
Var * specularCubemapAR = new Var("inSpecularCubemapAR", "samplerCubeArray");
Var * specularCubemapAR = new Var("SpecularCubemapAR", "samplerCubeArray");
specularCubemapAR->uniform = true;
specularCubemapAR->sampler = true;
specularCubemapAR->constNum = Var::getTexUnitNum();
Var * irradianceCubemapAR = new Var("inIrradianceCubemapAR", "samplerCubeArray");
Var * irradianceCubemapAR = new Var("IrradianceCubemapAR", "samplerCubeArray");
irradianceCubemapAR->uniform = true;
irradianceCubemapAR->sampler = true;
irradianceCubemapAR->constNum = Var::getTexUnitNum();
@ -3044,14 +3031,24 @@ void ReflectionProbeFeatGLSL::processPix(Vector<ShaderComponent*>& componentList
return;
}
Var* eyePos = (Var*)LangElement::find("eyePosWorld");
if (!eyePos)
{
eyePos = new Var;
eyePos->setType("vec3");
eyePos->setName("eyePosWorld");
eyePos->uniform = true;
eyePos->constSortPos = cspPotentialPrimitive;
}
Var *curColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
//Reflection vec
String computeForwardProbes = String(" @.rgb = computeForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t");
String computeForwardProbes = String(" @.rgb = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
computeForwardProbes += String("@,@,\r\n\t\t");
computeForwardProbes += String("@,@).rgb; \r\n");
meta->addStatement(new GenOp(computeForwardProbes.c_str(), curColor, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray,
meta->addStatement(new GenOp(computeForwardProbes.c_str(), curColor, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos,
skylightCubemapIdx, BRDFTexture,
irradianceCubemapAR, specularCubemapAR));
@ -3078,9 +3075,9 @@ void ReflectionProbeFeatGLSL::setTexData(Material::StageData& stageDat,
passData.mSamplerNames[texIndex] = "BRDFTexture";
passData.mTexType[texIndex++] = Material::Standard;
// assuming here that it is a scenegraph cubemap
passData.mSamplerNames[texIndex] = "inSpecularCubemapAR";
passData.mSamplerNames[texIndex] = "SpecularCubemapAR";
passData.mTexType[texIndex++] = Material::SGCube;
passData.mSamplerNames[texIndex] = "inIrradianceCubemapAR";
passData.mSamplerNames[texIndex] = "IrradianceCubemapAR";
passData.mTexType[texIndex++] = Material::SGCube;
}
}

View file

@ -764,7 +764,7 @@ Var* ShaderFeatureHLSL::getWsView( Var *wsPosition, MultiLine *meta )
eyePos->constSortPos = cspPass;
}
meta->addStatement( new GenOp( " @ = normalize( @ - @ );\r\n",
meta->addStatement( new GenOp( " @ = @ - @;\r\n",
new DecOp( wsView ), eyePos, wsPosition ) );
}
@ -844,14 +844,16 @@ Var* ShaderFeatureHLSL::addOutDetailTexCoord( Vector<ShaderComponent*> &compon
Var* ShaderFeatureHLSL::getSurface(Vector<ShaderComponent*>& componentList, MultiLine* meta, const MaterialFeatureData& fd)
{
ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(componentList[C_CONNECTOR]);
Var *surface = (Var *)LangElement::find("surface");
Var* diffuseColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
if (!surface)
{
Var *diffuseColor = (Var *)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
Var* ormConfig = (Var*)LangElement::find("ORMConfig");
Var *ormConfig = (Var *)LangElement::find("ORMConfig");
if (!ormConfig)
{
Var* metalness = (Var*)LangElement::find("metalness");
Var *metalness = (Var *)LangElement::find("metalness");
if (!metalness)
{
metalness = new Var("metalness", "float");
@ -859,7 +861,7 @@ Var* ShaderFeatureHLSL::getSurface(Vector<ShaderComponent*>& componentList, Mult
metalness->constSortPos = cspPotentialPrimitive;
}
Var* roughness = (Var*)LangElement::find("roughness");
Var *roughness = (Var *)LangElement::find("roughness");
if (!roughness)
{
roughness = new Var("roughness", "float");
@ -868,30 +870,24 @@ Var* ShaderFeatureHLSL::getSurface(Vector<ShaderComponent*>& componentList, Mult
}
ormConfig = new Var("ORMConfig", "float4");
LangElement* colorDecl = new DecOp(ormConfig);
LangElement *colorDecl = new DecOp(ormConfig);
meta->addStatement(new GenOp(" @ = float4(0.0,1.0,@,@);\r\n", colorDecl, roughness, metalness)); //reconstruct matinfo, no ao darkening
}
Var* normal = (Var*)LangElement::find("normal");
Var *normal = (Var *)LangElement::find("normal");
if (!normal)
{
normal = new Var("normal", "float3");
meta->addStatement(new GenOp(" @;\r\n\n", new DecOp(normal)));
Var* wsNormal = (Var*)LangElement::find("wsNormal");
if (!fd.features[MFT_NormalMap])
{
Var *wsNormal = (Var *)LangElement::find("wsNormal");
if (!wsNormal)
wsNormal = getInWorldNormal(componentList);
meta->addStatement(new GenOp(" @ = normalize( @ );\r\n\n", normal, wsNormal));
}
else
{
meta->addStatement(new GenOp(" @ = normalize( @ );\r\n", normal, wsNormal));
}
}
Var* wsEyePos = (Var*)LangElement::find("eyePosWorld");
Var *wsEyePos = (Var *)LangElement::find("eyePosWorld");
if (!wsEyePos)
{
@ -900,15 +896,11 @@ Var* ShaderFeatureHLSL::getSurface(Vector<ShaderComponent*>& componentList, Mult
wsEyePos->constSortPos = cspPass;
}
Var* wsPosition = getInWsPosition(componentList);
Var* wsView = getWsView(wsPosition, meta);
Var *wsPosition = getInWsPosition(componentList);
Var *wsView = getWsView(wsPosition, meta);
Var* surface = (Var*)LangElement::find("surface");
if (!surface)
{
surface = new Var("surface", "Surface");
meta->addStatement(new GenOp(" @ = createForwardSurface(@,@,@,@,@,@);\r\n\n", new DecOp(surface), diffuseColor, normal, ormConfig,
meta->addStatement(new GenOp(" @ = createForwardSurface(@,normalize(@),@,@,@,@);\r\n\n", new DecOp(surface), diffuseColor, normal, ormConfig,
wsPosition, wsEyePos, wsView));
}
@ -3076,12 +3068,12 @@ void ReflectionProbeFeatHLSL::processPix(Vector<ShaderComponent*> &componentList
inRefPosArray->uniform = true;
inRefPosArray->constSortPos = cspPotentialPrimitive;
Var * refScaleArray = new Var("inRefScale", "float4");
Var * refScaleArray = new Var("inRefScaleArray", "float4");
refScaleArray->arraySize = MAX_FORWARD_PROBES;
refScaleArray->uniform = true;
refScaleArray->constSortPos = cspPotentialPrimitive;
Var *probeConfigData = new Var("inProbeConfigData", "float4");
Var *probeConfigData = new Var("inProbeConfigDataArray", "float4");
probeConfigData->arraySize = MAX_FORWARD_PROBES;
probeConfigData->uniform = true;
probeConfigData->constSortPos = cspPotentialPrimitive;
@ -3101,22 +3093,22 @@ void ReflectionProbeFeatHLSL::processPix(Vector<ShaderComponent*> &componentList
BRDFTextureTex->texture = true;
BRDFTextureTex->constNum = BRDFTexture->constNum;
Var *specularCubemapAR = new Var("inSpecularCubemapAR", "SamplerState");
Var *specularCubemapAR = new Var("SpecularCubemapAR", "SamplerState");
specularCubemapAR->uniform = true;
specularCubemapAR->sampler = true;
specularCubemapAR->constNum = Var::getTexUnitNum(); // used as texture unit num here
Var *specularCubemapARTex = new Var("texture_inSpecularCubemapAR", "TextureCubeArray");
Var *specularCubemapARTex = new Var("texture_SpecularCubemapAR", "TextureCubeArray");
specularCubemapARTex->uniform = true;
specularCubemapARTex->texture = true;
specularCubemapARTex->constNum = specularCubemapAR->constNum;
Var *irradianceCubemapAR = new Var("inIrradianceCubemapAR", "SamplerState");
Var *irradianceCubemapAR = new Var("IrradianceCubemapAR", "SamplerState");
irradianceCubemapAR->uniform = true;
irradianceCubemapAR->sampler = true;
irradianceCubemapAR->constNum = Var::getTexUnitNum(); // used as texture unit num here
Var *irradianceCubemapARTex = new Var("texture_inIrradianceCubemapAR", "TextureCubeArray");
Var *irradianceCubemapARTex = new Var("texture_IrradianceCubemapAR", "TextureCubeArray");
irradianceCubemapARTex->uniform = true;
irradianceCubemapARTex->texture = true;
irradianceCubemapARTex->constNum = irradianceCubemapAR->constNum;
@ -3138,11 +3130,21 @@ void ReflectionProbeFeatHLSL::processPix(Vector<ShaderComponent*> &componentList
ibl = new Var("ibl", "float3");
}
String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t");
Var* eyePos = (Var*)LangElement::find("eyePosWorld");
if (!eyePos)
{
eyePos = new Var;
eyePos->setType("float3");
eyePos->setName("eyePosWorld");
eyePos->uniform = true;
eyePos->constSortPos = cspPass;
}
String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
computeForwardProbes += String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t");
computeForwardProbes += String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@)).rgb; \r\n");
meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray,
meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos,
skylightCubemapIdx, BRDFTexture,
irradianceCubemapAR, specularCubemapAR));
@ -3171,9 +3173,9 @@ void ReflectionProbeFeatHLSL::setTexData(Material::StageData &stageDat,
passData.mSamplerNames[texIndex] = "BRDFTexture";
passData.mTexType[texIndex++] = Material::Standard;
// assuming here that it is a scenegraph cubemap
passData.mSamplerNames[texIndex] = "inSpecularCubemapAR";
passData.mSamplerNames[texIndex] = "SpecularCubemapAR";
passData.mTexType[texIndex++] = Material::SGCube;
passData.mSamplerNames[texIndex] = "inIrradianceCubemapAR";
passData.mSamplerNames[texIndex] = "IrradianceCubemapAR";
passData.mTexType[texIndex++] = Material::SGCube;
}
}

View file

@ -80,17 +80,19 @@ const String ShaderGenVars::glowMul("$glowMul");
//Reflection Probes - Forward lit. not to be confused with the deferred handwritten vars
//change to parity once we've got the same arrays used for both routes
const String ShaderGenVars::probePosition("$inProbePosArray");
const String ShaderGenVars::probeRefPos("$inRefPosArray");
const String ShaderGenVars::refScale("$inRefScale");
const String ShaderGenVars::probePositionArray("$inProbePosArray");
const String ShaderGenVars::probeRefPosArray("$inRefPosArray");
const String ShaderGenVars::refScaleArray("$inRefScaleArray");
const String ShaderGenVars::worldToObjArray("$inWorldToObjArray");
const String ShaderGenVars::probeConfigData("$inProbeConfigData");
const String ShaderGenVars::specularCubemapAR("$inSpecularCubemapAR");
const String ShaderGenVars::irradianceCubemapAR("$inIrradianceCubemapAR");
const String ShaderGenVars::probeConfigDataArray("$inProbeConfigDataArray");
const String ShaderGenVars::specularCubemapAR("$SpecularCubemapAR");
const String ShaderGenVars::irradianceCubemapAR("$IrradianceCubemapAR");
const String ShaderGenVars::probeCount("$inNumProbes");
const String ShaderGenVars::BRDFTextureMap("$BRDFTexture");
const String ShaderGenVars::maxProbeDrawDistance("$maxProbeDrawDistance");
//Skylight
const String ShaderGenVars::skylightCubemapIdx("$inSkylightCubemapIdx");

View file

@ -91,17 +91,19 @@ struct ShaderGenVars
const static String glowMul;
//Reflection Probes
const static String probePosition;
const static String probeRefPos;
const static String refScale;
const static String probePositionArray;
const static String probeRefPosArray;
const static String refScaleArray;
const static String worldToObjArray;
const static String probeConfigData;
const static String probeConfigDataArray;
const static String specularCubemapAR;
const static String irradianceCubemapAR;
const static String probeCount;
const static String BRDFTextureMap;
const static String maxProbeDrawDistance;
//Skylight
const static String skylightCubemapIdx;

View file

@ -15,4 +15,6 @@ singleton PostEffect( reflectionProbeArrayPostFX )
texture[0] = "#deferred";
texture[1] = "#color";
texture[2] = "#matinfo";
allowReflectPass = true;
};

View file

@ -23,6 +23,8 @@
#include "./torque.glsl"
#include "./brdf.glsl"
uniform float maxProbeDrawDistance;
#ifndef TORQUE_SHADERGEN
#line 27
// These are the uniforms used by most lighting shaders.
@ -330,7 +332,7 @@ float defineSphereSpaceInfluence(vec3 wsPosition, vec3 wsProbePosition, float ra
{
vec3 L = wsProbePosition.xyz - wsPosition;
float contribution = 1.0 - length(L) / radius;
return contribution;
return saturate(contribution);
}
float getDistBoxToPoint(vec3 pt, vec3 extents)
@ -342,10 +344,9 @@ float getDistBoxToPoint(vec3 pt, vec3 extents)
float defineBoxSpaceInfluence(vec3 wsPosition, mat4 worldToObj, float attenuation)
{
vec3 surfPosLS = tMul(worldToObj, vec4(wsPosition, 1.0)).xyz;
float atten = 1.0 - attenuation;
float baseVal = 0.25;
float dist = getDistBoxToPoint(surfPosLS, vec3(baseVal, baseVal, baseVal));
return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist));
return saturate(smoothstep(baseVal, (baseVal-attenuation/2), dist));
}
// Box Projected IBL Lighting
@ -367,9 +368,9 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refSca
}
vec4 computeForwardProbes(Surface surface,
float cubeMips, int numProbes, mat4x4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES],
vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
float skylightCubemapIdx, sampler2D BRDFTexture,
float cubeMips, int numProbes, mat4x4 inWorldToObjArray[MAX_FORWARD_PROBES], vec4 inProbeConfigData[MAX_FORWARD_PROBES],
vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 inRefScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
vec3 wsEyePos, float skylightCubemapIdx, sampler2D BRDFTexture,
samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR)
{
int i = 0;
@ -384,47 +385,37 @@ vec4 computeForwardProbes(Surface surface,
for (i = 0; i < numProbes; ++i)
{
contribution[i] = 0;
if (probeConfigData[i].r == 0) //box
float atten = 1.0-(length(wsEyePos-inProbePosArray[i].xyz)/maxProbeDrawDistance);
if (inProbeConfigData[i].r == 0) //box
{
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
if (contribution[i] > 0.0)
probehits++;
contribution[i] = defineBoxSpaceInfluence(surface.P, inWorldToObjArray[i], inProbeConfigData[i].b)*atten;
}
else if (probeConfigData[i].r == 1) //sphere
else if (inProbeConfigData[i].r == 1) //sphere
{
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g);
if (contribution[i] > 0.0)
probehits++;
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, inProbeConfigData[i].g)*atten;
}
contribution[i] = max(contribution[i], 0);
if (contribution[i]>0.0)
probehits++;
else
contribution[i] = 0.0;
blendSum += contribution[i];
invBlendSum += (1.0f - contribution[i]);
}
if (probehits > 1.0)
if (probehits > 1.0)//if we overlap
{
invBlendSum = (probehits - blendSum)/(probehits-1); //grab the remainder
for (i = 0; i < numProbes; i++)
{
blendFactor[i] = ((contribution[i] / blendSum)) / probehits;
blendFactor[i] *= ((contribution[i]) / invBlendSum);
blendFactor[i] = saturate(blendFactor[i]);
blendFacSum += blendFactor[i];
blendFactor[i] = contribution[i]/blendSum; //what % total is this instance
blendFactor[i] *= blendFactor[i] / invBlendSum; //what should we add to sum to 1
blendFacSum += blendFactor[i]; //running tally of results
}
// Normalize blendVal
if (blendFacSum == 0.0f) // Possible with custom weight
{
blendFacSum = 1.0f;
}
float invBlendSumWeighted = 1.0f / blendFacSum;
for (i = 0; i < numProbes; ++i)
{
blendFactor[i] *= invBlendSumWeighted;
contribution[i] *= blendFactor[i];
contribution[i] *= blendFactor[i]/blendFacSum; //normalize
}
}
@ -471,8 +462,8 @@ vec4 computeForwardProbes(Surface surface,
float contrib = contribution[i];
if (contrib > 0.0f)
{
float cubemapIdx = int(probeConfigData[i].a);
vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
float cubemapIdx = int(inProbeConfigData[i].a);
vec3 dir = boxProject(surface.P, surface.R, inWorldToObjArray[i], inRefScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
@ -491,8 +482,8 @@ vec4 computeForwardProbes(Surface surface,
vec3 kD = 1.0f - F;
kD *= 1.0f - surface.metalness;
float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
vec2 envBRDF = textureLod(BRDFTexture, vec2(dfgNdotV, surface.roughness),0).rg;
//float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
vec2 envBRDF = textureLod(BRDFTexture, vec2(surface.NdotV, surface.roughness),0).rg;
specular *= F * envBRDF.x + surface.f90 * envBRDF.y;
irradiance *= kD * surface.baseColor.rgb;
@ -504,13 +495,16 @@ vec4 computeForwardProbes(Surface surface,
float horizonOcclusion = 1.3;
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
horizon *= horizon;
#if CAPTURING == 1
return vec4(mix(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0);
#else
return vec4((irradiance + specular) * horizon, 0);//alpha writes disabled
#endif
}
vec4 debugVizForwardProbes(Surface surface,
float cubeMips, int numProbes, mat4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES],
vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
float cubeMips, int numProbes, mat4 inWorldToObjArray[MAX_FORWARD_PROBES], vec4 inProbeConfigData[MAX_FORWARD_PROBES],
vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 inRefScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
float skylightCubemapIdx, sampler2D BRDFTexture,
samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR, int showAtten, int showContrib, int showSpec, int showDiff)
{
@ -527,15 +521,15 @@ vec4 debugVizForwardProbes(Surface surface,
{
contribution[i] = 0;
if (probeConfigData[i].r == 0) //box
if (inProbeConfigData[i].r == 0) //box
{
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
contribution[i] = defineBoxSpaceInfluence(surface.P, inWorldToObjArray[i], inProbeConfigData[i].b);
if (contribution[i] > 0.0)
probehits++;
}
else if (probeConfigData[i].r == 1) //sphere
else if (inProbeConfigData[i].r == 1) //sphere
{
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g);
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, inProbeConfigData[i].g);
if (contribution[i] > 0.0)
probehits++;
}
@ -620,8 +614,8 @@ vec4 debugVizForwardProbes(Surface surface,
float contrib = contribution[i];
if (contrib > 0.0f)
{
float cubemapIdx = probeConfigData[i].a;
vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
float cubemapIdx = inProbeConfigData[i].a;
vec3 dir = boxProject(surface.P, surface.R, inWorldToObjArray[i], inRefScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;

View file

@ -24,6 +24,9 @@
#include "./brdf.hlsl"
#include "./shaderModelAutoGen.hlsl"
//globals
uniform float3 eyePosWorld;
uniform float maxProbeDrawDistance;
#ifndef TORQUE_SHADERGEN
// These are the uniforms used by most lighting shaders.
@ -333,7 +336,7 @@ float defineSphereSpaceInfluence(float3 wsPosition, float3 wsProbePosition, floa
{
float3 L = wsProbePosition.xyz - wsPosition;
float contribution = 1.0 - length(L) / radius;
return contribution;
return saturate(contribution);
}
float getDistBoxToPoint(float3 pt, float3 extents)
@ -345,10 +348,9 @@ float getDistBoxToPoint(float3 pt, float3 extents)
float defineBoxSpaceInfluence(float3 wsPosition, float4x4 worldToObj, float attenuation)
{
float3 surfPosLS = mul(worldToObj, float4(wsPosition, 1.0)).xyz;
float atten = 1.0 - attenuation;
float baseVal = 0.25;
float dist = getDistBoxToPoint(surfPosLS, float3(baseVal, baseVal, baseVal));
return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist));
return saturate(smoothstep(baseVal, (baseVal-attenuation/2), dist));
}
// Box Projected IBL Lighting
@ -370,9 +372,9 @@ float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, f
}
float4 computeForwardProbes(Surface surface,
float cubeMips, int numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES],
float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture),
float cubeMips, int numProbes, float4x4 inWorldToObjArray[MAX_FORWARD_PROBES], float4 inProbeConfigData[MAX_FORWARD_PROBES],
float4 inProbePosArray[MAX_FORWARD_PROBES], float4 inRefScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
float3 wsEyePos, float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture),
TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR))
{
int i = 0;
@ -384,50 +386,41 @@ float4 computeForwardProbes(Surface surface,
float probehits = 0;
//Set up our struct data
float contribution[MAX_FORWARD_PROBES];
//Process prooooobes
for (i = 0; i < numProbes; ++i)
{
contribution[i] = 0;
if (probeConfigData[i].r == 0) //box
contribution[i] = 0.0;
float atten = 1.0-(length(wsEyePos-inProbePosArray[i].xyz)/maxProbeDrawDistance);
if (inProbeConfigData[i].r == 0) //box
{
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
if (contribution[i] > 0.0)
probehits++;
contribution[i] = defineBoxSpaceInfluence(surface.P, inWorldToObjArray[i], inProbeConfigData[i].b)*atten;
}
else if (probeConfigData[i].r == 1) //sphere
else if (inProbeConfigData[i].r == 1) //sphere
{
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g);
if (contribution[i] > 0.0)
probehits++;
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, inProbeConfigData[i].g)*atten;
}
contribution[i] = max(contribution[i], 0);
if (contribution[i]>0.0)
probehits++;
else
contribution[i] = 0.0;
blendSum += contribution[i];
invBlendSum += (1.0f - contribution[i]);
}
if (probehits > 1.0)
if (probehits > 1.0)//if we overlap
{
invBlendSum = (probehits - blendSum)/(probehits-1); //grab the remainder
for (i = 0; i < numProbes; i++)
{
blendFactor[i] = ((contribution[i] / blendSum)) / probehits;
blendFactor[i] *= ((contribution[i]) / invBlendSum);
blendFactor[i] = saturate(blendFactor[i]);
blendFacSum += blendFactor[i];
blendFactor[i] = contribution[i]/blendSum; //what % total is this instance
blendFactor[i] *= blendFactor[i] / invBlendSum; //what should we add to sum to 1
blendFacSum += blendFactor[i]; //running tally of results
}
// Normalize blendVal
if (blendFacSum == 0.0f) // Possible with custom weight
{
blendFacSum = 1.0f;
}
float invBlendSumWeighted = 1.0f / blendFacSum;
for (i = 0; i < numProbes; ++i)
{
blendFactor[i] *= invBlendSumWeighted;
contribution[i] *= blendFactor[i];
contribution[i] *= blendFactor[i]/blendFacSum; //normalize
}
}
@ -474,8 +467,8 @@ float4 computeForwardProbes(Surface surface,
float contrib = contribution[i];
if (contrib > 0.0f)
{
int cubemapIdx = probeConfigData[i].a;
float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
int cubemapIdx = inProbeConfigData[i].a;
float3 dir = boxProject(surface.P, surface.R, inWorldToObjArray[i], inRefScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
@ -494,8 +487,8 @@ float4 computeForwardProbes(Surface surface,
float3 kD = 1.0f - F;
kD *= 1.0f - surface.metalness;
float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(dfgNdotV, surface.roughness,0,0)).rg;
//float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.NdotV, surface.roughness,0,0)).rg;
specular *= F * envBRDF.x + surface.f90 * envBRDF.y;
irradiance *= kD * surface.baseColor.rgb;
@ -507,13 +500,16 @@ float4 computeForwardProbes(Surface surface,
float horizonOcclusion = 1.3;
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
horizon *= horizon;
#if CAPTURING == 1
return float4(lerp(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0);
#else
return float4((irradiance + specular) * horizon, 0);//alpha writes disabled
#endif
}
float4 debugVizForwardProbes(Surface surface,
float cubeMips, int numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES],
float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
float cubeMips, int numProbes, float4x4 inWorldToObjArray[MAX_FORWARD_PROBES], float4 inProbeConfigData[MAX_FORWARD_PROBES],
float4 inProbePosArray[MAX_FORWARD_PROBES], float4 inRefScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture),
TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR), int showAtten, int showContrib, int showSpec, int showDiff)
{
@ -530,15 +526,15 @@ float4 debugVizForwardProbes(Surface surface,
{
contribution[i] = 0;
if (probeConfigData[i].r == 0) //box
if (inProbeConfigData[i].r == 0) //box
{
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
contribution[i] = defineBoxSpaceInfluence(surface.P, inWorldToObjArray[i], inProbeConfigData[i].b);
if (contribution[i] > 0.0)
probehits++;
}
else if (probeConfigData[i].r == 1) //sphere
else if (inProbeConfigData[i].r == 1) //sphere
{
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g);
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, inProbeConfigData[i].g);
if (contribution[i] > 0.0)
probehits++;
}
@ -623,8 +619,8 @@ float4 debugVizForwardProbes(Surface surface,
float contrib = contribution[i];
if (contrib > 0.0f)
{
int cubemapIdx = probeConfigData[i].a;
float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
int cubemapIdx = inProbeConfigData[i].a;
float3 dir = boxProject(surface.P, surface.R, inWorldToObjArray[i], inRefScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;

View file

@ -196,6 +196,38 @@ void main()
lightCol *= max(cookie.r, max(cookie.g, cookie.b));
#endif
#ifdef DIFFUSE_LIGHT_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
vec3 diffuse = BRDF_GetDebugDiffuse(surface,surfaceToLight) * factor;
vec3 final = max(0.0f, diffuse);
OUT_col = vec4(final, 0);
return
#endif
#ifdef SPECULAR_LIGHT_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
vec3 diffuse = BRDF_GetDebugSpecular(surface,surfaceToLight) * factor;
vec3 final = max(0.0f, diffuse);
OUT_col = vec4(final, 0);
return
#endif
#ifdef DETAIL_LIGHTING_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
vec3 final = max(vec3(0.0f), diffuse + spec * surface.F);
OUT_col = vec4(final, 0);
return
#endif
//get punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
}

View file

@ -84,78 +84,57 @@ void main()
{
contribution[i] = 0;
float atten =1.0-(length(eyePosWorld-probePosArray[i].xyz)/maxProbeDrawDistance);
if (probeConfigData[i].r == 0) //box
{
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
if (contribution[i]>0.0)
probehits++;
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b)*atten;
}
else if (probeConfigData[i].r == 1) //sphere
{
contribution[i] = defineSphereSpaceInfluence(surface.P, probePosArray[i].xyz, probeConfigData[i].g);
contribution[i] = defineSphereSpaceInfluence(surface.P, probePosArray[i].xyz, probeConfigData[i].g)*atten;
}
if (contribution[i]>0.0)
probehits++;
}
contribution[i] = max(contribution[i],0);
else
contribution[i] = 0;
blendSum += contribution[i];
invBlendSum += (1.0f - contribution[i]);
}
// Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary.
// And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1).
// respect constraint B.
// Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary
// and respect constraint A.
if (probehits > 1.0)
if (probehits > 1.0)//if we overlap
{
invBlendSum = (probehits - blendSum)/(probehits-1); //grab the remainder
for (i = 0; i < numProbes; i++)
{
blendFactor[i] = ((contribution[i] / blendSum)) / probehits;
blendFactor[i] *= ((contribution[i]) / invBlendSum);
blendFactor[i] = saturate(blendFactor[i]);
blendFacSum += blendFactor[i];
blendFactor[i] = contribution[i]/blendSum; //what % total is this instance
blendFactor[i] *= blendFactor[i] / invBlendSum; //what should we add to sum to 1
blendFacSum += blendFactor[i]; //running tally of results
}
// Normalize blendVal
if (blendFacSum == 0.0f) // Possible with custom weight
{
blendFacSum = 1.0f;
}
float invBlendSumWeighted = 1.0f / blendFacSum;
for (i = 0; i < numProbes; ++i)
{
blendFactor[i] *= invBlendSumWeighted;
contribution[i] *= blendFactor[i];
contribution[i] *= blendFactor[i]/blendFacSum; //normalize
}
}
#if DEBUGVIZ_ATTENUATION == 1
float contribAlpha = 1;
float contribAlpha = 0;
for (i = 0; i < numProbes; ++i)
{
contribAlpha -= contribution[i];
contribAlpha += contribution[i];
}
OUT_col = vec4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1);
OUT_col = vec4(contribAlpha,contribAlpha,contribAlpha, 1);
return;
#endif
#if DEBUGVIZ_CONTRIB == 1
vec3 finalContribColor = vec3(0, 0, 0);
float contribAlpha = 1;
for (i = 0; i < numProbes; ++i)
{
finalContribColor += contribution[i] *probeContribColors[i].rgb;
contribAlpha -= contribution[i];
finalContribColor += contribution[i] * vec3(fmod(i+1,2),fmod(i+1,3),fmod(i+1,4));
}
//Skylight coloration for anything not covered by probes above
if(skylightCubemapIdx != -1)
finalContribColor += vec3(0, 1, 0) * contribAlpha;
OUT_col = vec4(finalContribColor, 1);
return;
#endif
@ -188,7 +167,7 @@ void main()
}
#endif
if (skylightCubemapIdx != -1 && alpha > 0.001)
if (skylightCubemapIdx != -1 && alpha >= 0.001)
{
irradiance = lerp(irradiance,textureLod(irradianceCubemapAR, vec4(surface.R, skylightCubemapIdx), 0).xyz,alpha);
specular = lerp(specular,textureLod(specularCubemapAR, vec4(surface.R, skylightCubemapIdx), lod).xyz,alpha);
@ -220,6 +199,9 @@ void main()
float horizonOcclusion = 1.3;
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
horizon *= horizon;
OUT_col = vec4(irradiance + specular, 0);//alpha writes disabled
#if CAPTURING == 1
OUT_col = vec4(mix(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0);
#else
OUT_col = vec4((irradiance + specular) * horizon, 0);//alpha writes disabled
#endif
}

View file

@ -122,6 +122,41 @@ void main()
lightCol *= max(cookie.r, max(cookie.g, cookie.b));
#endif
#ifdef DIFFUSE_LIGHT_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
vec3 diffuse = BRDF_GetDebugDiffuse(surface,surfaceToLight) * factor;
vec3 final = max(0.0f, diffuse) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams );
OUT_col = vec4(final, 0);
return;
#endif
#ifdef SPECULAR_LIGHT_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
vec3 diffuse = BRDF_GetDebugSpecular(surface,surfaceToLight) * factor;
vec3 final = max(0.0f, diffuse) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams );
OUT_col = vec4(final, 0);
return;
#endif
#ifdef DETAIL_LIGHTING_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
vec3 final = max(vec3(0.0f), diffuse + spec * surface.F) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams );
OUT_col = vec4(final, 0);
return;
#endif
//get Punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
//get spot angle attenuation

View file

@ -216,7 +216,7 @@ void main()
lightingColor = shadowed_colors.rgb;
#endif
shadow = lerp( shadow, 1.0, saturate( fadeOutAmt ) );
shadow = mix( shadow, 1.0, saturate( fadeOutAmt ) );
#ifdef PSSM_DEBUG_RENDER
if ( fadeOutAmt > 1.0 )
@ -225,6 +225,37 @@ void main()
#endif //NO_SHADOW
#ifdef DIFFUSE_LIGHT_VIZ
vec3 factor = lightingColor.rgb * max(surfaceToLight.NdotL, 0) * shadow * lightBrightness;
vec3 diffuse = BRDF_GetDebugDiffuse(surface,surfaceToLight) * factor;
vec3 final = max(0.0f, diffuse);
OUT_col = vec4(final, 0);
return;
#endif
#ifdef SPECULAR_LIGHT_VIZ
vec3 factor = lightingColor.rgb * max(surfaceToLight.NdotL, 0) * shadow * lightBrightness;
vec3 spec = BRDF_GetDebugSpecular(surface, surfaceToLight) * factor;
vec3 final = max(0.0f, factor);
OUT_col = vec4(final, 0);
return;
#endif
#ifdef DETAIL_LIGHTING_VIZ
vec3 factor = lightingColor.rgb * max(surfaceToLight.NdotL, 0) * shadow * lightBrightness;
vec3 diffuse = BRDF_GetDebugDiffuse(surface,surfaceToLight) * factor;
vec3 spec = BRDF_GetDebugSpecular(surface,surfaceToLight) * factor;
vec3 final = max(0.0f, diffuse + spec);
OUT_col = vec4(final, 0);
return;
#endif
//get directional light contribution
vec3 lighting = getDirectionalLight(surface, surfaceToLight, lightingColor.rgb, lightBrightness, shadow);

View file

@ -134,7 +134,6 @@ uniform float shadowSoftness;
uniform float4x4 worldToCamera;
uniform float3x3 worldToLightProj;
uniform float3 eyePosWorld;
uniform float4x4 cameraToWorld;
float4 main( ConvexConnectP IN ) : SV_TARGET
@ -218,12 +217,12 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
#ifdef DETAIL_LIGHTING_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
float3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
float3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
vec3 final = max(vec3(0.0f), diffuse + spec * surface.F);
float3 final = max(float3(0.0f), diffuse + spec * surface.F);
return final;
#endif

View file

@ -12,7 +12,6 @@ TORQUE_UNIFORM_SAMPLER2D(BRDFTexture, 3);
uniform float4 rtParams0;
uniform float4 vsFarPlane;
uniform float4x4 cameraToWorld;
uniform float3 eyePosWorld;
//cubemap arrays require all the same size. so shared mips# value
uniform float cubeMips;
@ -76,79 +75,58 @@ float4 main(PFXVertToPix IN) : SV_TARGET
//Process prooooobes
for (i = 0; i < numProbes; ++i)
{
contribution[i] = 0;
contribution[i] = 0.0;
float atten =1.0-(length(eyePosWorld-probePosArray[i].xyz)/maxProbeDrawDistance);
if (probeConfigData[i].r == 0) //box
{
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
if (contribution[i]>0.0)
probehits++;
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b)*atten;
}
else if (probeConfigData[i].r == 1) //sphere
{
contribution[i] = defineSphereSpaceInfluence(surface.P, probePosArray[i].xyz, probeConfigData[i].g);
contribution[i] = defineSphereSpaceInfluence(surface.P, probePosArray[i].xyz, probeConfigData[i].g)*atten;
}
if (contribution[i]>0.0)
probehits++;
}
contribution[i] = max(contribution[i],0);
else
contribution[i] = 0.0;
blendSum += contribution[i];
invBlendSum += (1.0f - contribution[i]);
}
// Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary.
// And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1).
// respect constraint B.
// Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary
// and respect constraint A.
if (probehits > 1.0)
if (probehits > 1.0)//if we overlap
{
invBlendSum = (probehits - blendSum)/(probehits-1); //grab the remainder
for (i = 0; i < numProbes; i++)
{
blendFactor[i] = ((contribution[i] / blendSum)) / probehits;
blendFactor[i] *= ((contribution[i]) / invBlendSum);
blendFactor[i] = saturate(blendFactor[i]);
blendFacSum += blendFactor[i];
blendFactor[i] = contribution[i]/blendSum; //what % total is this instance
blendFactor[i] *= blendFactor[i] / invBlendSum; //what should we add to sum to 1
blendFacSum += blendFactor[i]; //running tally of results
}
// Normalize blendVal
if (blendFacSum == 0.0f) // Possible with custom weight
{
blendFacSum = 1.0f;
}
float invBlendSumWeighted = 1.0f / blendFacSum;
for (i = 0; i < numProbes; ++i)
{
blendFactor[i] *= invBlendSumWeighted;
contribution[i] *= blendFactor[i];
contribution[i] *= blendFactor[i]/blendFacSum; //normalize
}
}
#if DEBUGVIZ_ATTENUATION == 1
float contribAlpha = 1;
float contribAlpha = 0;
for (i = 0; i < numProbes; ++i)
{
contribAlpha -= contribution[i];
contribAlpha += contribution[i];
}
return float4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1);
return float4(contribAlpha,contribAlpha,contribAlpha, 1);
#endif
#if DEBUGVIZ_CONTRIB == 1
float3 finalContribColor = float3(0, 0, 0);
float contribAlpha = 1;
for (i = 0; i < numProbes; ++i)
{
finalContribColor += contribution[i] *probeContribColors[i].rgb;
contribAlpha -= contribution[i];
finalContribColor += contribution[i] * float3(fmod(i+1,2),fmod(i+1,3),fmod(i+1,4));
}
//Skylight coloration for anything not covered by probes above
if(skylightCubemapIdx != -1)
finalContribColor += float3(0, 1, 0) * contribAlpha;
return float4(finalContribColor, 1);
#endif
}
@ -209,6 +187,9 @@ float4 main(PFXVertToPix IN) : SV_TARGET
float horizonOcclusion = 1.3;
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
horizon *= horizon;
#if CAPTURING == 1
return float4(lerp(surface.baseColor.rgb,(irradiance + specular) * horizon,surface.metalness/2),0);
#else
return float4((irradiance + specular) * horizon, 0);//alpha writes disabled
#endif
}

View file

@ -67,7 +67,6 @@ uniform float4x4 worldToLightProj;
uniform float4 lightParams;
uniform float shadowSoftness;
uniform float3 eyePosWorld;
uniform float4x4 cameraToWorld;
uniform float4x4 worldToCamera;
@ -147,12 +146,12 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
#ifdef DETAIL_LIGHTING_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
float3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
float3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
vec3 final = max(vec3(0.0f), diffuse + spec * surface.F) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams );
vec3 final = max(float3(0.0f), diffuse + spec * surface.F) * getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams );
return final;
#endif

View file

@ -42,7 +42,6 @@ uniform float4 lightColor;
uniform float4 lightAmbient;
uniform float shadowSoftness;
uniform float3 eyePosWorld;
uniform float4 atlasXOffset;
uniform float4 atlasYOffset;