Merge branch 'PBR_ProbeArrayWIP' of https://github.com/Areloch/Torque3D into PBR_ProbeArrayWIP

# Conflicts:
#	Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl
This commit is contained in:
Azaezel 2019-03-26 01:06:59 -05:00
commit 255242db41
7 changed files with 140 additions and 259 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

@ -78,8 +78,8 @@ float defineBoxSpaceInfluence(Surface surface, ProbeData probe, float3 wsEyeRay)
float3 surfPosLS = mul(probe.worldToLocal, float4(surface.P, 1.0)).xyz;
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
@ -105,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;
else
return float3(0, 0, 0);
return color;
}
float3 iblBoxSpecular(Surface surface, ProbeData probe)
@ -126,21 +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;
else
return float3(0, 0, 0);
}
float3 iblSkylightDiffuse(Surface surface, ProbeData probe)
{
float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.R, probe.probeIdx, 0).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;
@ -152,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;
}
@ -221,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
@ -249,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
@ -288,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);
@ -334,11 +294,17 @@ 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;
@ -381,4 +347,4 @@ float4 main(PFXVertToPix IN) : SV_TARGET
return float4(cubeColor, 1);
#endif
}
}