Undid debug work, shifted logic over entirely to utilize the updateTexture methods. Refactored probe init'ing so they'll load correctly without nudging, properly sequestered skylights from the probe array and updated the shader to contain az's changes as well as skylight and probe array changes.

This commit is contained in:
Areloch 2019-03-25 23:17:53 -05:00
parent e241cbc7c9
commit 4c959e1fa1
7 changed files with 141 additions and 262 deletions

View file

@ -168,6 +168,10 @@ void BoxEnvironmentProbe::updateProbeParams()
mProbeInfo->mProbeShapeType = ProbeRenderInst::Box; mProbeInfo->mProbeShapeType = ProbeRenderInst::Box;
mProbeInfo->mAtten = mAtten; mProbeInfo->mAtten = mAtten;
PROBEMGR->updateProbes();
updateCubemaps();
} }
void BoxEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat) void BoxEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat)

View file

@ -294,8 +294,6 @@ bool ReflectionProbe::onAdd()
{ {
createGeometry(); createGeometry();
updateProbeParams(); updateProbeParams();
PROBEMGR->registerProbe(mProbeInfoIdx);
} }
setMaskBits(-1); setMaskBits(-1);
@ -458,6 +456,8 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
mathRead(*stream, &mProbeRefOffset); mathRead(*stream, &mProbeRefOffset);
mathRead(*stream, &mProbeRefScale); mathRead(*stream, &mProbeRefScale);
mDirty = true;
} }
if (stream->readFlag()) // ShapeTypeMask if (stream->readFlag()) // ShapeTypeMask
@ -467,24 +467,30 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
mProbeShapeType = (ProbeRenderInst::ProbeShapeType)shapeType; mProbeShapeType = (ProbeRenderInst::ProbeShapeType)shapeType;
createGeometry(); createGeometry();
mDirty = true;
} }
if (stream->readFlag()) // UpdateMask if (stream->readFlag()) // UpdateMask
{ {
stream->read(&mRadius); stream->read(&mRadius);
mDirty = true;
} }
if (stream->readFlag()) // BakeInfoMask if (stream->readFlag()) // BakeInfoMask
{ {
stream->read(&mProbeUniqueID); stream->read(&mProbeUniqueID);
mDirty = true;
} }
if (stream->readFlag()) // EnabledMask if (stream->readFlag()) // EnabledMask
{ {
mEnabled = stream->readFlag(); mEnabled = stream->readFlag();
}
bool isMaterialDirty = false; mDirty = true;
}
if (stream->readFlag()) // ModeMask if (stream->readFlag()) // ModeMask
{ {
@ -492,7 +498,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
stream->read(&reflectModeType); stream->read(&reflectModeType);
mReflectionModeType = (ReflectionModeType)reflectModeType; mReflectionModeType = (ReflectionModeType)reflectModeType;
isMaterialDirty = true; mDirty = true;
} }
if (stream->readFlag()) // CubemapMask if (stream->readFlag()) // CubemapMask
@ -505,7 +511,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
processStaticCubemap(); processStaticCubemap();
} }
isMaterialDirty = true; mDirty = true;
} }
if (mDirty) if (mDirty)
@ -524,9 +530,9 @@ void ReflectionProbe::updateProbeParams()
mProbeInfo = new ProbeRenderInst(); mProbeInfo = new ProbeRenderInst();
mProbeInfoIdx = ProbeRenderInst::all.size() - 1; mProbeInfoIdx = ProbeRenderInst::all.size() - 1;
mProbeInfo->mIsEnabled = false; mProbeInfo->mIsEnabled = false;
}
updateCubemaps(); PROBEMGR->registerProbe(mProbeInfoIdx);
}
mProbeInfo->mProbeShapeType = mProbeShapeType; mProbeInfo->mProbeShapeType = mProbeShapeType;
@ -607,7 +613,8 @@ void ReflectionProbe::processStaticCubemap()
mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap; mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap;
//Update the probe manager with our new texture! //Update the probe manager with our new texture!
//PROBEMGR->updateProbeTexture(mProbeInfo); if(!mProbeInfo->mIsSkylight)
PROBEMGR->updateProbeTexture(mProbeInfo);
} }
void ReflectionProbe::updateCubemaps() void ReflectionProbe::updateCubemaps()
@ -658,10 +665,8 @@ void ReflectionProbe::updateCubemaps()
else else
mProbeInfo->mIsEnabled = false; mProbeInfo->mIsEnabled = false;
PROBEMGR->updateProbes(); if (!mProbeInfo->mIsSkylight && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
PROBEMGR->updateProbeTexture(mProbeInfo);
//if (mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
// PROBEMGR->updateProbeTexture(mProbeInfo);
} }
bool ReflectionProbe::createClientResources() bool ReflectionProbe::createClientResources()

View file

@ -179,6 +179,10 @@ void Skylight::updateProbeParams()
mProbeInfo->mIsSkylight = true; mProbeInfo->mIsSkylight = true;
mProbeInfo->mScore = -1.0f; //sky comes first mProbeInfo->mScore = -1.0f; //sky comes first
PROBEMGR->updateProbes();
updateCubemaps();
} }
void Skylight::prepRenderImage(SceneRenderState *state) void Skylight::prepRenderImage(SceneRenderState *state)

View file

@ -154,6 +154,10 @@ void SphereEnvironmentProbe::updateProbeParams()
Parent::updateProbeParams(); Parent::updateProbeParams();
mProbeInfo->mProbeShapeType = ProbeRenderInst::Sphere; mProbeInfo->mProbeShapeType = ProbeRenderInst::Sphere;
PROBEMGR->updateProbes();
updateCubemaps();
} }
void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state) void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state)

View file

@ -84,7 +84,8 @@ ProbeRenderInst::ProbeRenderInst() : SystemInterface(),
mProbeRefOffset(0, 0, 0), mProbeRefOffset(0, 0, 0),
mProbeRefScale(1,1,1), mProbeRefScale(1,1,1),
mAtten(0.0), mAtten(0.0),
mCubemapIndex(0) mCubemapIndex(0),
mIsSkylight(false)
{ {
} }
@ -285,38 +286,43 @@ void RenderProbeMgr::registerProbe(U32 probeIdx)
mRegisteredProbes.push_back_unique(probeIdx); mRegisteredProbes.push_back_unique(probeIdx);
const U32 cubeIndex = _findNextEmptyCubeSlot(); if (!ProbeRenderInst::all[probeIdx]->mIsSkylight)
if (cubeIndex == INVALID_CUBE_SLOT)
{ {
Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot."); const U32 cubeIndex = _findNextEmptyCubeSlot();
return; if (cubeIndex == INVALID_CUBE_SLOT)
{
Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot.");
return;
}
//check if we need to resize the cubemap array
if (cubeIndex >= mCubeSlotCount)
{
//alloc temp array handles
GFXCubemapArrayHandle irr = GFXCubemapArrayHandle(GFX->createCubemapArray());
GFXCubemapArrayHandle prefilter = GFXCubemapArrayHandle(GFX->createCubemapArray());
irr->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_IRRAD_SIZE, PROBE_FORMAT);
prefilter->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_PREFILTER_SIZE, PROBE_FORMAT);
mIrradianceArray->copyTo(irr);
mPrefilterArray->copyTo(prefilter);
//assign the temp handles to the new ones, this will destroy the old ones as well
mIrradianceArray = irr;
mPrefilterArray = prefilter;
mCubeSlotCount += PROBE_ARRAY_SLOT_BUFFER_SIZE;
}
ProbeRenderInst::all[probeIdx]->mCubemapIndex = cubeIndex;
//mark cubemap slot as taken
mCubeMapSlots[cubeIndex] = true;
mCubeMapCount++;
Con::warnf("RenderProbeMgr::registerProbe: Registered probe %u to cubeIndex %u", probeIdx, cubeIndex);
} }
//check if we need to resize the cubemap array
if (cubeIndex >= mCubeSlotCount)
{
//alloc temp array handles
GFXCubemapArrayHandle irr = GFXCubemapArrayHandle(GFX->createCubemapArray());
GFXCubemapArrayHandle prefilter = GFXCubemapArrayHandle(GFX->createCubemapArray());
irr->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_IRRAD_SIZE, PROBE_FORMAT);
prefilter->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_PREFILTER_SIZE, PROBE_FORMAT);
mIrradianceArray->copyTo(irr);
mPrefilterArray->copyTo(prefilter);
//assign the temp handles to the new ones, this will destroy the old ones as well
mIrradianceArray = irr;
mPrefilterArray = prefilter;
mCubeSlotCount += PROBE_ARRAY_SLOT_BUFFER_SIZE;
}
ProbeRenderInst::all[probeIdx]->mCubemapIndex = cubeIndex;
//mark cubemap slot as taken
mCubeMapSlots[cubeIndex] = true;
mCubeMapCount++;
//rebuild our probe data //rebuild our probe data
_setupStaticParameters(); _setupStaticParameters();
} }
@ -446,7 +452,7 @@ void RenderProbeMgr::_setupStaticParameters()
mEffectiveProbeCount++; mEffectiveProbeCount++;
} }
if (mEffectiveProbeCount != 0) /*if (mEffectiveProbeCount != 0)
{ {
bool useOldWay = false; bool useOldWay = false;
if (useOldWay) if (useOldWay)
@ -470,11 +476,15 @@ void RenderProbeMgr::_setupStaticParameters()
mPrefilterArray->updateTexture(cubeMaps[i], cubeIndex); mPrefilterArray->updateTexture(cubeMaps[i], cubeIndex);
} }
} }
} }*/
} }
void RenderProbeMgr::updateProbeTexture(ProbeRenderInst* probe) void RenderProbeMgr::updateProbeTexture(ProbeRenderInst* probe)
{ {
//We don't stuff skylights into the array, so we can just skip out on this if it's a skylight
if (probe->mIsSkylight)
return;
S32 probeIdx = ProbeRenderInst::all.find_next(probe); S32 probeIdx = ProbeRenderInst::all.find_next(probe);
if (probeIdx != -1) //i mean, the opposite shouldn't even be possible if (probeIdx != -1) //i mean, the opposite shouldn't even be possible
@ -489,6 +499,9 @@ void RenderProbeMgr::updateProbeTexture(U32 probeIdx)
const U32 cubeIndex = ProbeRenderInst::all[probeIdx]->mCubemapIndex; const U32 cubeIndex = ProbeRenderInst::all[probeIdx]->mCubemapIndex;
mIrradianceArray->updateTexture(ProbeRenderInst::all[probeIdx]->mIrradianceCubemap, cubeIndex); mIrradianceArray->updateTexture(ProbeRenderInst::all[probeIdx]->mIrradianceCubemap, cubeIndex);
mPrefilterArray->updateTexture(ProbeRenderInst::all[probeIdx]->mPrefilterCubemap, cubeIndex); mPrefilterArray->updateTexture(ProbeRenderInst::all[probeIdx]->mPrefilterCubemap, cubeIndex);
Con::warnf("UpdatedProbeTexture - probeIdx: %u on cubeIndex %u, Irrad validity: %d, Prefilter validity: %d", probeIdx, cubeIndex,
ProbeRenderInst::all[probeIdx]->mIrradianceCubemap->isInitialized(), ProbeRenderInst::all[probeIdx]->mPrefilterCubemap->isInitialized());
} }
void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state) void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)

View file

@ -41,7 +41,7 @@ new SimGroup(MissionGroup) {
enabled = "1"; enabled = "1";
ReflectionMode = "Baked Cubemap"; ReflectionMode = "Baked Cubemap";
StaticCubemap = "sky_day_hdr_cubemap"; StaticCubemap = "sky_day_hdr_cubemap";
position = "0 0 -0.0560153"; position = "0 0.704113 16.1515";
rotation = "1 0 0 0"; rotation = "1 0 0 0";
canSave = "1"; canSave = "1";
canSaveDynamicFields = "1"; canSaveDynamicFields = "1";
@ -81,7 +81,7 @@ new SimGroup(MissionGroup) {
squareSize = "128"; squareSize = "128";
scaleU = "25"; scaleU = "25";
scaleV = "25"; scaleV = "25";
Material = "Grid512_Grey_Mat"; Material = "Floor_Material";
canSave = "1"; canSave = "1";
canSaveDynamicFields = "1"; canSaveDynamicFields = "1";
enabled = "1"; enabled = "1";
@ -130,32 +130,13 @@ new SimGroup(MissionGroup) {
refOffset = "0 0 0"; refOffset = "0 0 0";
refScale = "10 10 10"; refScale = "10 10 10";
ReflectionMode = "Baked Cubemap"; ReflectionMode = "Baked Cubemap";
position = "0.130544 0.492826 4.70918"; position = "0.130544 0.239855 4.8594";
rotation = "1 0 0 0"; rotation = "1 0 0 0";
scale = "10 10 10"; scale = "10 10 10";
canSave = "1"; canSave = "1";
canSaveDynamicFields = "1"; canSaveDynamicFields = "1";
persistentId = "8072e1be-2846-11e7-9f56-abd46b190c60"; persistentId = "8072e1be-2846-11e7-9f56-abd46b190c60";
}; attenuation = "0";
new BoxEnvironmentProbe() {
enabled = "1";
refOffset = "0 0 0";
refScale = "10 10 10";
ReflectionMode = "Baked Cubemap";
position = "-26.7509 2.50947 1.94424";
rotation = "0 0 -1 27.2465";
scale = "10 5 10";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "f281a5ff-1ae9-11e9-9c9a-df9135416cc7";
GroundColor = "0.8 0.7 0.5 1";
IndirectLight = "1 1 1 1";
IndirectLightMode = "Spherical Harmonics";
Intensity = "1";
posOffset = "0 0 0";
radius = "5";
reflectionPath = "levels/probeTest/probes/";
SkyColor = "0.5 0.5 1 1";
}; };
new ConvexShape() { new ConvexShape() {
Material = "Grid512_Orange_Mat"; Material = "Grid512_Orange_Mat";
@ -324,114 +305,18 @@ new SimGroup(MissionGroup) {
canSave = "1"; canSave = "1";
canSaveDynamicFields = "1"; canSaveDynamicFields = "1";
}; };
new SphereEnvironmentProbe() { new BoxEnvironmentProbe() {
enabled = "1"; enabled = "1";
radius = "5";
refOffset = "0 0 0"; refOffset = "0 0 0";
refScale = "10 10 10"; refScale = "10 10 10";
ReflectionMode = "Baked Cubemap"; ReflectionMode = "Baked Cubemap";
StaticCubemap = "HdrSkyCubemap"; position = "-22.7696 0.224002 4.70918";
position = "-25.5075 8.33063 1.52035";
rotation = "1 0 0 0"; rotation = "1 0 0 0";
scale = "10 10 10";
canSave = "1"; canSave = "1";
canSaveDynamicFields = "1"; canSaveDynamicFields = "1";
persistentId = "c4bc9059-3cb4-11e9-933c-d270d89e32b9"; persistentId = "d84cbe5b-4f76-11e9-977c-a561a736e3eb";
}; attenuation = "0";
new TSStatic() {
shapeName = "art/yorks/chapel/Module_Common/SB_chapel_ext.dae";
playAmbient = "1";
meshCulling = "0";
originSort = "0";
CollisionType = "Collision Mesh";
DecalType = "Collision Mesh";
allowPlayerStep = "0";
alphaFadeEnable = "0";
alphaFadeStart = "100";
alphaFadeEnd = "150";
alphaFadeInverse = "0";
renderNormals = "0";
forceDetail = "-1";
ignoreZodiacs = "0";
useGradientRange = "0";
gradientRange = "0 180";
invertGradientRange = "0";
position = "0.569034 -19.8511 -0.101853";
rotation = "1 0 0 0";
scale = "1 1 1";
canSave = "1";
canSaveDynamicFields = "1";
};
new TSStatic() {
shapeName = "art/yorks/chapel/Module_Common/LMA_chapel_int.dae";
playAmbient = "1";
meshCulling = "0";
originSort = "0";
CollisionType = "Collision Mesh";
DecalType = "Collision Mesh";
allowPlayerStep = "0";
alphaFadeEnable = "0";
alphaFadeStart = "100";
alphaFadeEnd = "150";
alphaFadeInverse = "0";
renderNormals = "0";
forceDetail = "-1";
ignoreZodiacs = "0";
useGradientRange = "0";
gradientRange = "0 180";
invertGradientRange = "0";
position = "0.569034 -19.8511 -0.101853";
rotation = "1 0 0 0";
scale = "1 1 1";
canSave = "1";
canSaveDynamicFields = "1";
};
new TSStatic() {
shapeName = "art/yorks/chapel/Module_Common/LMX_chapel_props.dae";
playAmbient = "1";
meshCulling = "0";
originSort = "0";
CollisionType = "Collision Mesh";
DecalType = "Collision Mesh";
allowPlayerStep = "0";
alphaFadeEnable = "0";
alphaFadeStart = "100";
alphaFadeEnd = "150";
alphaFadeInverse = "0";
renderNormals = "0";
forceDetail = "-1";
ignoreZodiacs = "0";
useGradientRange = "0";
gradientRange = "0 180";
invertGradientRange = "0";
position = "0.569034 -19.8511 -0.101853";
rotation = "1 0 0 0";
scale = "1 1 1";
canSave = "1";
canSaveDynamicFields = "1";
};
new TSStatic() {
shapeName = "art/yorks/chapel/Module_Common/SB_chapel_glass.dae";
playAmbient = "1";
meshCulling = "0";
originSort = "0";
CollisionType = "Collision Mesh";
DecalType = "Collision Mesh";
allowPlayerStep = "0";
alphaFadeEnable = "0";
alphaFadeStart = "100";
alphaFadeEnd = "150";
alphaFadeInverse = "0";
renderNormals = "0";
forceDetail = "-1";
ignoreZodiacs = "0";
useGradientRange = "0";
gradientRange = "0 180";
invertGradientRange = "0";
position = "0.569034 -19.8511 -0.101853";
rotation = "1 0 0 0";
scale = "1 1 1";
canSave = "1";
canSaveDynamicFields = "1";
}; };
}; };
//--- OBJECT WRITE END --- //--- OBJECT WRITE END ---

View file

@ -76,11 +76,10 @@ float getDistBoxToPoint(float3 pt, float3 extents)
float defineBoxSpaceInfluence(Surface surface, ProbeData probe, float3 wsEyeRay) float defineBoxSpaceInfluence(Surface surface, ProbeData probe, float3 wsEyeRay)
{ {
float3 surfPosLS = mul(probe.worldToLocal, float4(surface.P, 1.0)).xyz; float3 surfPosLS = mul(probe.worldToLocal, float4(surface.P, 1.0)).xyz;
float probeattenuationvalue = 0.5; // feed meh float atten = 1.0-probe.attenuation;
float atten = 1.0 - probeattenuationvalue;
float baseVal = 0.25; float baseVal = 0.25;
float dist = getDistBoxToPoint(surfPosLS, float3(baseVal, baseVal, baseVal)); float dist = getDistBoxToPoint(surfPosLS,float3(baseVal,baseVal,baseVal));
return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist)); return saturate(smoothstep(baseVal+0.0001,atten*baseVal,dist));
} }
// Box Projected IBL Lighting // Box Projected IBL Lighting
@ -106,10 +105,7 @@ float3 iblBoxDiffuse(Surface surface, ProbeData probe)
float3 dir = boxProject(surface, probe); float3 dir = boxProject(surface, probe);
float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, probe.cubemapIdx, 0).xyz; float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, probe.cubemapIdx, 0).xyz;
if (probe.contribution>0) return color;
return color*probe.contribution;
else
return float3(0, 0, 0);
} }
float3 iblBoxSpecular(Surface surface, ProbeData probe) float3 iblBoxSpecular(Surface surface, ProbeData probe)
@ -127,22 +123,16 @@ float3 iblBoxSpecular(Surface surface, ProbeData probe)
#endif #endif
float3 color = TORQUE_TEXCUBEARRAYLOD(cubeMapAR, dir, probe.cubemapIdx, lod).xyz * (brdf.x + brdf.y); float3 color = TORQUE_TEXCUBEARRAYLOD(cubeMapAR, dir, probe.cubemapIdx, lod).xyz * (brdf.x + brdf.y);
if (probe.contribution>0)
return color*probe.contribution;
else
return float3(0, 0, 0);
}
float3 iblSkylightDiffuse(Surface surface, ProbeData probe)
{
float lod = surface.roughness*cubeMips;
float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.R, probe.probeIdx, lod).xyz;
return color; return color;
} }
float3 iblSkylightSpecular(Surface surface, ProbeData probe) float3 iblSkylightDiffuse(Surface surface)
{
float3 color = TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz;
return color;
}
float3 iblSkylightSpecular(Surface surface)
{ {
// BRDF // BRDF
float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV, 0.0, 0.0)).xy; float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV, 0.0, 0.0)).xy;
@ -154,8 +144,7 @@ float3 iblSkylightSpecular(Surface surface, ProbeData probe)
float lod = 0; float lod = 0;
#endif #endif
float3 color = TORQUE_TEXCUBEARRAYLOD(cubeMapAR, surface.R, probe.probeIdx, lod).xyz * (brdf.x + brdf.y); float3 color = TORQUE_TEXCUBELOD(skylightPrefilterMap, float4(surface.R, lod)).xyz * (brdf.x + brdf.y);
return color; return color;
} }
@ -223,24 +212,24 @@ float4 main(PFXVertToPix IN) : SV_TARGET
} }
// Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary. // 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). // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1).
// respect constraint B. // respect constraint B.
// Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary
// and respect constraint A. // and respect constraint A.
for (i = 0; i < numProbes; i++) for (i = 0; i < numProbes; i++)
{ {
if (probehits>1.0) if (probehits>1.0)
{ {
blendFactor[i] = ((probes[i].contribution / blendSum)) / (probehits - 1); blendFactor[i] = ((probes[i].contribution / blendSum)) / (probehits - 1);
blendFactor[i] *= ((probes[i].contribution) / invBlendSum); blendFactor[i] *= ((probes[i].contribution) / invBlendSum);
blendFacSum += blendFactor[i]; blendFacSum += blendFactor[i];
} }
else else
{ {
blendFactor[i] = probes[i].contribution; blendFactor[i] = probes[i].contribution;
blendFacSum = probes[i].contribution; blendFacSum = probes[i].contribution;
} }
} }
// Normalize blendVal // Normalize blendVal
@ -251,28 +240,25 @@ float4 main(PFXVertToPix IN) : SV_TARGET
} }
#endif #endif
//use probehits for sharp cuts when singular, if (probehits>1.0)
//blendSum when wanting blend on all edging {
if (blendSum>1.0) float invBlendSumWeighted = 1.0f / blendFacSum;
{ for (i = 0; i < numProbes; ++i)
float invBlendSumWeighted = 1.0f / blendFacSum; {
for (i = 0; i < numProbes; ++i) blendFactor[i] *= invBlendSumWeighted;
{ probes[i].contribution = saturate(blendFactor[i]);
blendFactor[i] *= invBlendSumWeighted;
probes[i].contribution = blendFactor[i];
alpha -= probes[i].contribution; alpha -= probes[i].contribution;
} }
} }
#if DEBUGVIZ_ATTENUATION == 1 #if DEBUGVIZ_ATTENUATION == 1
/*float attenVis = 0; float attenVis = 0;
for (i = 0; i < numProbes; ++i) for (i = 0; i < numProbes; ++i)
{ {
attenVis += probes[i].contribution; attenVis += probes[i].contribution;
} }
return float4(attenVis, attenVis, attenVis, 1);*/ return float4(attenVis, attenVis, attenVis, 1);
return float4(alpha, alpha, alpha, 1);
#endif #endif
#if DEBUGVIZ_CONTRIB == 1 #if DEBUGVIZ_CONTRIB == 1
@ -290,34 +276,6 @@ float4 main(PFXVertToPix IN) : SV_TARGET
#endif #endif
} }
if (hasSkylight && alpha == 1)
{
float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV, 0.0, 0.0)).xy;
float lod = surface.roughness*cubeMips;
#if DEBUGVIZ_SPECCUBEMAP == 0 && DEBUGVIZ_DIFFCUBEMAP == 0
float3 specular = TORQUE_TEXCUBELOD(skylightPrefilterMap, float4(surface.R, lod)).xyz * (brdf.x + brdf.y);
float3 irradiance = TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz;
float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
//energy conservation
float3 kD = 1.0.xxx - F;
kD *= 1.0 - surface.metalness;
float3 diffuse = kD * irradiance * surface.baseColor.rgb;
float4 finalColor = float4(diffuse + specular * surface.ao, alpha);
return finalColor;
#elif DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0
float3 specular = TORQUE_TEXCUBELOD(skylightPrefilterMap, float4(surface.R, lod)).xyz;
float4 finalColor = float4(specular, 1);
return finalColor;
#elif DEBUGVIZ_DIFFCUBEMAP == 1
float3 irradiance = TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz;
float4 finalColor = float4(irradiance, 1);
return finalColor;
#endif
}
#if DEBUGVIZ_SPECCUBEMAP == 0 && DEBUGVIZ_DIFFCUBEMAP == 0 #if DEBUGVIZ_SPECCUBEMAP == 0 && DEBUGVIZ_DIFFCUBEMAP == 0
float3 irradiance = float3(0, 0, 0); float3 irradiance = float3(0, 0, 0);
@ -336,15 +294,21 @@ float4 main(PFXVertToPix IN) : SV_TARGET
if (probes[i].type == 2) //skip skylight if (probes[i].type == 2) //skip skylight
continue; continue;
irradiance += iblBoxDiffuse(surface, probes[i]); irradiance += iblBoxDiffuse(surface, probes[i])*probes[i].contribution;
specular += F*iblBoxSpecular(surface, probes[i]); specular += F*iblBoxSpecular(surface, probes[i])*probes[i].contribution;
contrib += probes[i].contribution; contrib +=probes[i].contribution;
}
//contrib = saturate(contrib);
if (hasSkylight && alpha != 0)
{
irradiance = lerp(irradiance, iblSkylightDiffuse(surface), alpha);
specular = lerp(specular, F*iblSkylightSpecular(surface), alpha);
} }
contrib = saturate(contrib);
//final diffuse color //final diffuse color
float3 diffuse = kD * irradiance * surface.baseColor.rgb; float3 diffuse = kD * irradiance * surface.baseColor.rgb;
float4 finalColor = float4(diffuse + specular * surface.ao, blendFacSum); float4 finalColor = float4(diffuse + specular * surface.ao, 1.0);
return finalColor; return finalColor;