Corrected the blending logic somewhat, added visualization modes for spec/diffuse probe influences, attenuation and contribution.

This commit is contained in:
Areloch 2019-02-17 03:47:40 -06:00
parent 8d08ab2370
commit b754c022ba
6 changed files with 271 additions and 81 deletions

View file

@ -272,6 +272,8 @@ bool ReflectionProbe::onAdd()
{
createGeometry();
updateProbeParams();
PROBEMGR->registerProbe(mProbeInfoIdx);
}
setMaskBits(-1);
@ -281,6 +283,10 @@ bool ReflectionProbe::onAdd()
void ReflectionProbe::onRemove()
{
if (isClientObject())
{
PROBEMGR->unregisterProbe(mProbeInfoIdx);
}
// Remove this object from the scene
removeFromScene();
@ -441,7 +447,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
updateMaterial();
}
//PROBEMGR->updateProbes();
PROBEMGR->updateProbes();
}
void ReflectionProbe::createGeometry()
@ -597,6 +603,8 @@ void ReflectionProbe::updateMaterial()
mProbeInfo->mIsEnabled = true;
else
mProbeInfo->mIsEnabled = false;
PROBEMGR->updateProbes();
}
bool ReflectionProbe::createClientResources()
@ -682,7 +690,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
mProbeInfo->mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
//Register
PROBEMGR->registerProbe(mProbeInfoIdx);
//PROBEMGR->registerProbe(mProbeInfoIdx);
if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
{

View file

@ -230,7 +230,7 @@ void RenderProbeMgr::registerProbe(U32 probeIdx)
mRegisteredProbes.push_back_unique(probeIdx);
//rebuild our probe data
//_setupStaticParameters();
_setupStaticParameters();
}
void RenderProbeMgr::unregisterProbe(U32 probeIdx)
@ -242,7 +242,7 @@ void RenderProbeMgr::unregisterProbe(U32 probeIdx)
mRegisteredProbes.remove(probeIdx);
//rebuild our probe data
//_setupStaticParameters();
_setupStaticParameters();
}
//
@ -283,22 +283,21 @@ void RenderProbeMgr::_setupStaticParameters()
probeWorldToObjData.setSize(MAXPROBECOUNT);
probeBBMinData.setSize(MAXPROBECOUNT);
probeBBMaxData.setSize(MAXPROBECOUNT);
probeUseSphereModeData.setSize(MAXPROBECOUNT);
probeRadiusData.setSize(MAXPROBECOUNT);
probeAttenuationData.setSize(MAXPROBECOUNT);
probeConfigData.setSize(MAXPROBECOUNT);
}
probePositionsData.fill(Point4F::Zero);
probeWorldToObjData.fill(MatrixF::Identity);
probeBBMinData.fill(Point4F::Zero);
probeBBMaxData.fill(Point4F::Zero);
probeUseSphereModeData.fill(Point4F::Zero);
probeRadiusData.fill(Point4F::Zero);
probeAttenuationData.fill(Point4F::Zero);
probeConfigData.fill(Point4F::Zero);
cubeMaps.clear();
irradMaps.clear();
//This should probably ultimately be a per-probe value, but for now, global for testing/adjustability
F32 attenuation = Con::getFloatVariable("$pref::ReflectionProbes::AttenuationStrength", 3.5);
for (U32 i = 0; i < probeCount; i++)
{
if (mEffectiveProbeCount >= MAXPROBECOUNT)
@ -320,7 +319,7 @@ void RenderProbeMgr::_setupStaticParameters()
if (curEntry.mIsSkylight)
continue;
mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels();
mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels();
//Setup
Point3F probePos = curEntry.getPosition() + curEntry.mProbePosOffset;
@ -331,10 +330,10 @@ void RenderProbeMgr::_setupStaticParameters()
probeBBMinData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.minExtents.x, curEntry.mBounds.minExtents.y, curEntry.mBounds.minExtents.z, 0);
probeBBMaxData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.maxExtents.x, curEntry.mBounds.maxExtents.y, curEntry.mBounds.maxExtents.z, 0);
probeUseSphereModeData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 0,0,0);
probeRadiusData[mEffectiveProbeCount] = Point4F(curEntry.mRadius,0,0,0);
probeAttenuationData[mEffectiveProbeCount] = Point4F(1, 0, 0, 0);
probeConfigData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0,
curEntry.mRadius,
attenuation,
1);
cubeMaps.push_back(curEntry.mCubemap);
irradMaps.push_back(curEntry.mIrradianceCubemap);
@ -423,7 +422,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
static AlignedArray<Point3F> probeLocalPositions(4, sizeof(Point3F));
static AlignedArray<F32> probeIsSphere(4, sizeof(F32));
//static AlignedArray<CubemapData> probeCubemap(4, sizeof(CubemapData));
F32 range;
//F32 range;
// Need to clear the buffers so that we don't leak
// lights from previous passes or have NaNs.
@ -437,7 +436,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
matSet.restoreSceneViewProjection();
const MatrixF &worldToCameraXfm = matSet.getWorldToCamera();
//const MatrixF &worldToCameraXfm = matSet.getWorldToCamera();
// Gather the data for the first 4 probes.
/*const ProbeRenderInst *probe;
@ -586,7 +585,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
if (getProbeArrayEffect() == nullptr)
return;
updateProbes();
//updateProbes();
// Early out if nothing to draw.
if (!ProbeRenderInst::all.size() || !RenderProbeMgr::smRenderReflectionProbes || mEffectiveProbeCount == 0
@ -605,13 +604,43 @@ void RenderProbeMgr::render( SceneRenderState *state )
//_setupPerFrameParameters(state);
//Array rendering
U32 probeCount = ProbeRenderInst::all.size();
//U32 probeCount = ProbeRenderInst::all.size();
if (mEffectiveProbeCount != 0)
{
mProbeArrayEffect->setCubemapArrayTexture(4, mCubemapArray);
mProbeArrayEffect->setCubemapArrayTexture(5, mIrradArray);
String useDebugAtten = Con::getVariable("$Probes::showAttenuation", "0");
mProbeArrayEffect->setShaderMacro("DEBUGVIZ_ATTENUATION", useDebugAtten);
String useDebugSpecCubemap = Con::getVariable("$Probes::showSpecularCubemaps", "0");
mProbeArrayEffect->setShaderMacro("DEBUGVIZ_SPECCUBEMAP", useDebugSpecCubemap);
String useDebugDiffuseCubemap = Con::getVariable("$Probes::showDiffuseCubemaps", "0");
mProbeArrayEffect->setShaderMacro("DEBUGVIZ_DIFFCUBEMAP", useDebugDiffuseCubemap);
String useDebugContrib = Con::getVariable("$Probes::showProbeContrib", "0");
mProbeArrayEffect->setShaderMacro("DEBUGVIZ_CONTRIB", useDebugContrib);
if (useDebugContrib == String("1"))
{
MRandomLCG RandomGen;
RandomGen.setSeed(mEffectiveProbeCount);
//also set up some colors
Vector<Point4F> contribColors;
contribColors.setSize(MAXPROBECOUNT);
for (U32 i = 0; i < mEffectiveProbeCount; i++)
{
contribColors[i] = Point4F(RandomGen.randF(0, 1), RandomGen.randF(0, 1), RandomGen.randF(0, 1),1);
}
mProbeArrayEffect->setShaderConst("$probeContribColors", contribColors);
}
mProbeArrayEffect->setShaderConst("$cubeMips", (float)mMipCount);
mProbeArrayEffect->setShaderConst("$numProbes", (float)mEffectiveProbeCount);
@ -619,9 +648,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData);
mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMinData);
mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMaxData);
mProbeArrayEffect->setShaderConst("$useSphereMode", probeUseSphereModeData);
mProbeArrayEffect->setShaderConst("$radius", probeRadiusData);
mProbeArrayEffect->setShaderConst("$attenuation", probeAttenuationData);
mProbeArrayEffect->setShaderConst("$probeConfigData", probeConfigData);
}
// Make sure the effect is gonna render.

View file

@ -164,9 +164,7 @@ class RenderProbeMgr : public RenderBinManager
Vector<MatrixF> probeWorldToObjData;
Vector<Point4F> probeBBMinData;
Vector<Point4F> probeBBMaxData;
Vector<Point4F> probeUseSphereModeData;
Vector<Point4F> probeRadiusData;
Vector<Point4F> probeAttenuationData;
Vector<Point4F> probeConfigData;
Vector<GFXCubemapHandle> cubeMaps;
Vector<GFXCubemapHandle> irradMaps;

View file

@ -132,7 +132,7 @@ new SimGroup(MissionGroup) {
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "0 0 4";
position = "-0.0194688 0 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
@ -152,7 +152,7 @@ new SimGroup(MissionGroup) {
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "-10 8 4";
position = "-7.18203 8.03441 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
@ -171,7 +171,7 @@ new SimGroup(MissionGroup) {
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "-10 0 4";
position = "-10.0428 0.020255 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
@ -190,7 +190,7 @@ new SimGroup(MissionGroup) {
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "-10 -8 4";
position = "-7.8725 -8.01423 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
@ -203,6 +203,120 @@ new SimGroup(MissionGroup) {
reflectionPath = "levels/probeTest/probes/";
SkyColor = "0.5 0.5 1 1";
};
new BoxEnvironmentProbe() {
enabled = "1";
radius = "5";
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "-0.618301 -7.21245 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "9b2db461-3291-11e9-8898-df29fd75d18c";
GroundColor = "0.8 0.7 0.5 1";
IndirectLight = "1 1 1 1";
IndirectLightMode = "Spherical Harmonics";
Intensity = "1";
reflectionPath = "levels/probeTest/probes/";
SkyColor = "0.5 0.5 1 1";
};
new BoxEnvironmentProbe() {
enabled = "1";
radius = "5";
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "-19.8124 -1.4213 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "9850277f-3291-11e9-8898-df29fd75d18c";
GroundColor = "0.8 0.7 0.5 1";
IndirectLight = "1 1 1 1";
IndirectLightMode = "Spherical Harmonics";
Intensity = "1";
reflectionPath = "levels/probeTest/probes/";
SkyColor = "0.5 0.5 1 1";
};
new BoxEnvironmentProbe() {
enabled = "1";
radius = "5";
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "-4.665 12.4006 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "9752cd1f-3291-11e9-8898-df29fd75d18c";
GroundColor = "0.8 0.7 0.5 1";
IndirectLight = "1 1 1 1";
IndirectLightMode = "Spherical Harmonics";
Intensity = "1";
reflectionPath = "levels/probeTest/probes/";
SkyColor = "0.5 0.5 1 1";
};
new BoxEnvironmentProbe() {
enabled = "1";
radius = "5";
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "-12.7966 11.7207 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "9536f9d8-3291-11e9-8898-df29fd75d18c";
GroundColor = "0.8 0.7 0.5 1";
IndirectLight = "1 1 1 1";
IndirectLightMode = "Spherical Harmonics";
Intensity = "1";
reflectionPath = "levels/probeTest/probes/";
SkyColor = "0.5 0.5 1 1";
};
new BoxEnvironmentProbe() {
enabled = "1";
radius = "5";
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "-16.0723 -6.9977 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "8f479759-3291-11e9-8898-df29fd75d18c";
GroundColor = "0.8 0.7 0.5 1";
IndirectLight = "1 1 1 1";
IndirectLightMode = "Spherical Harmonics";
Intensity = "1";
reflectionPath = "levels/probeTest/probes/";
SkyColor = "0.5 0.5 1 1";
};
new BoxEnvironmentProbe() {
enabled = "1";
radius = "5";
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
Bake = "0";
position = "-16.0723 5.77606 4";
rotation = "1 0 0 0";
scale = "5 5 5";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "8856e1d2-3291-11e9-8898-df29fd75d18c";
GroundColor = "0.8 0.7 0.5 1";
IndirectLight = "1 1 1 1";
IndirectLightMode = "Spherical Harmonics";
Intensity = "1";
reflectionPath = "levels/probeTest/probes/";
SkyColor = "0.5 0.5 1 1";
};
new ConvexShape() {
Material = "Grid512_Orange_Mat";
position = "0.487092 0.454657 9.4951";
@ -213,7 +327,7 @@ new SimGroup(MissionGroup) {
surface = "0 0 0 1 0 0 0.5";
surface = "0 1 0 0 0 0 -0.5";
surface = "0.707107 0 0 0.707107 0 0.5 0";
surface = "0.707107 0 0 0.707106 0 0.5 0";
surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@ -228,7 +342,7 @@ new SimGroup(MissionGroup) {
surface = "0 0 0 1 0 0 0.5";
surface = "0 1 0 0 0 0 -0.5";
surface = "0.707107 0 0 0.707107 0 0.5 0";
surface = "0.707107 0 0 0.707106 0 0.5 0";
surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@ -243,7 +357,7 @@ new SimGroup(MissionGroup) {
surface = "0 0 0 1 0 0 0.5";
surface = "0 1 0 0 0 0 -0.5";
surface = "0.707107 0 0 0.707106 0 0.5 0";
surface = "0.707107 0 0 0.707107 0 0.5 0";
surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@ -258,7 +372,7 @@ new SimGroup(MissionGroup) {
surface = "0 0 0 1 0 0 0.5";
surface = "0 1 0 0 0 0 -0.5";
surface = "0.707107 0 0 0.707106 0 0.5 0";
surface = "0.707107 0 0 0.707107 0 0.5 0";
surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@ -273,7 +387,7 @@ new SimGroup(MissionGroup) {
surface = "0 0 0 1 0 0 0.5";
surface = "0 1 0 0 0 0 -0.5";
surface = "0.707107 0 0 0.707106 0 0.5 0";
surface = "0.707107 0 0 0.707107 0 0.5 0";
surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@ -288,7 +402,7 @@ new SimGroup(MissionGroup) {
surface = "0 0 0 1 0 0 0.5";
surface = "0 1 0 0 0 0 -0.5";
surface = "0.707107 0 0 0.707107 0 0.5 0";
surface = "0.707107 0 0 0.707106 0 0.5 0";
surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@ -303,7 +417,7 @@ new SimGroup(MissionGroup) {
surface = "0 0 0 1 0 0 0.5";
surface = "0 1 0 0 0 0 -0.5";
surface = "0.707107 0 0 0.707106 0 0.5 0";
surface = "0.707107 0 0 0.707107 0 0.5 0";
surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";

View file

@ -26,15 +26,20 @@ uniform float4 inProbePosArray[MAX_PROBES];
uniform float4x4 worldToObjArray[MAX_PROBES];
uniform float4 bbMinArray[MAX_PROBES];
uniform float4 bbMaxArray[MAX_PROBES];
uniform float4 useSphereMode[MAX_PROBES];
uniform float4 radius[MAX_PROBES];
uniform float4 attenuation[MAX_PROBES];
uniform float4 probeConfigData[MAX_PROBES]; //r,g,b/mode,radius,atten
#if DEBUGVIZ_CONTRIB
uniform float4 probeContribColors[MAX_PROBES];
#endif
// Box Projected IBL Lighting
// Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/
// and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
float3 boxProject(float3 wsPosition, float3 reflectDir, float3 boxWSPos, float3 boxMin, float3 boxMax)
float3 boxProject(float3 wsPosition, float3 wsEyeRay, float3 reflectDir, float3 boxWSPos, float3 boxMin, float3 boxMax)
{
//float3 rayLS = mul(worldToObjArray[id], float4(wsEyeRay, 1.0)).xyz;
//float3 reflCameraLS = mul(worldToObjArray[id], float4(reflectDir), 1.0)).xyz;
float3 nrdir = reflectDir;
float3 offset = wsPosition;
float3 plane1vec = (boxMax - offset) / nrdir;
@ -49,23 +54,19 @@ float3 boxProject(float3 wsPosition, float3 reflectDir, float3 boxWSPos, float3
float3 iblBoxDiffuse( Surface surface, int id)
{
float3 cubeN = boxProject(surface.P, surface.N, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz);
float3 cubeN = boxProject(surface.P, surface.V, surface.R, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz);
cubeN.z *=-1;
return TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR,cubeN,id,0).xyz;
}
float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTexture), int id)
float3 iblBoxSpecular(Surface surface, TORQUE_SAMPLER2D(brdfTexture), int id)
{
float ndotv = clamp(dot(surface.N, surfToEye), 0.0, 1.0);
// BRDF
float2 brdf = TORQUE_TEX2DLOD(brdfTexture, float4(surface.roughness, ndotv,0.0,0.0)).xy;
float2 brdf = TORQUE_TEX2DLOD(brdfTexture, float4(surface.roughness, surface.NdotV,0.0,0.0)).xy;
// Radiance (Specular)
float lod = surface.roughness*cubeMips;
float3 r = reflect(surfToEye, surface.N);
float3 cubeR = normalize(r);
cubeR = boxProject(surface.P, surface.N, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz);
float3 cubeR = boxProject(surface.P, surface.V, surface.R, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz);
float3 radiance = TORQUE_TEXCUBEARRAYLOD(cubeMapAR,cubeR,id,lod).xyz * (brdf.x + brdf.y);
@ -74,14 +75,13 @@ float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTe
float defineBoxSpaceInfluence(Surface surface, int id)
{
float tempAttenVal = 3.5; //replace with per probe atten
float3 surfPosLS = mul( worldToObjArray[id], float4(surface.P,1.0)).xyz;
float3 boxMinLS = inProbePosArray[id].xyz-(float3(1,1,1)*radius[id].x);
float3 boxMaxLS = inProbePosArray[id].xyz+(float3(1,1,1)*radius[id].x);
float3 boxMinLS = inProbePosArray[id].xyz-(float3(1,1,1)*probeConfigData[id].g);
float3 boxMaxLS = inProbePosArray[id].xyz+(float3(1,1,1)*probeConfigData[id].g);
float boxOuterRange = length(boxMaxLS - boxMinLS);
float boxInnerRange = boxOuterRange / tempAttenVal;
float boxInnerRange = boxOuterRange / probeConfigData[id].b;
float3 localDir = float3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z));
localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange);
@ -102,52 +102,47 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
if (getFlag(surface.matFlag, 0))
{
discard;
}
float blendVal[MAX_PROBES];
float3 surfToEye = normalize(surface.P - eyePosWorld);
}
int i = 0;
float blendVal[MAX_PROBES];
float blendSum = 0;
float invBlendSum = 0;
for(i=0; i < numProbes; i++)
{
if(useSphereMode[i].r)
for (i = 0; i < numProbes; i++)
{
if (probeConfigData[i].r)
{
float3 L = inProbePosArray[i].xyz - surface.P;
blendVal[i] = 1.0-length(L)/radius[i].r;
blendVal[i] = max(0,blendVal[i]);
float3 L = inProbePosArray[i].xyz - surface.P;
blendVal[i] = 1.0 - length(L) / probeConfigData[i].g;
blendVal[i] = max(0, blendVal[i]);
}
else
{
blendVal[i] = defineBoxSpaceInfluence(surface, i);
blendVal[i] = max(0,blendVal[i]);
blendVal[i] = defineBoxSpaceInfluence(surface, i);
blendVal[i] = max(0, blendVal[i]);
}
blendSum += blendVal[i];
invBlendSum +=(1.0f - blendVal[i]);
blendSum += blendVal[i];
invBlendSum += (1.0f - blendVal[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.
for(i=0; i < numProbes; i++)
//This is what's cross-contaminating between probe's influence areas.
//Need to review this logic before we utilize it again
/*for (i = 0; i < numProbes; i++)
{
blendVal[i] = (1.0f - ( blendVal[i] / blendSum)) / (numProbes - 1);
blendVal[i] = (1.0f - (blendVal[i] / blendSum)) / (numProbes - 1);
blendVal[i] *= ((1.0f - blendVal[i]) / invBlendSum);
blendSum += blendVal[i];
}
}*/
float finalSum = blendSum;
//return TORQUE_TEX2D(colorBuffer, IN.uv0.xy);
//return float4(surface.N,1);
//return float4(1,1,1, 1);
//return float4(finalSum,finalSum,finalSum, 1);
// Normalize blendVal
// Normalize blendVal
if (blendSum == 0.0f) // Possible with custom weight
{
blendSum = 1.0f;
@ -158,6 +153,28 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
{
blendVal[i] *= invBlendSumWeighted;
}
//return float4(blendVal[0], blendVal[0], blendVal[0], 1);
#if DEBUGVIZ_ATTENUATION == 1
return float4(blendSum, blendSum, blendSum, 1);
#endif
#if DEBUGVIZ_CONTRIB == 1
float3 finalContribColor = float3(0, 0, 0);
for (i = 0; i < numProbes; ++i)
{
if (blendVal[i] == 0)
continue;
finalContribColor += blendSum * probeContribColors[i].rgb;
}
return float4(finalContribColor, 1);
#endif
#if DEBUGVIZ_SPECCUBEMAP == 0 && DEBUGVIZ_DIFFCUBEMAP == 0
float3 irradiance = float3(0,0,0);
float3 specular = float3(0,0,0);
@ -168,13 +185,35 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
kD *= 1.0 - surface.metalness;
for (i = 0; i < numProbes; ++i)
{
irradiance += blendVal[i]*iblBoxDiffuse(surface,i);
if (blendVal[i] == 0)
continue;
irradiance += blendVal[i]*iblBoxDiffuse(surface, i);
specular += blendVal[i]*F*iblBoxSpecular(surface, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture),i);
specular += blendVal[i]*F*iblBoxSpecular(surface, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture),i);
}
//final diffuse color
float3 diffuse = kD * irradiance * surface.baseColor.rgb;
float4 finalColor = float4(diffuse + specular * surface.ao, blendSum);
return finalColor;
#elif DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0
float3 cubeColor = float3(0, 0, 0);
for (i = 0; i < numProbes; ++i)
{
cubeColor += blendVal[i] * iblBoxSpecular(surface, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture), i);
}
return float4(cubeColor,1);
#elif DEBUGVIZ_DIFFCUBEMAP == 1
float3 cubeColor = float3(0, 0, 0);
for (i = 0; i < numProbes; ++i)
{
cubeColor += blendVal[i] * iblBoxDiffuse(surface, i);
}
return float4(cubeColor, 1);
#endif
}

View file

@ -130,6 +130,10 @@ function initializeWorldEditor()
EVisibility.addOption( "AL: Backbuffer", "$AL_BackbufferVisualizeVar", "toggleBackbufferViz" );
EVisibility.addOption( "AL: Glow Buffer", "$AL_GlowVisualizeVar", "toggleGlowViz" );
EVisibility.addOption( "AL: PSSM Cascade Viz", "$AL::PSSMDebugRender", "" );
EVisibility.addOption( "Probes: Attenuation", "$Probes::showAttenuation", "" );
EVisibility.addOption( "Probes: Specular Cubemaps", "$Probes::showSpecularCubemaps", "" );
EVisibility.addOption( "Probes: Diffuse Cubemaps", "$Probes::showDiffuseCubemaps", "" );
EVisibility.addOption( "Probes: Contribution", "$Probes::showProbeContrib", "" );
EVisibility.addOption( "Frustum Lock", "$Scene::lockCull", "" );
EVisibility.addOption( "Disable Zone Culling", "$Scene::disableZoneCulling", "" );
EVisibility.addOption( "Disable Terrain Occlusion", "$Scene::disableTerrainOcclusion", "" );