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 1627cbabe6
commit e2b194182c
7 changed files with 141 additions and 262 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -84,7 +84,8 @@ ProbeRenderInst::ProbeRenderInst() : SystemInterface(),
mProbeRefOffset(0, 0, 0),
mProbeRefScale(1,1,1),
mAtten(0.0),
mCubemapIndex(0)
mCubemapIndex(0),
mIsSkylight(false)
{
}
@ -285,38 +286,43 @@ void RenderProbeMgr::registerProbe(U32 probeIdx)
mRegisteredProbes.push_back_unique(probeIdx);
const U32 cubeIndex = _findNextEmptyCubeSlot();
if (cubeIndex == INVALID_CUBE_SLOT)
if (!ProbeRenderInst::all[probeIdx]->mIsSkylight)
{
Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot.");
return;
const U32 cubeIndex = _findNextEmptyCubeSlot();
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
_setupStaticParameters();
}
@ -446,7 +452,7 @@ void RenderProbeMgr::_setupStaticParameters()
mEffectiveProbeCount++;
}
if (mEffectiveProbeCount != 0)
/*if (mEffectiveProbeCount != 0)
{
bool useOldWay = false;
if (useOldWay)
@ -470,11 +476,15 @@ void RenderProbeMgr::_setupStaticParameters()
mPrefilterArray->updateTexture(cubeMaps[i], cubeIndex);
}
}
}
}*/
}
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);
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;
mIrradianceArray->updateTexture(ProbeRenderInst::all[probeIdx]->mIrradianceCubemap, 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)

View file

@ -41,7 +41,7 @@ new SimGroup(MissionGroup) {
enabled = "1";
ReflectionMode = "Baked Cubemap";
StaticCubemap = "sky_day_hdr_cubemap";
position = "0 0 -0.0560153";
position = "0 0.704113 16.1515";
rotation = "1 0 0 0";
canSave = "1";
canSaveDynamicFields = "1";
@ -81,7 +81,7 @@ new SimGroup(MissionGroup) {
squareSize = "128";
scaleU = "25";
scaleV = "25";
Material = "Grid512_Grey_Mat";
Material = "Floor_Material";
canSave = "1";
canSaveDynamicFields = "1";
enabled = "1";
@ -130,32 +130,13 @@ new SimGroup(MissionGroup) {
refOffset = "0 0 0";
refScale = "10 10 10";
ReflectionMode = "Baked Cubemap";
position = "0.130544 0.492826 4.70918";
position = "0.130544 0.239855 4.8594";
rotation = "1 0 0 0";
scale = "10 10 10";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "8072e1be-2846-11e7-9f56-abd46b190c60";
};
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";
attenuation = "0";
};
new ConvexShape() {
Material = "Grid512_Orange_Mat";
@ -324,114 +305,18 @@ new SimGroup(MissionGroup) {
canSave = "1";
canSaveDynamicFields = "1";
};
new SphereEnvironmentProbe() {
new BoxEnvironmentProbe() {
enabled = "1";
radius = "5";
refOffset = "0 0 0";
refScale = "10 10 10";
ReflectionMode = "Baked Cubemap";
StaticCubemap = "HdrSkyCubemap";
position = "-25.5075 8.33063 1.52035";
position = "-22.7696 0.224002 4.70918";
rotation = "1 0 0 0";
scale = "10 10 10";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "c4bc9059-3cb4-11e9-933c-d270d89e32b9";
};
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";
persistentId = "d84cbe5b-4f76-11e9-977c-a561a736e3eb";
attenuation = "0";
};
};
//--- OBJECT WRITE END ---

View file

@ -76,11 +76,10 @@ float getDistBoxToPoint(float3 pt, float3 extents)
float defineBoxSpaceInfluence(Surface surface, ProbeData probe, float3 wsEyeRay)
{
float3 surfPosLS = mul(probe.worldToLocal, float4(surface.P, 1.0)).xyz;
float probeattenuationvalue = 0.5; // feed meh
float atten = 1.0 - probeattenuationvalue;
float atten = 1.0-probe.attenuation;
float baseVal = 0.25;
float dist = getDistBoxToPoint(surfPosLS, float3(baseVal, baseVal, baseVal));
return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist));
float dist = getDistBoxToPoint(surfPosLS,float3(baseVal,baseVal,baseVal));
return saturate(smoothstep(baseVal+0.0001,atten*baseVal,dist));
}
// Box Projected IBL Lighting
@ -106,10 +105,7 @@ float3 iblBoxDiffuse(Surface surface, ProbeData probe)
float3 dir = boxProject(surface, probe);
float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, probe.cubemapIdx, 0).xyz;
if (probe.contribution>0)
return color*probe.contribution;
else
return float3(0, 0, 0);
return color;
}
float3 iblBoxSpecular(Surface surface, ProbeData probe)
@ -127,22 +123,16 @@ float3 iblBoxSpecular(Surface surface, ProbeData probe)
#endif
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;
}
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
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;
#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;
}
@ -223,24 +212,24 @@ float4 main(PFXVertToPix IN) : SV_TARGET
}
// 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++)
{
if (probehits>1.0)
{
blendFactor[i] = ((probes[i].contribution / blendSum)) / (probehits - 1);
blendFactor[i] *= ((probes[i].contribution) / invBlendSum);
blendFacSum += blendFactor[i];
}
else
{
blendFactor[i] = probes[i].contribution;
blendFacSum = probes[i].contribution;
}
}
// 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++)
{
if (probehits>1.0)
{
blendFactor[i] = ((probes[i].contribution / blendSum)) / (probehits - 1);
blendFactor[i] *= ((probes[i].contribution) / invBlendSum);
blendFacSum += blendFactor[i];
}
else
{
blendFactor[i] = probes[i].contribution;
blendFacSum = probes[i].contribution;
}
}
// Normalize blendVal
@ -251,28 +240,25 @@ float4 main(PFXVertToPix IN) : SV_TARGET
}
#endif
//use probehits for sharp cuts when singular,
//blendSum when wanting blend on all edging
if (blendSum>1.0)
{
float invBlendSumWeighted = 1.0f / blendFacSum;
for (i = 0; i < numProbes; ++i)
{
blendFactor[i] *= invBlendSumWeighted;
probes[i].contribution = blendFactor[i];
if (probehits>1.0)
{
float invBlendSumWeighted = 1.0f / blendFacSum;
for (i = 0; i < numProbes; ++i)
{
blendFactor[i] *= invBlendSumWeighted;
probes[i].contribution = saturate(blendFactor[i]);
alpha -= probes[i].contribution;
}
}
alpha -= probes[i].contribution;
}
}
#if DEBUGVIZ_ATTENUATION == 1
/*float attenVis = 0;
for (i = 0; i < numProbes; ++i)
{
attenVis += probes[i].contribution;
}
return float4(attenVis, attenVis, attenVis, 1);*/
return float4(alpha, alpha, alpha, 1);
float attenVis = 0;
for (i = 0; i < numProbes; ++i)
{
attenVis += probes[i].contribution;
}
return float4(attenVis, attenVis, attenVis, 1);
#endif
#if DEBUGVIZ_CONTRIB == 1
@ -290,34 +276,6 @@ float4 main(PFXVertToPix IN) : SV_TARGET
#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
float3 irradiance = float3(0, 0, 0);
@ -336,15 +294,21 @@ float4 main(PFXVertToPix IN) : SV_TARGET
if (probes[i].type == 2) //skip skylight
continue;
irradiance += iblBoxDiffuse(surface, probes[i]);
specular += F*iblBoxSpecular(surface, probes[i]);
contrib += probes[i].contribution;
irradiance += iblBoxDiffuse(surface, probes[i])*probes[i].contribution;
specular += F*iblBoxSpecular(surface, probes[i])*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
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;