diff --git a/Engine/source/T3D/fx/precipitation.cpp b/Engine/source/T3D/fx/precipitation.cpp index 11b9f4b67..471c31734 100644 --- a/Engine/source/T3D/fx/precipitation.cpp +++ b/Engine/source/T3D/fx/precipitation.cpp @@ -786,7 +786,6 @@ void Precipitation::unpackUpdate(NetConnection* con, BitStream* stream) mUseWind = stream->readFlag(); mFollowCam = stream->readFlag(); mAnimateSplashes = stream->readFlag(); - mDropHitMask = dropHitMask | ( mDropHitPlayers ? PlayerObjectType : 0 ) | ( mDropHitVehicles ? VehicleObjectType : 0 ); diff --git a/Engine/source/T3D/levelInfo.cpp b/Engine/source/T3D/levelInfo.cpp index 8edb6993f..d2f1c53f7 100644 --- a/Engine/source/T3D/levelInfo.cpp +++ b/Engine/source/T3D/levelInfo.cpp @@ -37,6 +37,8 @@ #include "torqueConfig.h" #include "T3D/accumulationVolume.h" +#include "console/typeValidators.h" +#include "materials/materialManager.h" IMPLEMENT_CO_NETOBJECT_V1(LevelInfo); @@ -88,7 +90,8 @@ LevelInfo::LevelInfo() mAmbientLightBlendPhase( 1.f ), mSoundAmbience( NULL ), mSoundDistanceModel( SFXDistanceModelLinear ), - mSoundscape( NULL ) + mSoundscape( NULL ), + mDampness(0.0) { mFogData.density = 0.0f; mFogData.densityOffset = 0.0f; @@ -120,6 +123,8 @@ LevelInfo::~LevelInfo() //----------------------------------------------------------------------------- +FRangeValidator ValiDampnessRange(0.0f, 1.0f); + void LevelInfo::initPersistFields() { addGroup( "Visibility" ); @@ -130,6 +135,8 @@ void LevelInfo::initPersistFields() addField( "decalBias", TypeF32, Offset( mDecalBias, LevelInfo ), "NearPlane bias used when rendering Decal and DecalRoad. This should be tuned to the visibleDistance in your level." ); + addFieldV("dampness", TypeF32, Offset(mDampness, LevelInfo), &ValiDampnessRange, + "@brief dampness influence"); endGroup( "Visibility" ); addGroup( "Fog" ); @@ -199,6 +206,7 @@ U32 LevelInfo::packUpdate(NetConnection *conn, U32 mask, BitStream *stream) stream->write( mNearClip ); stream->write( mVisibleDistance ); stream->write( mDecalBias ); + stream->write(mDampness); stream->write( mFogData.density ); stream->write( mFogData.densityOffset ); @@ -229,6 +237,8 @@ void LevelInfo::unpackUpdate(NetConnection *conn, BitStream *stream) stream->read( &mNearClip ); stream->read( &mVisibleDistance ); stream->read( &mDecalBias ); + stream->read(&mDampness); + MATMGR->setDampness(mDampness); stream->read( &mFogData.density ); stream->read( &mFogData.densityOffset ); diff --git a/Engine/source/T3D/levelInfo.h b/Engine/source/T3D/levelInfo.h index 122d7ad8d..542c0d82e 100644 --- a/Engine/source/T3D/levelInfo.h +++ b/Engine/source/T3D/levelInfo.h @@ -92,6 +92,8 @@ class LevelInfo : public NetObject /// SFXSoundscape* mSoundscape; + + F32 mDampness; ///writeFlag(mEnabled); } + stream->writeFlag(mCanDamp); return retMask; } @@ -491,6 +494,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) mDirty = true; } + mCanDamp = stream->readFlag(); } //----------------------------------------------------------------------------- @@ -555,7 +559,8 @@ void ReflectionProbe::updateProbeParams() mProbeInfo.mProbeRefOffset = mProbeRefOffset; mProbeInfo.mProbeRefScale = mProbeRefScale; - + mProbeInfo.mCanDamp = mCanDamp; + mProbeInfo.mDirty = true; if (mCubemapDirty) diff --git a/Engine/source/T3D/lighting/reflectionProbe.h b/Engine/source/T3D/lighting/reflectionProbe.h index af6947338..75570ce52 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.h +++ b/Engine/source/T3D/lighting/reflectionProbe.h @@ -109,7 +109,7 @@ public: }; ProbeShapeType mProbeShapeType; - + bool mCanDamp; public: ProbeInfo() : mScore(0) {} @@ -255,7 +255,7 @@ protected: bool mResourcesCreated; U32 mCaptureMask; - + bool mCanDamp; public: ReflectionProbe(); virtual ~ReflectionProbe(); diff --git a/Engine/source/T3D/lighting/skylight.cpp b/Engine/source/T3D/lighting/skylight.cpp index 09d813050..880c22681 100644 --- a/Engine/source/T3D/lighting/skylight.cpp +++ b/Engine/source/T3D/lighting/skylight.cpp @@ -78,6 +78,7 @@ ConsoleDocClass(Skylight, Skylight::Skylight() : ReflectionProbe() { mCaptureMask = SKYLIGHT_CAPTURE_TYPEMASK; + mCanDamp = true; } Skylight::~Skylight() diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index 13865489a..1203daf3f 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -47,6 +47,7 @@ String GFXTextureManager::smMissingTexturePath(Con::getVariable("$Core::MissingT String GFXTextureManager::smUnavailableTexturePath(Con::getVariable("$Core::UnAvailableTexturePath")); String GFXTextureManager::smWarningTexturePath(Con::getVariable("$Core::WarningTexturePath")); String GFXTextureManager::smBRDFTexturePath(Con::getVariable("$Core::BRDFTexture")); +String GFXTextureManager::smWetnessTexturePath(Con::getVariable("$Core::WetnessTexture")); GFXTextureManager::EventSignal GFXTextureManager::smEventSignal; @@ -74,7 +75,11 @@ void GFXTextureManager::init() "@ingroup GFX\n" ); Con::addVariable("$Core::BRDFTexture", TypeRealString, &smBRDFTexturePath, - "The file path of the texture used as the default irradiance cubemap for PBR.\n" + "The file path of the texture used as the default BRDF lut for PBR.\n" + "@ingroup GFX\n"); + + Con::addVariable("$Core::WetnessTexture", TypeRealString, &smWetnessTexturePath, + "The file path of the texture used as the default wetness influence map for PBR.\n" "@ingroup GFX\n"); } diff --git a/Engine/source/gfx/gfxTextureManager.h b/Engine/source/gfx/gfxTextureManager.h index 90a8a4bc6..bf92a62ca 100644 --- a/Engine/source/gfx/gfxTextureManager.h +++ b/Engine/source/gfx/gfxTextureManager.h @@ -76,6 +76,7 @@ public: static const String& getWarningTexturePath() { return smWarningTexturePath; } static const String& getBRDFTexturePath() { return smBRDFTexturePath; } + static const String& getWetnessTexturePath() { return smWetnessTexturePath; } /// Update width and height based on available resources. /// @@ -215,7 +216,8 @@ protected: static String smWarningTexturePath; static String smBRDFTexturePath; - + static String smWetnessTexturePath; + GFXTextureObject *mListHead; GFXTextureObject *mListTail; diff --git a/Engine/source/materials/materialManager.cpp b/Engine/source/materials/materialManager.cpp index e0496e2d2..6922e946d 100644 --- a/Engine/source/materials/materialManager.cpp +++ b/Engine/source/materials/materialManager.cpp @@ -58,7 +58,8 @@ MaterialManager::MaterialManager() mDt = 0.0f; mAccumTime = 0.0f; - mLastTime = 0; + mLastTime = 0; + mDampness = 0.0f; mWarningInst = NULL; GFXDevice::getDeviceEventSignal().notify( this, &MaterialManager::_handleGFXEvent ); diff --git a/Engine/source/materials/materialManager.h b/Engine/source/materials/materialManager.h index 570830d5a..6f1889c26 100644 --- a/Engine/source/materials/materialManager.h +++ b/Engine/source/materials/materialManager.h @@ -105,7 +105,10 @@ public: F32 getTotalTime() const { return mAccumTime; } F32 getDeltaTime() const { return mDt; } U32 getLastUpdateTime() const { return mLastTime; } - + + F32 getDampness() const { return mDampness; } + F32 getDampnessClamped() const { return mClampF(mDampness, 0.0, 1.0); } + void setDampness(F32 dampness) { mDampness = dampness; } /// Signal used to notify systems that /// procedural shaders have been flushed. typedef Signal FlushSignal; @@ -163,6 +166,7 @@ protected: F32 mDt; F32 mAccumTime; U32 mLastTime; + F32 mDampness; BaseMatInstance* mWarningInst; diff --git a/Engine/source/materials/processedCustomMaterial.cpp b/Engine/source/materials/processedCustomMaterial.cpp index e347c088f..e2657b349 100644 --- a/Engine/source/materials/processedCustomMaterial.cpp +++ b/Engine/source/materials/processedCustomMaterial.cpp @@ -319,8 +319,9 @@ bool ProcessedCustomMaterial::setupPass( SceneRenderState *state, const SceneDat if (pm) pm->setProbeInfo(this, NULL, sgData, state, pass, shaderConsts); - shaderConsts->setSafe(rpd->shaderHandles.mAccumTimeSC, MATMGR->getTotalTime()); - + shaderConsts->setSafe(rpd->shaderHandles.mAccumTimeSC, MATMGR->getTotalTime()); + shaderConsts->setSafe(rpd->shaderHandles.mDampnessSC, MATMGR->getDampnessClamped()); + return true; } diff --git a/Engine/source/materials/processedShaderMaterial.cpp b/Engine/source/materials/processedShaderMaterial.cpp index ff8053e5f..397028594 100644 --- a/Engine/source/materials/processedShaderMaterial.cpp +++ b/Engine/source/materials/processedShaderMaterial.cpp @@ -94,6 +94,7 @@ void ShaderConstHandles::init( GFXShader *shader, CustomMaterial* mat /*=NULL*/) mEyeMatSC = shader->getShaderConstHandle(ShaderGenVars::eyeMat); mOneOverFarplane = shader->getShaderConstHandle(ShaderGenVars::oneOverFarplane); mAccumTimeSC = shader->getShaderConstHandle(ShaderGenVars::accumTime); + mDampnessSC = shader->getShaderConstHandle(ShaderGenVars::dampness); mMinnaertConstantSC = shader->getShaderConstHandle(ShaderGenVars::minnaertConstant); mSubSurfaceParamsSC = shader->getShaderConstHandle(ShaderGenVars::subSurfaceParams); mDiffuseAtlasParamsSC = shader->getShaderConstHandle(ShaderGenVars::diffuseAtlasParams); @@ -1097,6 +1098,7 @@ void ProcessedShaderMaterial::_setShaderConstants(SceneRenderState * state, cons shaderConsts->setSafe( handles->mAccumTimeSC, MATMGR->getTotalTime() ); + shaderConsts->setSafe(handles->mDampnessSC, MATMGR->getDampnessClamped()); // If the shader constants have not been lost then // they contain the content from a previous render pass. // diff --git a/Engine/source/materials/processedShaderMaterial.h b/Engine/source/materials/processedShaderMaterial.h index cc50b0cfc..e5edc7a7d 100644 --- a/Engine/source/materials/processedShaderMaterial.h +++ b/Engine/source/materials/processedShaderMaterial.h @@ -81,6 +81,7 @@ public: GFXShaderConstHandle* mEyeMatSC; GFXShaderConstHandle* mOneOverFarplane; GFXShaderConstHandle* mAccumTimeSC; + GFXShaderConstHandle* mDampnessSC; GFXShaderConstHandle* mMinnaertConstantSC; GFXShaderConstHandle* mSubSurfaceParamsSC; GFXShaderConstHandle* mDiffuseAtlasParamsSC; diff --git a/Engine/source/materials/shaderData.h b/Engine/source/materials/shaderData.h index 0fb1286bc..4bef16679 100644 --- a/Engine/source/materials/shaderData.h +++ b/Engine/source/materials/shaderData.h @@ -93,7 +93,7 @@ protected: enum { - NumTextures = 8 + NumTextures = 16 }; String mSamplerNames[NumTextures]; @@ -134,4 +134,4 @@ public: DECLARE_CONOBJECT(ShaderData); }; -#endif // _SHADERTDATA_H_ \ No newline at end of file +#endif // _SHADERTDATA_H_ diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index 55c638c94..84d283bda 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -492,6 +492,7 @@ PostEffect::PostEffect() mLightDirectionSC( NULL ), mCameraForwardSC( NULL ), mAccumTimeSC( NULL ), + mDampnessSC(NULL), mDeltaTimeSC( NULL ), mInvCameraMatSC( NULL ), mMatCameraToWorldSC( NULL), @@ -785,6 +786,8 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) mCameraForwardSC = mShader->getShaderConstHandle( "$camForward" ); mAccumTimeSC = mShader->getShaderConstHandle( "$accumTime" ); + mDampnessSC = mShader->getShaderConstHandle("$dampness"); + mDeltaTimeSC = mShader->getShaderConstHandle( "$deltaTime" ); mInvCameraMatSC = mShader->getShaderConstHandle( "$invCameraMat" ); @@ -965,7 +968,8 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) } mShaderConsts->setSafe( mAccumTimeSC, MATMGR->getTotalTime() ); mShaderConsts->setSafe( mDeltaTimeSC, MATMGR->getDeltaTime() ); - + mShaderConsts->setSafe(mDampnessSC, MATMGR->getDampnessClamped()); + // Now set all the constants that are dependent on the scene state. if ( state ) { diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index 22e4b6c94..5a2e6b6ae 100644 --- a/Engine/source/postFx/postEffect.h +++ b/Engine/source/postFx/postEffect.h @@ -85,7 +85,7 @@ public: enum { - NumTextures = 8, + NumTextures = 16, }; protected: @@ -156,6 +156,7 @@ protected: GFXShaderConstHandle *mLightDirectionSC; GFXShaderConstHandle *mCameraForwardSC; GFXShaderConstHandle *mAccumTimeSC; + GFXShaderConstHandle* mDampnessSC; GFXShaderConstHandle *mDeltaTimeSC; GFXShaderConstHandle *mInvCameraMatSC; GFXShaderConstHandle *mMatCameraToWorldSC; diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 18a375a64..8a85f8261 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -98,7 +98,9 @@ ProbeShaderConstants::ProbeShaderConstants() mProbeIrradianceCubemapArraySC(NULL), mProbeCountSC(NULL), mBRDFTextureMap(NULL), + mWetnessTextureMap(NULL), mSkylightCubemapIdxSC(NULL), + mSkylightDampSC(NULL), mWorldToObjArraySC(NULL), mMaxProbeDrawDistanceSC(NULL) { @@ -135,8 +137,10 @@ void ProbeShaderConstants::init(GFXShader* shader) mProbeCountSC = shader->getShaderConstHandle(ShaderGenVars::probeCount); mBRDFTextureMap = shader->getShaderConstHandle(ShaderGenVars::BRDFTextureMap); + mWetnessTextureMap = shader->getShaderConstHandle(ShaderGenVars::WetnessTextureMap); - mSkylightCubemapIdxSC = shader->getShaderConstHandle(ShaderGenVars::skylightCubemapIdx); + mSkylightCubemapIdxSC = shader->getShaderConstHandle(ShaderGenVars::skylightCubemapIdx); + mSkylightDampSC = shader->getShaderConstHandle(ShaderGenVars::skylightDamp); mMaxProbeDrawDistanceSC = shader->getShaderConstHandle(ShaderGenVars::maxProbeDrawDistance); @@ -145,10 +149,10 @@ void ProbeShaderConstants::init(GFXShader* shader) bool ProbeShaderConstants::isValid() { - if (mProbePositionArraySC->isValid() || - mProbeConfigDataArraySC->isValid() || - mRefScaleArraySC->isValid() || - mProbeSpecularCubemapArraySC->isValid() || + if (mProbePositionArraySC->isValid() && + mProbeConfigDataArraySC->isValid() && + mRefScaleArraySC->isValid() && + mProbeSpecularCubemapArraySC->isValid() && mProbeIrradianceCubemapArraySC->isValid()) return true; @@ -169,6 +173,7 @@ RenderProbeMgr::RenderProbeMgr() mLastConstants(nullptr), mHasSkylight(false), mSkylightCubemapIdx(-1), + mSkylightDamp(true), mCubeMapCount(0), mUseHDRCaptures(true) { @@ -197,6 +202,7 @@ RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 proce mEffectiveProbeCount = 0; mHasSkylight = false; mSkylightCubemapIdx = -1; + mSkylightDamp = true; mLastConstants = nullptr; mMipCount = 0; mUseHDRCaptures = true; @@ -236,6 +242,12 @@ bool RenderProbeMgr::onAdd() return false; } + String wetnessTexturePath = GFXTextureManager::getWetnessTexturePath(); + if (!mWetnessTexture.set(wetnessTexturePath, &GFXTexturePersistentProfile, "WetnessTexture")) + { + Con::errorf("RenderProbeMgr::onAdd: Failed to load Wetness Texture"); + return false; + } return true; } @@ -306,6 +318,7 @@ void RenderProbeMgr::getBestProbes(const Point3F& objPosition, ProbeDataSet* pro else { probeDataSet->skyLightIdx = curEntry.mCubemapIndex; + probeDataSet->skyLightDamp = curEntry.mProbeInfo->mCanDamp; mHasSkylight = true; } } @@ -330,13 +343,13 @@ void RenderProbeMgr::getBestProbes(const Point3F& objPosition, ProbeDataSet* pro probeDataSet->probeWorldToObjArray[i] = p2A; p2A.inverse(); probeDataSet->refScaleArray[i] = curEntry.mProbeInfo->mProbeRefScale / (p2A.getScale()*2); + probeDataSet->refScaleArray[i].w = curEntry.mProbeInfo->mCanDamp? 1.0 : 0.0; Point3F probePos = curEntry.mProbeInfo->mObject->getPosition(); Point3F refPos = probePos + curEntry.mProbeInfo->mProbeRefOffset * probeDataSet->refScaleArray[i].asPoint3F(); probeDataSet->probePositionArray[i] = Point4F(probePos.x, probePos.y, probePos.z, 0); probeDataSet->probeRefPositionArray[i] = Point4F(refPos.x, refPos.y, refPos.z, 0); - } } @@ -422,7 +435,7 @@ PostEffect* RenderProbeMgr::getProbeArrayEffect() mProbeArrayEffect->setShaderConst("$numProbes", (S32)0); mProbeArrayEffect->setShaderConst("$skylightCubemapIdx", (S32)-1); - + mProbeArrayEffect->setShaderConst(ShaderGenVars::skylightDamp, (S32)true); mProbeArrayEffect->setShaderConst("$cubeMips", (float)0); mProbeArrayEffect->setShaderConst("$maxProbeDrawDistance", smMaxProbeDrawDistance); @@ -784,10 +797,14 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData& sgData, shaderConsts->setSafe(probeShaderConsts->mProbeConfigDataArraySC, probeConfigAlignedArray); } - if (probeShaderConsts->mBRDFTextureMap->getSamplerRegister() != -1 && mBRDFTexture.isValid()) + if (mBRDFTexture.isValid(), probeShaderConsts->mBRDFTextureMap->getSamplerRegister() != -1) GFX->setTexture(probeShaderConsts->mBRDFTextureMap->getSamplerRegister(), mBRDFTexture); + if (mWetnessTexture.isValid() && probeShaderConsts->mWetnessTextureMap->getSamplerRegister() != -1) + GFX->setTexture(probeShaderConsts->mWetnessTextureMap->getSamplerRegister(), mWetnessTexture); + shaderConsts->setSafe(probeShaderConsts->mSkylightCubemapIdxSC, (float)probeSet.skyLightIdx); + shaderConsts->setSafe(probeShaderConsts->mSkylightDampSC, (int)probeSet.skyLightDamp); if (probeShaderConsts->mProbeSpecularCubemapArraySC->getSamplerRegister() != -1) GFX->setCubeArrayTexture(probeShaderConsts->mProbeSpecularCubemapArraySC->getSamplerRegister(), mPrefilterArray); @@ -859,6 +876,11 @@ void RenderProbeMgr::render( SceneRenderState *state ) String probeCapturing = Con::getVariable("$Probes::Capturing", "0"); mProbeArrayEffect->setShaderMacro("CAPTURING", probeCapturing); + + mProbeArrayEffect->setTexture(3, mBRDFTexture); + mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray); + mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray); + mProbeArrayEffect->setTexture(6, mWetnessTexture); //ssao mask if (AdvancedLightBinManager::smUseSSAOMask) { @@ -868,20 +890,16 @@ void RenderProbeMgr::render( SceneRenderState *state ) if (pTexObj) { mProbeArrayEffect->setShaderMacro("USE_SSAO_MASK"); - mProbeArrayEffect->setTexture(6, pTexObj); + mProbeArrayEffect->setTexture(7, pTexObj); } } else { - mProbeArrayEffect->setTexture(6, GFXTexHandle(NULL)); + mProbeArrayEffect->setTexture(7, GFXTexHandle(NULL)); } - - mProbeArrayEffect->setTexture(3, mBRDFTexture); - mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray); - mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray); - mProbeArrayEffect->setShaderConst("$numProbes", (S32)mProbeData.effectiveProbeCount); mProbeArrayEffect->setShaderConst("$skylightCubemapIdx", (S32)mProbeData.skyLightIdx); + mProbeArrayEffect->setShaderConst(ShaderGenVars::skylightDamp, mProbeData.skyLightDamp); mProbeArrayEffect->setShaderConst("$cubeMips", (float)mPrefilterArray->getMipMapLevels()); diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index 0d26bd047..4f64eaf95 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -98,8 +98,9 @@ struct ProbeShaderConstants GFXShaderConstHandle *mProbeCountSC; GFXShaderConstHandle *mBRDFTextureMap; - + GFXShaderConstHandle* mWetnessTextureMap; GFXShaderConstHandle *mSkylightCubemapIdxSC; + GFXShaderConstHandle* mSkylightDampSC; GFXShaderConstHandle* mMaxProbeDrawDistanceSC; @@ -127,9 +128,8 @@ struct ProbeDataSet Vector probeConfigArray; Vector probeWorldToObjArray; - S32 skyLightIdx; - + bool skyLightDamp; U32 effectiveProbeCount; U32 maxProbeCount; @@ -141,10 +141,10 @@ struct ProbeDataSet probeConfigArray.setSize(0); probeWorldToObjArray.setSize(0); - skyLightIdx = -1; effectiveProbeCount = 0; maxProbeCount = 0; + skyLightDamp = true; } ProbeDataSet(U32 _maxProbeCount) @@ -212,7 +212,7 @@ private: /// If we have a skylight, what's the array pair index for it? /// S32 mSkylightCubemapIdx; - + bool mSkylightDamp; /// /// The 'effective' probe count. This tracks the number of probes that are actually going to be rendered /// @@ -279,7 +279,8 @@ private: /// The BRDF texture used in PBR math calculations /// GFXTexHandle mBRDFTexture; - + GFXTexHandle mWetnessTexture; + /// /// Processed best probe selection list of the current frame when rendering in deferred mode. /// diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp index 213cc3726..d044fbad3 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp @@ -2982,6 +2982,10 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList skylightCubemapIdx->uniform = true; skylightCubemapIdx->constSortPos = cspPotentialPrimitive; + Var* SkylightDamp = new Var("SkylightDamp", "int"); + SkylightDamp->uniform = true; + SkylightDamp->constSortPos = cspPotentialPrimitive; + Var * inProbePosArray = new Var("inProbePosArray", "vec4"); inProbePosArray->arraySize = MAX_FORWARD_PROBES; inProbePosArray->uniform = true; @@ -3025,6 +3029,14 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList irradianceCubemapAR->sampler = true; irradianceCubemapAR->constNum = Var::getTexUnitNum(); + // create texture var + Var* WetnessTexture = new Var; + WetnessTexture->setType("sampler2D"); + WetnessTexture->setName("WetnessTexture"); + WetnessTexture->uniform = true; + WetnessTexture->sampler = true; + WetnessTexture->constNum = Var::getTexUnitNum(); // used as texture unit num here + Var* surface = getSurface(componentList, meta, fd); if (!surface) @@ -3051,14 +3063,29 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList eyePos->uniform = true; eyePos->constSortPos = cspPass; } - + + Var* accumTime = (Var*)LangElement::find("accumTime"); + if (!accumTime) + { + accumTime = new Var("accumTime", "float"); + accumTime->uniform = true; + accumTime->constSortPos = cspPass; + } + Var* dampness = (Var*)LangElement::find("dampness"); + if (!dampness) + { + dampness = new Var("dampness", "float"); + dampness->uniform = true; + dampness->constSortPos = cspPass; + } + //Reflection vec String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t"); - computeForwardProbes += String("@,@,\r\n\t\t"); + computeForwardProbes += String("@,@,@,@,@,@,\r\n\t\t"); computeForwardProbes += String("@,@).rgb; \r\n"); meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos, - skylightCubemapIdx, BRDFTexture, + skylightCubemapIdx, SkylightDamp, BRDFTexture, WetnessTexture, accumTime, dampness, irradianceCubemapAR, specularCubemapAR)); Var *ambient = (Var *)LangElement::find("ambient"); @@ -3078,8 +3105,8 @@ ShaderFeature::Resources ReflectionProbeFeatGLSL::getResources(const MaterialFea { Resources res; - res.numTex = 3; - res.numTexReg = 3; + res.numTex = 4; + res.numTexReg = 4; return res; } @@ -3098,5 +3125,7 @@ void ReflectionProbeFeatGLSL::setTexData(Material::StageData& stageDat, passData.mTexType[texIndex++] = Material::SGCube; passData.mSamplerNames[texIndex] = "IrradianceCubemapAR"; passData.mTexType[texIndex++] = Material::SGCube; + passData.mSamplerNames[texIndex] = "WetnessTexture"; + passData.mTexType[texIndex++] = Material::Standard; } } diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index 28f0d7ee2..40b2b4a47 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp @@ -3060,6 +3060,10 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList skylightCubemapIdx->uniform = true; skylightCubemapIdx->constSortPos = cspPotentialPrimitive; + Var* SkylightDamp = new Var("SkylightDamp", "int"); + SkylightDamp->uniform = true; + SkylightDamp->constSortPos = cspPotentialPrimitive; + Var *inProbePosArray = new Var("inProbePosArray", "float4"); inProbePosArray->arraySize = MAX_FORWARD_PROBES; inProbePosArray->uniform = true; @@ -3115,6 +3119,16 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList irradianceCubemapARTex->texture = true; irradianceCubemapARTex->constNum = irradianceCubemapAR->constNum; + Var* WetnessTexture = new Var("WetnessTexture", "SamplerState"); + WetnessTexture->uniform = true; + WetnessTexture->sampler = true; + WetnessTexture->constNum = Var::getTexUnitNum(); // used as texture unit num here + + Var* WetnessTextureTex = new Var("texture_WetnessTexture", "Texture2D"); + WetnessTextureTex->uniform = true; + WetnessTextureTex->texture = true; + WetnessTextureTex->constNum = WetnessTexture->constNum; + Var* surface = getSurface(componentList, meta, fd); if (!surface) @@ -3142,12 +3156,28 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList eyePos->constSortPos = cspPass; } + Var* accumTime = (Var*)LangElement::find("accumTime"); + if (!accumTime) + { + accumTime = new Var("accumTime", "float"); + accumTime->uniform = true; + accumTime->constSortPos = cspPass; + } + + Var* dampness = (Var*)LangElement::find("dampness"); + if (!dampness) + { + dampness = new Var("dampness", "float"); + dampness->uniform = true; + dampness->constSortPos = cspPass; + } + String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t"); - computeForwardProbes += String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t"); + computeForwardProbes += String("@,@,TORQUE_SAMPLER2D_MAKEARG(@),TORQUE_SAMPLER2D_MAKEARG(@), @, @,\r\n\t\t"); computeForwardProbes += String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@)).rgb; \r\n"); meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos, - skylightCubemapIdx, BRDFTexture, + skylightCubemapIdx, SkylightDamp, BRDFTexture, WetnessTexture, accumTime, dampness, irradianceCubemapAR, specularCubemapAR)); Var *ambient = (Var *)LangElement::find("ambient"); @@ -3167,8 +3197,8 @@ ShaderFeature::Resources ReflectionProbeFeatHLSL::getResources(const MaterialFea { Resources res; - res.numTex = 3; - res.numTexReg = 3; + res.numTex = 4; + res.numTexReg = 4; return res; } @@ -3187,5 +3217,7 @@ void ReflectionProbeFeatHLSL::setTexData(Material::StageData &stageDat, passData.mTexType[texIndex++] = Material::SGCube; passData.mSamplerNames[texIndex] = "IrradianceCubemapAR"; passData.mTexType[texIndex++] = Material::SGCube; + passData.mSamplerNames[texIndex] = "WetnessTexture"; + passData.mTexType[texIndex++] = Material::Standard; } } diff --git a/Engine/source/shaderGen/shaderGenVars.cpp b/Engine/source/shaderGen/shaderGenVars.cpp index e7e7296c1..b1fa02347 100644 --- a/Engine/source/shaderGen/shaderGenVars.cpp +++ b/Engine/source/shaderGen/shaderGenVars.cpp @@ -50,6 +50,7 @@ const String ShaderGenVars::colorMultiply("$colorMultiply"); const String ShaderGenVars::alphaTestValue("$alphaTestValue"); const String ShaderGenVars::texMat("$texMat"); const String ShaderGenVars::accumTime("$accumTime"); +const String ShaderGenVars::dampness("$dampness"); const String ShaderGenVars::minnaertConstant("$minnaertConstant"); const String ShaderGenVars::subSurfaceParams("$subSurfaceParams"); @@ -90,11 +91,13 @@ const String ShaderGenVars::irradianceCubemapAR("$IrradianceCubemapAR"); const String ShaderGenVars::probeCount("$inNumProbes"); const String ShaderGenVars::BRDFTextureMap("$BRDFTexture"); +const String ShaderGenVars::WetnessTextureMap("$WetnessTexture"); const String ShaderGenVars::maxProbeDrawDistance("$maxProbeDrawDistance"); //Skylight const String ShaderGenVars::skylightCubemapIdx("$inSkylightCubemapIdx"); +const String ShaderGenVars::skylightDamp("$SkylightDamp"); // These are ignored by the D3D layers. const String ShaderGenVars::fogMap("$fogMap"); diff --git a/Engine/source/shaderGen/shaderGenVars.h b/Engine/source/shaderGen/shaderGenVars.h index c32d97c94..a4e87338c 100644 --- a/Engine/source/shaderGen/shaderGenVars.h +++ b/Engine/source/shaderGen/shaderGenVars.h @@ -59,6 +59,7 @@ struct ShaderGenVars const static String alphaTestValue; const static String texMat; const static String accumTime; + const static String dampness; const static String minnaertConstant; const static String subSurfaceParams; @@ -101,11 +102,12 @@ struct ShaderGenVars const static String probeCount; const static String BRDFTextureMap; - + const static String WetnessTextureMap; const static String maxProbeDrawDistance; //Skylight const static String skylightCubemapIdx; + const static String skylightDamp; // Textures const static String fogMap; diff --git a/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.tscript b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.tscript index 4f17d4a68..104056efe 100644 --- a/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.tscript +++ b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.tscript @@ -302,7 +302,8 @@ singleton ShaderData( PFX_ReflectionProbeArray ) samplerNames[3] = "$BRDFTexture"; samplerNames[4] = "$specularCubemapAR"; samplerNames[5] = "$irradianceCubemapAR"; - samplerNames[6] = "$ssaoMask"; + samplerNames[6] = "$WetnessTexture"; + samplerNames[7] = "$ssaoMask"; pixVersion = 2.0; }; @@ -331,5 +332,6 @@ singleton GFXStateBlockData( PFX_ReflectionProbeArrayStateBlock ) samplerStates[3] = SamplerClampPoint; samplerStates[4] = SamplerClampLinear; samplerStates[5] = SamplerClampLinear; - samplerStates[6] = SamplerClampPoint; + samplerStates[6] = SamplerWrapPoint; + samplerStates[7] = SamplerClampPoint; }; \ No newline at end of file diff --git a/Templates/BaseGame/game/core/postFX/scripts/ReflectionProbes/reflectionProbeArrayPostFX.tscript b/Templates/BaseGame/game/core/postFX/scripts/ReflectionProbes/reflectionProbeArrayPostFX.tscript index 879ec5774..cb7892b27 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/ReflectionProbes/reflectionProbeArrayPostFX.tscript +++ b/Templates/BaseGame/game/core/postFX/scripts/ReflectionProbes/reflectionProbeArrayPostFX.tscript @@ -15,6 +15,5 @@ singleton PostEffect( reflectionProbeArrayPostFX ) texture[0] = "#deferred"; texture[1] = "#color"; texture[2] = "#matinfo"; - allowReflectPass = true; }; diff --git a/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript b/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript index 955c9d3da..1051ee621 100644 --- a/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript +++ b/Templates/BaseGame/game/core/rendering/Core_Rendering.tscript @@ -5,7 +5,8 @@ function Core_Rendering::onCreate(%this) $Core::UnAvailableTexturePath = "core/rendering/images/unavailable"; $Core::WarningTexturePath = "core/rendering/images/warnMat"; $Core::CommonShaderPath = "core/rendering/shaders"; - $Core::BRDFTexture = "core/rendering/images/brdfTexture.dds"; + $Core::BRDFTexture = "core/rendering/images/brdfTexture.dds"; + $Core::WetnessTexture = "core/rendering/images/wetMap.png"; $Core::NoImageAssetFallback = "Core_Rendering:missingTexture_image"; $Core::NoMaterialAssetFallback = "Core_Rendering:noMaterial"; diff --git a/Templates/BaseGame/game/core/rendering/images/wetMap.png b/Templates/BaseGame/game/core/rendering/images/wetMap.png new file mode 100644 index 000000000..895016a98 Binary files /dev/null and b/Templates/BaseGame/game/core/rendering/images/wetMap.png differ diff --git a/Templates/BaseGame/game/core/rendering/images/wetMap_image.asset.taml b/Templates/BaseGame/game/core/rendering/images/wetMap_image.asset.taml new file mode 100644 index 000000000..ab367bcb8 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/images/wetMap_image.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 5ed56658e..fd159cf4e 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -367,14 +367,36 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refSca return posonbox - refPosition.xyz; } +void dampen(inout Surface surface, sampler2D WetnessTexture, float accumTime, float degree) +{ + if (degree<=0.0) return; + vec3 n = abs(surface.N); + + float grav = 2.0-pow(dot(float3(0,0,-1),surface.N),3); + if (grav<0) grav*=-1.0; + + float speed = accumTime*(1.0-surface.roughness)*grav; + vec2 wetoffset = vec2(speed,speed/2)*0.1; + + float wetness = texture(WetnessTexture, vec2(surface.P.xy*0.2+wetoffset)).b; + wetness = lerp(wetness,texture(WetnessTexture,vec2(surface.P.zx*0.2+wetoffset)).b,n.y); + wetness = lerp(wetness,texture(WetnessTexture,vec2(surface.P.zy*0.2+wetoffset)).b,n.x); + wetness = pow(wetness,3)*degree; + + surface.roughness = lerp(surface.roughness,(1.0-pow(wetness,2))*surface.roughness*0.92f+0.04f,degree); + surface.baseColor.rgb = lerp(surface.baseColor.rgb,surface.baseColor.rgb*(2.0-wetness)/2,degree); + updateSurface(surface); +} + vec4 computeForwardProbes(Surface surface, float cubeMips, int numProbes, mat4x4 inWorldToObjArray[MAX_FORWARD_PROBES], vec4 inProbeConfigData[MAX_FORWARD_PROBES], vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 inRefScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES], - vec3 wsEyePos, float skylightCubemapIdx, sampler2D BRDFTexture, + vec3 wsEyePos, float skylightCubemapIdx, int SkylightDamp, sampler2D BRDFTexture, sampler2D WetnessTexture, float accumTime, float dampness, samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR) { int i = 0; float alpha = 1; + float wetAmmout = 0; float blendFactor[MAX_FORWARD_PROBES]; float blendSum = 0; float blendFacSum = 0; @@ -383,7 +405,7 @@ vec4 computeForwardProbes(Surface surface, //Set up our struct data float contribution[MAX_FORWARD_PROBES]; float blendCap = 0; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribution[i] = 0; float atten = 1.0-(length(wsEyePos-inProbePosArray[i].xyz)/maxProbeDrawDistance); @@ -401,9 +423,15 @@ vec4 computeForwardProbes(Surface surface, else contribution[i] = 0.0; + if (inRefScaleArray[i].w>0) + wetAmmout += contribution[i]; + else + wetAmmout -= contribution[i]; + blendSum += contribution[i]; blendCap = max(contribution[i],blendCap); } + if (wetAmmout<0) wetAmmout =0; if (probehits > 0.0) { @@ -415,7 +443,7 @@ vec4 computeForwardProbes(Surface surface, blendFacSum += blendFactor[i]; //running tally of results } - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { //normalize, but in the range of the highest value applied //to preserve blend vs skylight @@ -425,7 +453,7 @@ vec4 computeForwardProbes(Surface surface, #if (DEBUGVIZ_ATTENUATION == 1) float contribAlpha = 1; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribAlpha -= contribution[i]; } @@ -442,7 +470,7 @@ vec4 computeForwardProbes(Surface surface, vec3 finalContribColor = vec3(0, 0, 0); float contribAlpha = 1; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { finalContribColor += contribution[i] *probeContribColors[i].rgb; contribAlpha -= contribution[i]; @@ -458,10 +486,22 @@ vec4 computeForwardProbes(Surface surface, vec3 irradiance = vec3(0, 0, 0); vec3 specular = vec3(0, 0, 0); + for (i = 0; i < numProbes; i++) + { + float contrib = contribution[i]; + if (contrib > 0.0f) + { + alpha -= contrib; + } + } + if (SkylightDamp>0) + wetAmmout += alpha; + dampen(surface, WetnessTexture, accumTime, wetAmmout*dampness); + // Radiance (Specular) float lod = roughnessToMipLevel(surface.roughness, cubeMips); - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { float contrib = contribution[i]; if (contrib > 0.0f) @@ -471,16 +511,15 @@ vec4 computeForwardProbes(Surface surface, irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib; specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib; - alpha -= contrib; } } - + if(skylightCubemapIdx != -1 && alpha >= 0.001) { irradiance = mix(irradiance,textureLod(irradianceCubemapAR, vec4(surface.R, skylightCubemapIdx), 0).xyz, alpha); specular = mix(specular,textureLod(specularCubemapAR, vec4(surface.R, skylightCubemapIdx), lod).xyz, alpha); } - + //energy conservation vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); vec3 kD = 1.0f - F; @@ -521,7 +560,7 @@ vec4 debugVizForwardProbes(Surface surface, float probehits = 0; //Set up our struct data float contribution[MAX_FORWARD_PROBES]; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribution[i] = 0; @@ -561,7 +600,7 @@ vec4 debugVizForwardProbes(Surface surface, } float invBlendSumWeighted = 1.0f / blendFacSum; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { blendFactor[i] *= invBlendSumWeighted; contribution[i] *= blendFactor[i]; @@ -571,7 +610,7 @@ vec4 debugVizForwardProbes(Surface surface, if(showAtten == 1) { float contribAlpha = 1; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribAlpha -= contribution[i]; } @@ -589,7 +628,7 @@ vec4 debugVizForwardProbes(Surface surface, vec3 finalContribColor = vec3(0, 0, 0); float contribAlpha = 1; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { finalContribColor += contribution[i] *probeContribColors[i].rgb; contribAlpha -= contribution[i]; @@ -613,7 +652,7 @@ vec4 debugVizForwardProbes(Surface surface, lod = 0; } - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { float contrib = contribution[i]; if (contrib > 0.0f) diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index 66f531c83..3ddb51982 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -371,14 +371,36 @@ float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, f return posonbox-refPosition; } +void dampen(inout Surface surface, TORQUE_SAMPLER2D(WetnessTexture), float accumTime, float degree) +{ + if (degree<=0.0) return; + float3 n = abs(surface.N); + + float grav = 2.0-pow(dot(float3(0,0,-1),surface.N),3); + if (grav<0) grav*=-1.0; + + float speed = accumTime*(1.0-surface.roughness)*grav; + float2 wetoffset = float2(speed,speed/2)*0.1; + + float wetness = TORQUE_TEX2D(WetnessTexture, float2(surface.P.xy*0.2+wetoffset)).b; + wetness = lerp(wetness,TORQUE_TEX2D(WetnessTexture,float2(surface.P.zx*0.2+wetoffset)).b,n.y); + wetness = lerp(wetness,TORQUE_TEX2D(WetnessTexture,float2(surface.P.zy*0.2+wetoffset)).b,n.x); + wetness = pow(wetness,3)*degree; + + surface.roughness = lerp(surface.roughness,(1.0-pow(wetness,2))*surface.roughness*0.92f+0.04f,degree); + surface.baseColor.rgb = lerp(surface.baseColor.rgb,surface.baseColor.rgb*(2.0-wetness)/2,degree); + surface.Update(); +} + float4 computeForwardProbes(Surface surface, float cubeMips, int numProbes, float4x4 inWorldToObjArray[MAX_FORWARD_PROBES], float4 inProbeConfigData[MAX_FORWARD_PROBES], float4 inProbePosArray[MAX_FORWARD_PROBES], float4 inRefScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES], - float3 wsEyePos, float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture), + float3 wsEyePos, float skylightCubemapIdx, int SkylightDamp, TORQUE_SAMPLER2D(BRDFTexture), TORQUE_SAMPLER2D(WetnessTexture), float accumTime, float dampness, TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR)) { int i = 0; float alpha = 1; + float wetAmmout = 0; float blendFactor[MAX_FORWARD_PROBES]; float blendSum = 0; float blendFacSum = 0; @@ -389,7 +411,7 @@ float4 computeForwardProbes(Surface surface, float blendCap = 0; //Process prooooobes - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribution[i] = 0.0; float atten = 1.0-(length(wsEyePos-inProbePosArray[i].xyz)/maxProbeDrawDistance); @@ -407,10 +429,16 @@ float4 computeForwardProbes(Surface surface, else contribution[i] = 0.0; + if (inRefScaleArray[i].w>0) + wetAmmout += contribution[i]; + else + wetAmmout -= contribution[i]; + blendSum += contribution[i]; blendCap = max(contribution[i],blendCap); } - + if (wetAmmout<0) wetAmmout =0; + if (probehits > 0.0) { invBlendSum = (probehits - blendSum)/probehits; //grab the remainder @@ -421,7 +449,7 @@ float4 computeForwardProbes(Surface surface, blendFacSum += blendFactor[i]; //running tally of results } - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { //normalize, but in the range of the highest value applied //to preserve blend vs skylight @@ -431,7 +459,7 @@ float4 computeForwardProbes(Surface surface, #if DEBUGVIZ_ATTENUATION == 1 float contribAlpha = 1; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribAlpha -= contribution[i]; } @@ -448,7 +476,7 @@ float4 computeForwardProbes(Surface surface, float3 finalContribColor = float3(0, 0, 0); float contribAlpha = 1; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { finalContribColor += contribution[i] *probeContribColors[i].rgb; contribAlpha -= contribution[i]; @@ -464,10 +492,22 @@ float4 computeForwardProbes(Surface surface, float3 irradiance = float3(0, 0, 0); float3 specular = float3(0, 0, 0); + for (i = 0; i < numProbes; i++) + { + float contrib = contribution[i]; + if (contrib > 0.0f) + { + alpha -= contrib; + } + } + if (SkylightDamp>0) + wetAmmout += alpha; + dampen(surface, TORQUE_SAMPLER2D_MAKEARG(WetnessTexture), accumTime, wetAmmout*dampness); + // Radiance (Specular) float lod = roughnessToMipLevel(surface.roughness, cubeMips); - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { float contrib = contribution[i]; if (contrib > 0.0f) @@ -477,9 +517,9 @@ float4 computeForwardProbes(Surface surface, irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib; specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib; - alpha -= contrib; } } + if(skylightCubemapIdx != -1 && alpha >= 0.001) { @@ -527,7 +567,7 @@ float4 debugVizForwardProbes(Surface surface, float probehits = 0; //Set up our struct data float contribution[MAX_FORWARD_PROBES]; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribution[i] = 0; @@ -567,7 +607,7 @@ float4 debugVizForwardProbes(Surface surface, } float invBlendSumWeighted = 1.0f / blendFacSum; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { blendFactor[i] *= invBlendSumWeighted; contribution[i] *= blendFactor[i]; @@ -577,7 +617,7 @@ float4 debugVizForwardProbes(Surface surface, if(showAtten == 1) { float contribAlpha = 1; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribAlpha -= contribution[i]; } @@ -595,7 +635,7 @@ float4 debugVizForwardProbes(Surface surface, float3 finalContribColor = float3(0, 0, 0); float contribAlpha = 1; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { finalContribColor += contribution[i] *probeContribColors[i].rgb; contribAlpha -= contribution[i]; @@ -619,7 +659,7 @@ float4 debugVizForwardProbes(Surface surface, lod = 0; } - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { float contrib = contribution[i]; if (contrib > 0.0f) diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl index bc9f19fce..fcd3d46df 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl @@ -25,11 +25,13 @@ uniform int numProbes; uniform samplerCubeArray specularCubemapAR; uniform samplerCubeArray irradianceCubemapAR; - +uniform sampler2D WetnessTexture; #ifdef USE_SSAO_MASK uniform sampler2D ssaoMask; -uniform vec4 rtParams6; +uniform vec4 rtParams7; #endif +uniform float accumTime; +uniform float dampness; uniform vec4 probePosArray[MAX_PROBES]; uniform vec4 refPosArray[MAX_PROBES]; @@ -42,6 +44,7 @@ uniform vec4 probeContribColors[MAX_PROBES]; #endif uniform int skylightCubemapIdx; +uniform int SkylightDamp; out vec4 OUT_col; @@ -67,6 +70,7 @@ void main() float alpha = 1; + float wetAmmout = 0; #if SKYLIGHT_ONLY == 0 int i = 0; @@ -82,7 +86,7 @@ void main() if (alpha > 0) { //Process prooooobes - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribution[i] = 0; @@ -96,14 +100,20 @@ void main() contribution[i] = defineSphereSpaceInfluence(surface.P, probePosArray[i].xyz, probeConfigData[i].g)*atten; } - if (contribution[i]>0.0) - probehits++; + if (contribution[i]>0.0) + probehits++; else contribution[i] = 0; + if (refScaleArray[i].w>0) + wetAmmout += contribution[i]; + else + wetAmmout -= contribution[i]; + blendSum += contribution[i]; blendCap = max(contribution[i],blendCap); } + if (wetAmmout<0) wetAmmout =0; if (probehits > 0.0) { @@ -115,7 +125,7 @@ void main() blendFacSum += blendFactor[i]; //running tally of results } - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { //normalize, but in the range of the highest value applied //to preserve blend vs skylight @@ -125,7 +135,7 @@ void main() #if DEBUGVIZ_ATTENUATION == 1 float contribAlpha = 0; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribAlpha += contribution[i]; } @@ -136,7 +146,7 @@ void main() #if DEBUGVIZ_CONTRIB == 1 vec3 finalContribColor = vec3(0, 0, 0); - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { finalContribColor += contribution[i] * vec3(fmod(i+1,2),fmod(i+1,3),fmod(i+1,4)); } @@ -144,11 +154,23 @@ void main() return; #endif } + for (i = 0; i < numProbes; i++) + { + float contrib = contribution[i]; + if (contrib > 0.0f) + { + alpha -= contrib; + } + } #endif vec3 irradiance = vec3(0, 0, 0); vec3 specular = vec3(0, 0, 0); + if (SkylightDamp>0) + wetAmmout += alpha; + dampen(surface, WetnessTexture, accumTime, wetAmmout*dampness); + // Radiance (Specular) #if DEBUGVIZ_SPECCUBEMAP == 0 float lod = roughnessToMipLevel(surface.roughness, cubeMips); @@ -157,7 +179,7 @@ void main() #endif #if SKYLIGHT_ONLY == 0 - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { float contrib = contribution[i]; if (contrib > 0.0f) @@ -167,17 +189,16 @@ void main() irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib; specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib; - alpha -= contrib; } } #endif - + if (skylightCubemapIdx != -1 && alpha >= 0.001) { irradiance = lerp(irradiance,textureLod(irradianceCubemapAR, vec4(surface.R, skylightCubemapIdx), 0).xyz,alpha); specular = lerp(specular,textureLod(specularCubemapAR, vec4(surface.R, skylightCubemapIdx), lod).xyz,alpha); } - + #if DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0 OUT_col = vec4(specular, 1); return; diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl index bd192f711..e397a2410 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl @@ -20,11 +20,14 @@ uniform int numProbes; TORQUE_UNIFORM_SAMPLERCUBEARRAY(specularCubemapAR, 4); TORQUE_UNIFORM_SAMPLERCUBEARRAY(irradianceCubemapAR, 5); +TORQUE_UNIFORM_SAMPLER2D(WetnessTexture, 6); #ifdef USE_SSAO_MASK -TORQUE_UNIFORM_SAMPLER2D(ssaoMask, 6); -uniform float4 rtParams6; +TORQUE_UNIFORM_SAMPLER2D(ssaoMask, 7); +uniform float4 rtParams7; #endif +uniform float accumTime; +uniform float dampness; uniform float4 probePosArray[MAX_PROBES]; uniform float4 refPosArray[MAX_PROBES]; @@ -37,6 +40,7 @@ uniform float4 probeContribColors[MAX_PROBES]; #endif uniform int skylightCubemapIdx; +uniform int SkylightDamp; float4 main(PFXVertToPix IN) : SV_TARGET { @@ -59,7 +63,7 @@ float4 main(PFXVertToPix IN) : SV_TARGET #endif float alpha = 1; - + float wetAmmout = 0; #if SKYLIGHT_ONLY == 0 int i = 0; float blendFactor[MAX_PROBES]; @@ -74,7 +78,7 @@ float4 main(PFXVertToPix IN) : SV_TARGET if (alpha > 0) { //Process prooooobes - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribution[i] = 0.0; @@ -93,9 +97,15 @@ float4 main(PFXVertToPix IN) : SV_TARGET else contribution[i] = 0.0; + if (refScaleArray[i].w>0) + wetAmmout += contribution[i]; + else + wetAmmout -= contribution[i]; + blendSum += contribution[i]; blendCap = max(contribution[i],blendCap); } + if (wetAmmout<0) wetAmmout =0; if (probehits > 0.0) { invBlendSum = (probehits - blendSum)/probehits; //grab the remainder @@ -106,7 +116,7 @@ float4 main(PFXVertToPix IN) : SV_TARGET blendFacSum += blendFactor[i]; //running tally of results } - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { //normalize, but in the range of the highest value applied //to preserve blend vs skylight @@ -116,7 +126,7 @@ float4 main(PFXVertToPix IN) : SV_TARGET #if DEBUGVIZ_ATTENUATION == 1 float contribAlpha = 0; - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { contribAlpha += contribution[i]; } @@ -126,18 +136,30 @@ float4 main(PFXVertToPix IN) : SV_TARGET #if DEBUGVIZ_CONTRIB == 1 float3 finalContribColor = float3(0, 0, 0); - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { finalContribColor += contribution[i] * float3(fmod(i+1,2),fmod(i+1,3),fmod(i+1,4)); } return float4(finalContribColor, 1); #endif } + for (i = 0; i < numProbes; i++) + { + float contrib = contribution[i]; + if (contrib > 0.0f) + { + alpha -= contrib; + } + } #endif float3 irradiance = float3(0, 0, 0); float3 specular = float3(0, 0, 0); + if (SkylightDamp>0) + wetAmmout += alpha; + dampen(surface, TORQUE_SAMPLER2D_MAKEARG(WetnessTexture), accumTime, wetAmmout*dampness); + // Radiance (Specular) #if DEBUGVIZ_SPECCUBEMAP == 0 float lod = roughnessToMipLevel(surface.roughness, cubeMips); @@ -146,7 +168,7 @@ float4 main(PFXVertToPix IN) : SV_TARGET #endif #if SKYLIGHT_ONLY == 0 - for (i = 0; i < numProbes; ++i) + for (i = 0; i < numProbes; i++) { float contrib = contribution[i]; if (contrib > 0.0f) @@ -156,11 +178,9 @@ float4 main(PFXVertToPix IN) : SV_TARGET irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib; specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib; - alpha -= contrib; } } #endif - if(skylightCubemapIdx != -1 && alpha >= 0.001) { irradiance = lerp(irradiance,TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.R, skylightCubemapIdx, 0).xyz,alpha); @@ -172,7 +192,6 @@ float4 main(PFXVertToPix IN) : SV_TARGET #elif DEBUGVIZ_DIFFCUBEMAP == 1 return float4(irradiance, 1); #endif - //energy conservation float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); float3 kD = 1.0f - F;