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 903efc7cfd
7 changed files with 140 additions and 259 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

@ -78,8 +78,8 @@ 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 atten = 1.0-probe.attenuation; float atten = 1.0-probe.attenuation;
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
@ -105,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;
else
return float3(0, 0, 0);
} }
float3 iblBoxSpecular(Surface surface, ProbeData probe) float3 iblBoxSpecular(Surface surface, ProbeData probe)
@ -126,21 +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;
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; 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;
@ -152,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;
} }
@ -221,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
@ -249,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
@ -288,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);
@ -334,11 +294,17 @@ 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;
@ -381,4 +347,4 @@ float4 main(PFXVertToPix IN) : SV_TARGET
return float4(cubeColor, 1); return float4(cubeColor, 1);
#endif #endif
} }