diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index 549b67e62..787453890 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -54,7 +54,6 @@ extern bool gEditingMission; extern ColorI gCanvasClearColor; -bool ReflectionProbe::smRenderReflectionProbes = true; bool ReflectionProbe::smRenderPreviewProbes = true; IMPLEMENT_CO_NETOBJECT_V1(ReflectionProbe); @@ -73,8 +72,8 @@ ConsoleDocClass(ReflectionProbe, ImplementEnumType(ReflectProbeType, "Type of mesh data available in a shape.\n" "@ingroup gameObjects") -{ ProbeInfo::Sphere, "Sphere", "Sphere shaped" }, -{ ProbeInfo::Box, "Box", "Box shape" } +{ ProbeRenderInst::Sphere, "Sphere", "Sphere shaped" }, +{ ProbeRenderInst::Box, "Box", "Box shape" } EndImplementEnumType; ImplementEnumType(IndrectLightingModeEnum, @@ -105,7 +104,7 @@ ReflectionProbe::ReflectionProbe() mTypeMask = LightObjectType | MarkerObjectType; - mProbeShapeType = ProbeInfo::Box; + mProbeShapeType = ProbeRenderInst::Box; mIndrectLightingModeType = NoIndirect; @@ -132,7 +131,7 @@ ReflectionProbe::ReflectionProbe() mResourcesCreated = false; - mProbeInfo = new ProbeInfo(); + mProbeInfo = nullptr; mPrefilterSize = 64; mPrefilterMipLevels = mLog2(F32(mPrefilterSize)); @@ -148,6 +147,9 @@ ReflectionProbe::~ReflectionProbe() if (mEditorShapeInst) SAFE_DELETE(mEditorShapeInst); + if (mProbeInfo) + SAFE_DELETE(mProbeInfo); + if (mReflectionModeType != StaticCubemap && mStaticCubemap) mStaticCubemap->deleteObject(); } @@ -183,7 +185,7 @@ void ReflectionProbe::initPersistFields() &_doBake, &defaultProtectedGetFn, "Regenerate Voxel Grid", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors); endGroup("Reflection"); - Con::addVariable("$Light::renderReflectionProbes", TypeBool, &ReflectionProbe::smRenderReflectionProbes, + Con::addVariable("$Light::renderReflectionProbes", TypeBool, &ProbeManager::smRenderReflectionProbes, "Toggles rendering of light frustums when the light is selected in the editor.\n\n" "@note Only works for shadow mapped lights.\n\n" "@ingroup Lighting"); @@ -377,10 +379,10 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) if (stream->readFlag()) // ShapeTypeMask { - U32 shapeType = ProbeInfo::Sphere; + U32 shapeType = ProbeRenderInst::Sphere; stream->read(&shapeType); - mProbeShapeType = (ProbeInfo::ProbeShapeType)shapeType; + mProbeShapeType = (ProbeRenderInst::ProbeShapeType)shapeType; createGeometry(); } @@ -457,7 +459,10 @@ void ReflectionProbe::createGeometry() void ReflectionProbe::updateProbeParams() { if (mProbeInfo == nullptr) - return; + { + mProbeInfo = new ProbeRenderInst(); + mProbeInfo->mIsEnabled = false; + } updateMaterial(); @@ -465,13 +470,16 @@ void ReflectionProbe::updateProbeParams() mProbeInfo->mProbeShapeType = mProbeShapeType; + //mProbeInfo->mTransform = getWorldTransform(); mProbeInfo->setPosition(getPosition()); + //Point3F pos = mProbeInfo->mTransform.getPosition(); + //Update the bounds //mObjBox.minExtents.set(-1, -1, -1); //mObjBox.maxExtents.set(1, 1, 1); - //mObjScale.set(mRadius / 2, mRadius / 2, mRadius / 2); + mObjScale.set(mRadius, mRadius, mRadius); // Skip our transform... it just dirties mask bits. Parent::setTransform(mObjToWorld); @@ -484,6 +492,8 @@ void ReflectionProbe::updateProbeParams() mProbeInfo->mIsSkylight = false; mProbeInfo->mProbePosOffset = mProbePosOffset; + + mProbeInfo->mDirty = true; } void ReflectionProbe::updateMaterial() @@ -518,6 +528,12 @@ void ReflectionProbe::updateMaterial() { mProbeInfo->mCubemap = &mDynamicCubemap; } + + //Make us ready to render + if (mEnabled) + mProbeInfo->mIsEnabled = true; + else + mProbeInfo->mIsEnabled = false; } bool ReflectionProbe::createClientResources() @@ -583,7 +599,7 @@ void ReflectionProbe::generateTextures() void ReflectionProbe::prepRenderImage(SceneRenderState *state) { - if (!mEnabled || !ReflectionProbe::smRenderReflectionProbes) + if (!mEnabled || !ProbeManager::smRenderReflectionProbes) return; Point3F distVec = getRenderPosition() - state->getCameraPosition(); @@ -612,7 +628,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state) mProbeInfo->mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f); //Register - PROBEMGR->registerProbe(mProbeInfo, this); + //PROBEMGR->registerProbe(mProbeInfo, this); if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr) { @@ -694,7 +710,7 @@ void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat) { - if (!ReflectionProbe::smRenderReflectionProbes) + if (!ProbeManager::smRenderReflectionProbes) return; GFXDrawUtil *draw = GFX->getDrawUtil(); @@ -708,7 +724,7 @@ void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri, ColorI color = ColorI::WHITE; color.alpha = 25; - if (mProbeShapeType == ProbeInfo::Sphere) + if (mProbeShapeType == ProbeRenderInst::Sphere) { draw->drawSphere(desc, mRadius, getPosition(), color); } @@ -844,8 +860,8 @@ void ReflectionProbe::bake(String outputPath, S32 resolution) //gEditingMission = false; //Set this to true to use the prior method where it goes through the SPT_Reflect path for the bake - bool probeRenderState = ReflectionProbe::smRenderReflectionProbes; - ReflectionProbe::smRenderReflectionProbes = false; + bool probeRenderState = ProbeManager::smRenderReflectionProbes; + ProbeManager::smRenderReflectionProbes = false; for (U32 i = 0; i < 6; ++i) { GFXTexHandle blendTex; @@ -996,7 +1012,7 @@ void ReflectionProbe::bake(String outputPath, S32 resolution) Con::errorf("ReflectionProbe::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!"); } - ReflectionProbe::smRenderReflectionProbes = probeRenderState; + ProbeManager::smRenderReflectionProbes = probeRenderState; setMaskBits(-1); if (preCapture) diff --git a/Engine/source/T3D/lighting/reflectionProbe.h b/Engine/source/T3D/lighting/reflectionProbe.h index 3baa08239..5947bc0ee 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.h +++ b/Engine/source/T3D/lighting/reflectionProbe.h @@ -109,9 +109,9 @@ protected: //-------------------------------------------------------------------------- // Rendering variables //-------------------------------------------------------------------------- - ProbeInfo::ProbeShapeType mProbeShapeType; + ProbeRenderInst::ProbeShapeType mProbeShapeType; - ProbeInfo* mProbeInfo; + ProbeRenderInst* mProbeInfo; //Indirect Lighting Contribution stuff IndrectLightingModeType mIndrectLightingModeType; @@ -154,7 +154,6 @@ protected: U32 mSpherePrimitiveCount; //Debug rendering - static bool smRenderReflectionProbes; static bool smRenderPreviewProbes; U32 mDynamicLastBakeMS; @@ -221,7 +220,7 @@ public: // Get the Material instance void updateMaterial(); - void updateProbeParams(); + virtual void updateProbeParams(); bool createClientResources(); void generateTextures(); @@ -241,7 +240,7 @@ public: void bake(String outputPath, S32 resolution); }; -typedef ProbeInfo::ProbeShapeType ReflectProbeType; +typedef ProbeRenderInst::ProbeShapeType ReflectProbeType; DefineEnumType(ReflectProbeType); typedef ReflectionProbe::IndrectLightingModeType IndrectLightingModeEnum; diff --git a/Engine/source/T3D/lighting/skylight.cpp b/Engine/source/T3D/lighting/skylight.cpp index 5d25283ff..c55e43a5a 100644 --- a/Engine/source/T3D/lighting/skylight.cpp +++ b/Engine/source/T3D/lighting/skylight.cpp @@ -150,12 +150,9 @@ void Skylight::unpackUpdate(NetConnection *conn, BitStream *stream) void Skylight::updateProbeParams() { - if (mProbeInfo == nullptr) - return; - Parent::updateProbeParams(); - mProbeInfo->mProbeShapeType = ProbeInfo::Sphere; + mProbeInfo->mProbeShapeType = ProbeRenderInst::Sphere; mProbeInfo->setPosition(getPosition()); @@ -199,7 +196,7 @@ void Skylight::prepRenderImage(SceneRenderState *state) // Get a handy pointer to our RenderPassmanager //RenderPassManager *renderPass = state->getRenderPass(); - PROBEMGR->registerSkylight(mProbeInfo, this); + //PROBEMGR->registerSkylight(mProbeInfo, this); if (Skylight::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr) { diff --git a/Engine/source/T3D/lighting/skylight.h b/Engine/source/T3D/lighting/skylight.h index 9fc37334c..6301ca7fe 100644 --- a/Engine/source/T3D/lighting/skylight.h +++ b/Engine/source/T3D/lighting/skylight.h @@ -109,7 +109,7 @@ public: // minimizing texture, state, and shader switching by grouping objects that // use the same Materials. //-------------------------------------------------------------------------- - void updateProbeParams(); + virtual void updateProbeParams(); // This is the function that allows this object to submit itself for rendering void prepRenderImage(SceneRenderState *state); diff --git a/Engine/source/T3D/systems/componentSystem.h b/Engine/source/T3D/systems/componentSystem.h deleted file mode 100644 index fc106a6a2..000000000 --- a/Engine/source/T3D/systems/componentSystem.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "console/engineAPI.h" - -template -class SystemInterface -{ -public: - bool mIsEnabled; - bool mIsServer; - - static Vector all; - - SystemInterface() - { - all.push_back((T*)this); - } - - virtual ~SystemInterface() - { - for (U32 i = 0; i < all.size(); i++) - { - if (all[i] == (T*)this) - { - all.erase(i); - return; - } - } - } -}; -template Vector SystemInterface::all(0); \ No newline at end of file diff --git a/Engine/source/T3D/systems/render/meshRenderSystem.h b/Engine/source/T3D/systems/render/meshRenderSystem.h index 4bc2269db..9be78b4e3 100644 --- a/Engine/source/T3D/systems/render/meshRenderSystem.h +++ b/Engine/source/T3D/systems/render/meshRenderSystem.h @@ -1,6 +1,6 @@ #pragma once #include "scene/sceneRenderState.h" -#include "T3D/systems/componentSystem.h" +#include "core/util/SystemInterfaceList.h" #include "ts/tsShape.h" #include "ts/tsShapeInstance.h" #include "T3D/assets/ShapeAsset.h" diff --git a/Engine/source/T3D/systems/updateSystem.h b/Engine/source/T3D/systems/updateSystem.h index b7d24eb88..5aad7a732 100644 --- a/Engine/source/T3D/systems/updateSystem.h +++ b/Engine/source/T3D/systems/updateSystem.h @@ -1,5 +1,5 @@ #pragma once -#include "componentSystem.h" +#include "core/util/SystemInterfaceList.h" class UpdateSystemInterface : public SystemInterface { diff --git a/Engine/source/core/util/systemInterfaceList.h b/Engine/source/core/util/systemInterfaceList.h new file mode 100644 index 000000000..5e4e4b76d --- /dev/null +++ b/Engine/source/core/util/systemInterfaceList.h @@ -0,0 +1,30 @@ +#pragma once +#include "console/engineAPI.h" + +template +class SystemInterface +{ +public: + bool mIsEnabled; + bool mIsServer; + + static Vector all; + + SystemInterface() + { + all.push_back((T*)this); + } + + virtual ~SystemInterface() + { + for (U32 i = 0; i < all.size(); i++) + { + if (all[i] == (T*)this) + { + all.erase(i); + return; + } + } + } +}; +template Vector SystemInterface::all(0); \ No newline at end of file diff --git a/Engine/source/lighting/probeManager.cpp b/Engine/source/lighting/probeManager.cpp index 5b7b7af76..3e05d86ae 100644 --- a/Engine/source/lighting/probeManager.cpp +++ b/Engine/source/lighting/probeManager.cpp @@ -39,14 +39,18 @@ #include "renderInstance/renderDeferredMgr.h" #include "shaderGen/shaderGenVars.h" +#include "math/util/sphereMesh.h" + Signal ProbeManager::smActivateSignal; ProbeManager *ProbeManager::smProbeManager = NULL; +bool ProbeManager::smRenderReflectionProbes = true; // // -ProbeInfo::ProbeInfo() - : mTransform(true), +ProbeRenderInst::ProbeRenderInst() : SystemInterface(), + mTransform(true), + mDirty(false), mAmbient(0.0f, 0.0f, 0.0f, 1.0f), mPriority(1.0f), mScore(0.0f), @@ -56,7 +60,8 @@ ProbeInfo::ProbeInfo() mBRDFTexture(NULL), mRadius(1.0f), mIntensity(1.0f), - mProbePosOffset(0,0,0) + mProbePosOffset(0,0,0), + numPrims(0) { for (U32 i = 0; i < 5; ++i) { @@ -64,12 +69,26 @@ ProbeInfo::ProbeInfo() } } -ProbeInfo::~ProbeInfo() +ProbeRenderInst::~ProbeRenderInst() { - SAFE_DELETE(mCubemap); + if (mCubemap && !mCubemap->isNull()) + { + mCubemap->getPointer()->destroySelf(); + mCubemap->free(); + } + if (mIrradianceCubemap && !mIrradianceCubemap->isNull()) + { + mIrradianceCubemap->getPointer()->destroySelf(); + mIrradianceCubemap->free(); + } + if (mBRDFTexture && !mBRDFTexture->isNull()) + { + mBRDFTexture->getPointer()->destroySelf(); + mBRDFTexture->free(); + } } -void ProbeInfo::set(const ProbeInfo *probeInfo) +void ProbeRenderInst::set(const ProbeRenderInst *probeInfo) { mTransform = probeInfo->mTransform; mAmbient = probeInfo->mAmbient; @@ -95,38 +114,12 @@ void ProbeInfo::set(const ProbeInfo *probeInfo) } } -void ProbeInfo::getWorldToLightProj(MatrixF *outMatrix) const +void ProbeRenderInst::getWorldToLightProj(MatrixF *outMatrix) const { *outMatrix = getTransform(); outMatrix->inverse(); } - -void ProbeInfoList::registerProbe(ProbeInfo *light) -{ - if (!light) - return; - // just add the light, we'll try to scan for dupes later... - push_back(light); -} - -void ProbeInfoList::unregisterProbe(ProbeInfo *light) -{ - // remove all of them... - ProbeInfoList &list = *this; - for (U32 i = 0; isetPosition( mCullPos - (probe->getDirection() * 10000.0f ) ); - probe->mRadius = 2000000.0f; - } - - mSpecialProbes[type] = probe; - registerProbe(probe, NULL ); -} - -void ProbeManager::registerProbes( const Frustum *frustum, bool staticLighting ) -{ - PROFILE_SCOPE( ProbeManager_RegisterProbes ); - - // TODO: We need to work this out... - // - // 1. Why do we register and unregister lights on every - // render when they don't often change... shouldn't we - // just register once and keep them? - // - // 2. If we do culling of lights should this happen as part - // of registration or somewhere else? - // - - // Grab the lights to process. - Vector activeLights; - const U32 lightMask = LightObjectType; - - if ( staticLighting || !frustum ) - { - // We're processing static lighting or want all the lights - // in the container registerd... so no culling. - getSceneManager()->getContainer()->findObjectList( lightMask, &activeLights ); - } - else - { - // Cull the lights using the frustum. - getSceneManager()->getContainer()->findObjectList( *frustum, lightMask, &activeLights ); - /* supress light culling filter until we can sort out why that's misbehaving with dynamic cube mapping - for (U32 i = 0; i < activeLights.size(); ++i) - { - if (!getSceneManager()->mRenderedObjectsList.contains(activeLights[i])) - { - activeLights.erase(i); - --i; - } - } - */ - // Store the culling position for sun placement - // later... see setSpecialLight. - mCullPos = frustum->getPosition(); - - // HACK: Make sure the control object always gets - // processed as lights mounted to it don't change - // the shape bounds and can often get culled. - - GameConnection *conn = GameConnection::getConnectionToServer(); - if ( conn->getControlObject() ) - { - GameBase *conObject = conn->getControlObject(); - activeLights.push_back_unique( conObject ); - } - } - - // Let the lights register themselves. - /*for ( U32 i = 0; i < activeLights.size(); i++ ) - { - ISceneLight *lightInterface = dynamic_cast( activeLights[i] ); - if ( lightInterface ) - lightInterface->submitLights( this, staticLighting ); - }*/ -} - -void ProbeManager::registerSkylight(ProbeInfo *probe, SimObject *obj) -{ - mSkylight = probe; - - if (String("Advanced Lighting").equal(LIGHTMGR->getName(), String::NoCase)) - { - SceneRenderState* state = mSceneManager->getCurrentRenderState(); - - RenderPassManager *renderPass = state->getRenderPass(); - - // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager - ProbeRenderInst *probeInst = renderPass->allocInst(); - - probeInst->set(probe); - - probeInst->type = RenderPassManager::RIT_Probes; - - // Submit our RenderInst to the RenderPassManager - state->getRenderPass()->addInst(probeInst); - } -} - -void ProbeManager::registerProbe(ProbeInfo *probe, SimObject *obj ) -{ - // AssertFatal( !mRegisteredProbes.contains(probe), - //"ProbeManager::registerGlobalLight - This light is already registered!" ); - - if (!mRegisteredProbes.contains(probe)) - mRegisteredProbes.push_back(probe); - - if (String("Advanced Lighting").equal(LIGHTMGR->getName(), String::NoCase)) - { - SceneRenderState* state = mSceneManager->getCurrentRenderState(); - - RenderPassManager *renderPass = state->getRenderPass(); - - // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager - ProbeRenderInst *probeInst = renderPass->allocInst(); - - probeInst->set(probe); - - probeInst->type = RenderPassManager::RIT_Probes; - - // Submit our RenderInst to the RenderPassManager - state->getRenderPass()->addInst(probeInst); - } -} - -void ProbeManager::unregisterProbe(ProbeInfo *probe ) -{ - mRegisteredProbes.unregisterProbe(probe); - - // If this is the sun... clear the special light too. - if (probe == mSpecialProbes[SkylightProbeType] ) - dMemset(mSpecialProbes, 0, sizeof(mSpecialProbes) ); -} - -void ProbeManager::unregisterAllProbes() -{ - //dMemset(mSpecialProbes, 0, sizeof(mSpecialProbes) ); - mRegisteredProbes.clear(); - - mSkylight = nullptr; -} - -void ProbeManager::getAllUnsortedProbes( Vector *list ) const -{ - list->merge( mRegisteredProbes ); } ProbeShaderConstants* ProbeManager::getProbeShaderConstants(GFXShaderConstBuffer* buffer) @@ -489,7 +306,7 @@ void ProbeManager::_update4ProbeConsts( const SceneData &sgData, probeRadiusSC->isValid() || probeBoxMinSC->isValid() || probeBoxMaxSC->isValid() || - probeCubemapSC->isValid() && (!mRegisteredProbes.empty() || mSkylight)) + probeCubemapSC->isValid() && (!ProbeRenderInst::all.empty())) { PROFILE_SCOPE(ProbeManager_Update4ProbeConsts_setProbes); @@ -517,21 +334,13 @@ void ProbeManager::_update4ProbeConsts( const SceneData &sgData, const MatrixF &worldToCameraXfm = matSet.getWorldToCamera(); // Gather the data for the first 4 probes. - const ProbeInfo *probe; + const ProbeRenderInst *probe; for (U32 i = 0; i < 4; i++) { - if (i >= mRegisteredProbes.size()) + if (i >= ProbeRenderInst::all.size()) break; - if (i == 0 && mSkylight) - { - //quickly try and see if we have a skylight, and set that to always be probe 0 - probe = mSkylight; - } - else - { - probe = mRegisteredProbes[i]; - } + probe = ProbeRenderInst::all[i]; if (!probe) continue; @@ -555,7 +364,7 @@ void ProbeManager::_update4ProbeConsts( const SceneData &sgData, probeBoxMaxs[i].y = maxExt.y; probeBoxMaxs[i].z = maxExt.z; - probeIsSphere[i] = probe->mProbeShapeType == ProbeInfo::Sphere ? 1.0 : 0.0; + probeIsSphere[i] = probe->mProbeShapeType == ProbeRenderInst::Sphere ? 1.0 : 0.0; Point3F localProbePos; worldToCameraXfm.mulP(probe->getPosition(), &localProbePos); @@ -743,6 +552,469 @@ AvailableSLInterfaces* ProbeManager::getSceneLightingInterface() return NULL; } +void ProbeManager::updateDirtyProbes() +{ + for (U32 i = 0; i < ProbeRenderInst::all.size(); i++) + { + ProbeRenderInst* probe = ProbeRenderInst::all[i]; + + if (probe->mDirty) + { + //make sure we have a fill-out on our primitives, materials, etc + //so we don't have to always force an update when it's not needed + if (probe->mIsSkylight) + { + setupSkylightProbe(probe); + } + else + { + if (probe->mProbeShapeType == ProbeRenderInst::Sphere) + { + setupSphereReflectionProbe(probe); + } + else if(probe->mProbeShapeType == ProbeRenderInst::Box) + { + setupConvexReflectionProbe(probe); + } + } + + probe->mDirty = false; + } + } +} + +ProbeManager::SkylightMaterialInfo* ProbeManager::getSkylightMaterial() +{ + PROFILE_SCOPE(AdvancedLightBinManager_getSkylightMaterial); + + //ReflectProbeMaterialInfo *info = NULL; + + if (!mSkylightMaterial) + + // Now create the material info object. + mSkylightMaterial = new SkylightMaterialInfo("SklyightMaterial", + getGFXVertexFormat()); + + return mSkylightMaterial; +} + +ProbeManager::ReflectProbeMaterialInfo* ProbeManager::getReflectProbeMaterial() +{ + PROFILE_SCOPE(AdvancedLightBinManager_getReflectProbeMaterial); + + //ReflectProbeMaterialInfo *info = NULL; + + if (!mReflectProbeMaterial) + + // Now create the material info object. + mReflectProbeMaterial = new ReflectProbeMaterialInfo("ReflectionProbeMaterial", + getGFXVertexFormat()); + + return mReflectProbeMaterial; +} + +void ProbeManager::setupSkylightProbe(ProbeRenderInst *probeInfo) +{ + probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer); + + if (!mSkylightMaterial) + mSkylightMaterial = getSkylightMaterial(); +} + +void ProbeManager::setupSphereReflectionProbe(ProbeRenderInst *probeInfo) +{ + probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer); + + if (!mReflectProbeMaterial) + mReflectProbeMaterial = getReflectProbeMaterial(); +} + +void ProbeManager::setupConvexReflectionProbe(ProbeRenderInst *probeInfo) +{ + static const Point3F cubePoints[8] = + { + Point3F(1, -1, -1), Point3F(1, -1, 1), Point3F(1, 1, -1), Point3F(1, 1, 1), + Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1) + }; + + /*static const Point3F cubeNormals[6] = + { + Point3F(1, 0, 0), Point3F(-1, 0, 0), Point3F(0, 1, 0), + Point3F(0, -1, 0), Point3F(0, 0, 1), Point3F(0, 0, -1) + };*/ + + /*static const Point2F cubeTexCoords[4] = + { + Point2F(0, 0), Point2F(0, -1), + Point2F(1, 0), Point2F(1, -1) + };*/ + + static const U32 cubeFaces[36][3] = + { + { 3, 0, 3 },{ 0, 0, 0 },{ 1, 0, 1 }, + { 2, 0, 2 },{ 0, 0, 0 },{ 3, 0, 3 }, + { 7, 1, 1 },{ 4, 1, 2 },{ 5, 1, 0 }, + { 6, 1, 3 },{ 4, 1, 2 },{ 7, 1, 1 }, + { 3, 2, 1 },{ 5, 2, 2 },{ 2, 2, 0 }, + { 7, 2, 3 },{ 5, 2, 2 },{ 3, 2, 1 }, + { 1, 3, 3 },{ 4, 3, 0 },{ 6, 3, 1 }, + { 0, 3, 2 },{ 4, 3, 0 },{ 1, 3, 3 }, + { 3, 4, 3 },{ 6, 4, 0 },{ 7, 4, 1 }, + { 1, 4, 2 },{ 6, 4, 0 },{ 3, 4, 3 }, + { 2, 5, 1 },{ 4, 5, 2 },{ 0, 5, 0 }, + { 5, 5, 3 },{ 4, 5, 2 },{ 2, 5, 1 } + }; + + // Fill the vertex buffer + GFXVertexPC *pVert = NULL; + + probeInfo->numVerts = 36; + + probeInfo->vertBuffer.set(GFX, 36, GFXBufferTypeStatic); + pVert = probeInfo->vertBuffer.lock(); + + Point3F halfSize = Point3F(probeInfo->mRadius, probeInfo->mRadius, probeInfo->mRadius); + + for (U32 i = 0; i < 36; i++) + { + const U32& vdx = cubeFaces[i][0]; + pVert[i].point = cubePoints[vdx] * halfSize; + } + + probeInfo->vertBuffer.unlock(); + + // Fill the primitive buffer + U16 *pIdx = NULL; + + probeInfo->primBuffer.set(GFX, 36, 12, GFXBufferTypeStatic); + + probeInfo->primBuffer.lock(&pIdx); + + for (U16 i = 0; i < 36; i++) + pIdx[i] = i; + + probeInfo->primBuffer.unlock(); + + probeInfo->numPrims = 12; + + if (!mReflectProbeMaterial) + mReflectProbeMaterial = getReflectProbeMaterial(); + // + + // mReflectProbeBin.push_back(pEntry); +} + +GFXVertexBufferHandle ProbeManager::getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives) +{ + static SphereMesh sSphereMesh; + + if (mSphereGeometry.isNull()) + { + const SphereMesh::TriangleMesh * sphereMesh = sSphereMesh.getMesh(3); + S32 numPoly = sphereMesh->numPoly; + mSpherePrimitiveCount = 0; + mSphereGeometry.set(GFX, numPoly * 3, GFXBufferTypeStatic); + mSphereGeometry.lock(); + S32 vertexIndex = 0; + + for (S32 i = 0; ipoly[i].pnt[0]; + mSphereGeometry[vertexIndex].color = ColorI::WHITE; + vertexIndex++; + + mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[1]; + mSphereGeometry[vertexIndex].color = ColorI::WHITE; + vertexIndex++; + + mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[2]; + mSphereGeometry[vertexIndex].color = ColorI::WHITE; + vertexIndex++; + } + mSphereGeometry.unlock(); + } + + outNumPrimitives = mSpherePrimitiveCount; + outPrimitives = NULL; // For now + return mSphereGeometry; +} + +// +// +bool ReflectProbeMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat) +{ + bool success = Parent::init(features, vertexFormat); + + // If the initialization failed don't continue. + if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0) + return false; + return true; +} + +bool ReflectProbeMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData) +{ + // Go no further if the material failed to initialize properly. + if (!mProcessedMaterial || + mProcessedMaterial->getNumPasses() == 0) + return false; + + bool bRetVal = Parent::setupPass(state, sgData);; + + AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes"); + const RenderPassData *rpd = mProcessedMaterial->getPass(0); + AssertFatal(rpd, "No render pass data!"); + AssertFatal(rpd->mRenderStates[0], "No render state 0!"); + + if (!mProjectionState) + { + GFXStateBlockDesc desc; + desc.setZReadWrite(false); + desc.zWriteEnable = false; + desc.setCullMode(GFXCullNone); + desc.setBlend(true, GFXBlendOne, GFXBlendOne); + mProjectionState = GFX->createStateBlock(desc); + } + // Now override stateblock with our own + GFX->setStateBlock(mProjectionState); + + return bRetVal; +} + +// +// +ProbeManager::ReflectProbeMaterialInfo::ReflectProbeMaterialInfo(const String &matName, + const GFXVertexFormat *vertexFormat) + : matInstance(NULL), + zNearFarInvNearFar(NULL), + farPlane(NULL), + vsFarPlane(NULL), + negFarPlaneDotEye(NULL), + probeWSPos(NULL), + attenuation(NULL), + radius(NULL), + invViewMat(NULL), + cubeMips(NULL) +{ + Material *mat = MATMGR->getMaterialDefinitionByName(matName); + if (!mat) + return; + + matInstance = new ReflectProbeMatInstance(*mat); + + const Vector ¯os = Vector(); + + for (U32 i = 0; i < macros.size(); i++) + matInstance->addShaderMacro(macros[i].name, macros[i].value); + + matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat); + + attenuation = matInstance->getMaterialParameterHandle("$attenuation"); + radius = matInstance->getMaterialParameterHandle("$radius"); + probeLSPos = matInstance->getMaterialParameterHandle("$probeLSPos"); + probeWSPos = matInstance->getMaterialParameterHandle("$probeWSPos"); + farPlane = matInstance->getMaterialParameterHandle("$farPlane"); + vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane"); + negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye"); + zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar"); + + invViewMat = matInstance->getMaterialParameterHandle("$invViewMat"); + + useCubemap = matInstance->getMaterialParameterHandle("$useCubemap"); + + cubemap = matInstance->getMaterialParameterHandle("$cubeMap"); + cubeMips = matInstance->getMaterialParameterHandle("$cubeMips"); + + eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld"); + bbMin = matInstance->getMaterialParameterHandle("$bbMin"); + bbMax = matInstance->getMaterialParameterHandle("$bbMax"); + + useSphereMode = matInstance->getMaterialParameterHandle("$useSphereMode"); + + for (U32 i = 0; i < 9; i++) + shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i)); + + for (U32 i = 0; i < 5; i++) + shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i)); +} + +ProbeManager::ReflectProbeMaterialInfo::~ReflectProbeMaterialInfo() +{ + SAFE_DELETE(matInstance); +} + +void ProbeManager::ReflectProbeMaterialInfo::setViewParameters(const F32 _zNear, + const F32 _zFar, + const Point3F &_eyePos, + const PlaneF &_farPlane, + const PlaneF &_vsFarPlane, const MatrixF &_inverseViewMatrix) +{ + MaterialParameters *matParams = matInstance->getMaterialParameters(); + + matParams->setSafe(farPlane, *((const Point4F *)&_farPlane)); + + matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane)); + + if (negFarPlaneDotEye->isValid()) + { + // -dot( farPlane, eyePos ) + const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d); + matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal); + } + + matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar)); + + matParams->setSafe(invViewMat, _inverseViewMatrix); + + Point4F frPlane = *((const Point4F *)&_farPlane); + Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane); + Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar); + const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d); +} + +void ProbeManager::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly) +{ + //Set up the params + MaterialParameters *matParams = matInstance->getMaterialParameters(); + + matParams->setSafe(radius, probeInfo->mRadius); + + Point3F probePos = probeInfo->getPosition() + probeInfo->mProbePosOffset; + //worldViewOnly.mulP(probeInfo->getPosition(), &probePos); + matParams->setSafe(probeWSPos, probePos); + + worldViewOnly.mulP(probeInfo->getPosition(), &probePos); + matParams->setSafe(probeLSPos, probePos); + + // Get the attenuation falloff ratio and normalize it. + Point3F attenRatio = Point3F(0.0f, 1.0f, 1.0f); + F32 total = attenRatio.x + attenRatio.y + attenRatio.z; + if (total > 0.0f) + attenRatio /= total; + + F32 radius = probeInfo->mRadius; + + Point2F attenParams((1.0f / radius) * attenRatio.y, + (1.0f / (radius * radius)) * attenRatio.z); + + matParams->setSafe(attenuation, attenParams); + + NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred"); + + GFXTextureObject *deferredTexObject = deferredTexTarget->getTexture(); + if (!deferredTexObject) return; + + GFX->setTexture(0, deferredTexObject); + + NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo"); + + GFXTextureObject *matInfoTexObject = matInfoTexTarget->getTexture(); + if (!matInfoTexObject) return; + + GFX->setTexture(1, matInfoTexObject); + + if (probeInfo->mCubemap && !probeInfo->mCubemap->isNull()) + { + GFX->setCubeTexture(2, probeInfo->mCubemap->getPointer()); + } + else + { + GFX->setCubeTexture(2, NULL); + } + + if (probeInfo->mIrradianceCubemap && !probeInfo->mIrradianceCubemap->isNull()) + { + GFX->setCubeTexture(3, probeInfo->mIrradianceCubemap->getPointer()); + } + else + { + GFX->setCubeTexture(3, NULL); + } + + if (probeInfo->mBRDFTexture && !probeInfo->mBRDFTexture->isNull()) + { + GFX->setTexture(4, probeInfo->mBRDFTexture->getPointer()); + } + else + { + GFX->setTexture(4, NULL); + } + + if (probeInfo->mCubemap->isValid()) + matParams->setSafe(cubeMips, mPow(probeInfo->mCubemap->getPointer()->getMipMapLevels(), 2.0f)); + else + matParams->setSafe(cubeMips, F32(0.0)); + + matParams->setSafe(eyePosWorld, renderState->getCameraPosition()); + matParams->setSafe(bbMin, probeInfo->mBounds.minExtents); + matParams->setSafe(bbMax, probeInfo->mBounds.maxExtents); + + matParams->setSafe(useSphereMode, probeInfo->mProbeShapeType == ProbeRenderInst::Sphere ? 1.0f : 0.0f); + + //SH Terms + //static AlignedArray shTermsArray(9, sizeof(Point3F)); + //dMemset(shTermsArray.getBuffer(), 0, shTermsArray.getBufferSize()); + + for (U32 i = 0; i < 9; i++) + { + matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]); + } + + for (U32 i = 0; i < 5; i++) + { + matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]); + } + + const MatrixF worldToObjectXfm = probeInfo->mTransform; + MaterialParameterHandle *worldToObjMat = matInstance->getMaterialParameterHandle("$worldToObj"); + matParams->setSafe(worldToObjMat, worldToObjectXfm); +} + +// +// +// +ProbeManager::SkylightMaterialInfo::SkylightMaterialInfo(const String &matName, + const GFXVertexFormat *vertexFormat) + : ReflectProbeMaterialInfo(matName, vertexFormat) +{ + Material *mat = MATMGR->getMaterialDefinitionByName(matName); + if (!mat) + return; + + matInstance = new SkylightMatInstance(*mat); + + const Vector ¯os = Vector(); + + for (U32 i = 0; i < macros.size(); i++) + matInstance->addShaderMacro(macros[i].name, macros[i].value); + + matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat); + + farPlane = matInstance->getMaterialParameterHandle("$farPlane"); + vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane"); + negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye"); + zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar"); + + invViewMat = matInstance->getMaterialParameterHandle("$invViewMat"); + + useCubemap = matInstance->getMaterialParameterHandle("$useCubemap"); + cubemap = matInstance->getMaterialParameterHandle("$cubeMap"); + + eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld"); + + for (U32 i = 0; i < 9; i++) + shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i)); + + for (U32 i = 0; i < 5; i++) + shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i)); +} + +ProbeManager::SkylightMaterialInfo::~SkylightMaterialInfo() +{ + SAFE_DELETE(matInstance); +} + /*bool ProbeManager::lightScene( const char* callback, const char* param ) { BitSet32 flags = 0; diff --git a/Engine/source/lighting/probeManager.h b/Engine/source/lighting/probeManager.h index 75291e815..295ec3a2b 100644 --- a/Engine/source/lighting/probeManager.h +++ b/Engine/source/lighting/probeManager.h @@ -41,6 +41,20 @@ #ifndef _CUBEMAPDATA_H_ #include "gfx/sim/cubemapData.h" #endif +#ifndef _MATINSTANCE_H_ +#include "materials/matInstance.h" +#endif +#ifndef _MATTEXTURETARGET_H_ +#include "materials/matTextureTarget.h" +#endif +#ifndef _GFXPRIMITIVEBUFFER_H_ +#include "gfx/gfxPrimitiveBuffer.h" +#endif +#ifndef _GFXVERTEXBUFFER_H_ +#include "gfx/gfxVertexBuffer.h" +#endif + +#include "core/util/SystemInterfaceList.h" class SimObject; class ProbeManager; @@ -58,7 +72,7 @@ class SceneRenderState; class RenderDeferredMgr; class Frustum; -struct ProbeInfo +struct ProbeRenderInst : public SystemInterface { LinearColorF mAmbient; @@ -67,6 +81,8 @@ struct ProbeInfo F32 mRadius; F32 mIntensity; + bool mDirty; + Box3F mBounds; Point3F mProbePosOffset; @@ -90,8 +106,8 @@ struct ProbeInfo /// for this light. bool mDebugRender; - //GFXPrimitiveBufferHandle primBuffer; - //GFXVertexBufferHandle vertBuffer; + GFXPrimitiveBufferHandle primBuffer; + GFXVertexBufferHandle vertBuffer; U32 numPrims; U32 numVerts; Vector< U32 > numIndicesForPoly; @@ -110,11 +126,11 @@ struct ProbeInfo public: - ProbeInfo(); - ~ProbeInfo(); + ProbeRenderInst(); + ~ProbeRenderInst(); - // Copies data passed in from another probe - void set(const ProbeInfo *probe); + // Copies data passed in from light + void set(const ProbeRenderInst *probeInfo); // Accessors const MatrixF& getTransform() const { return mTransform; } @@ -145,13 +161,6 @@ public: void clear(); }; -class ProbeInfoList : public Vector -{ -public: - void registerProbe(ProbeInfo *probe); - void unregisterProbe(ProbeInfo *probe); -}; - struct ProbeShaderConstants { bool mInit; @@ -179,9 +188,92 @@ struct ProbeShaderConstants typedef Map ProbeConstantMap; +class ReflectProbeMatInstance : public MatInstance +{ + typedef MatInstance Parent; +protected: + MaterialParameterHandle * mProbeParamsSC; + bool mInternalPass; + + GFXStateBlockRef mProjectionState; + +public: + ReflectProbeMatInstance(Material &mat) : Parent(mat), mProbeParamsSC(NULL), mInternalPass(false), mProjectionState(NULL) {} + + virtual bool init(const FeatureSet &features, const GFXVertexFormat *vertexFormat); + virtual bool setupPass(SceneRenderState *state, const SceneData &sgData); +}; + +class SkylightMatInstance : public ReflectProbeMatInstance +{ + typedef ReflectProbeMatInstance Parent; + +public: + SkylightMatInstance(Material &mat) : Parent(mat) {} +}; + class ProbeManager { public: + struct ReflectProbeMaterialInfo + { + ReflectProbeMatInstance *matInstance; + + // { zNear, zFar, 1/zNear, 1/zFar } + MaterialParameterHandle *zNearFarInvNearFar; + + // Far frustum plane (World Space) + MaterialParameterHandle *farPlane; + + // Far frustum plane (View Space) + MaterialParameterHandle *vsFarPlane; + + // -dot( farPlane, eyePos ) + MaterialParameterHandle *negFarPlaneDotEye; + + // Inverse View matrix + MaterialParameterHandle *invViewMat; + + // Light Parameters + MaterialParameterHandle *probeLSPos; + MaterialParameterHandle *probeWSPos; + MaterialParameterHandle *attenuation; + MaterialParameterHandle *radius; + + MaterialParameterHandle *useCubemap; + MaterialParameterHandle *cubemap; + MaterialParameterHandle *cubeMips; + + MaterialParameterHandle *eyePosWorld; + MaterialParameterHandle *bbMin; + MaterialParameterHandle *bbMax; + + MaterialParameterHandle *useSphereMode; + + MaterialParameterHandle *shTerms[9]; + MaterialParameterHandle *shConsts[5]; + + ReflectProbeMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat); + + virtual ~ReflectProbeMaterialInfo(); + + + void setViewParameters(const F32 zNear, + const F32 zFar, + const Point3F &eyePos, + const PlaneF &farPlane, + const PlaneF &_vsFarPlane, + const MatrixF &_inverseViewMatrix); + + void setProbeParameters(const ProbeRenderInst *probe, const SceneRenderState* renderState, const MatrixF &worldViewOnly); + }; + + struct SkylightMaterialInfo : public ReflectProbeMaterialInfo + { + SkylightMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat); + + virtual ~SkylightMaterialInfo(); + }; enum SpecialProbeTypesEnum { @@ -193,11 +285,8 @@ public: ~ProbeManager(); - /// - static void initProbeFields(); - /// - static ProbeInfo* createProbeInfo(ProbeInfo* light = NULL); + static ProbeRenderInst* createProbeInfo(ProbeRenderInst* light = NULL); /// The light manager activation signal. static Signal smActivateSignal; @@ -217,7 +306,9 @@ public: // Returns the active scene lighting interface for this light manager. virtual AvailableSLInterfaces* getSceneLightingInterface(); - // Returns a "default" light info that callers should not free. Used for instances where we don't actually care about + void updateDirtyProbes(); + + /*// Returns a "default" light info that callers should not free. Used for instances where we don't actually care about // the light (for example, setting default data for SceneData) virtual ProbeInfo* getDefaultLight(); @@ -227,9 +318,9 @@ public: bool useDefault = true ); /// Set a special light type. - virtual void setSpecialProbe(SpecialProbeTypesEnum type, ProbeInfo *light ); + virtual void setSpecialProbe(SpecialProbeTypesEnum type, ProbeInfo *light );*/ - void registerSkylight(ProbeInfo *probe, SimObject *obj); + /*void registerSkylight(ProbeInfo *probe, SimObject *obj); // registered before scene traversal... virtual void registerProbe(ProbeInfo *light, SimObject *obj ); @@ -239,7 +330,7 @@ public: virtual void unregisterAllProbes(); /// Returns all unsorted and un-scored lights (both global and local). - void getAllUnsortedProbes( Vector *list ) const; + void getAllUnsortedProbes( Vector *list ) const;*/ /// Sets shader constants / textures for light infos virtual void setProbeInfo( ProcessedMaterial *pmat, @@ -255,6 +346,10 @@ public: const U32 textureSlot, GFXShaderConstBuffer *shaderConsts, ShaderConstHandles *handles ); + + ReflectProbeMaterialInfo* getReflectProbeMaterial(); + SkylightMaterialInfo* getSkylightMaterial(); + protected: /// The current active light manager. @@ -265,6 +360,15 @@ protected: public: ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer); + + // Add a reflection probe to the bin + void setupSkylightProbe(ProbeRenderInst *probeInfo); + void setupSphereReflectionProbe(ProbeRenderInst *probeInfo); + void setupConvexReflectionProbe(ProbeRenderInst *probeInfo); + + /// Debug rendering + static bool smRenderReflectionProbes; + protected: /// This helper function sets the shader constansts /// for the stock 4 light forward lighting code. @@ -279,19 +383,6 @@ protected: GFXShaderConstHandle *probeLocalPosSC, GFXShaderConstBuffer *shaderConsts ); - /// A dummy default light used when no lights - /// happen to be registered with the manager. - ProbeInfo *mDefaultProbe; - - /// The list of global registered lights which is - /// initialized before the scene is rendered. - ProbeInfoList mRegisteredProbes; - - ProbeInfo* mSkylight; - - /// The registered special light list. - ProbeInfo *mSpecialProbes[SpecialProbeTypesCount]; - /// The root culling position used for /// special sun light placement. /// @see setSpecialLight @@ -308,6 +399,19 @@ protected: GFXShaderRef mLastShader; ProbeShaderConstants* mLastConstants; + + // Convex geometry for lights + GFXVertexBufferHandle mSphereGeometry; + + GFXPrimitiveBufferHandle mSphereIndices; + + U32 mSpherePrimitiveCount; + + ReflectProbeMaterialInfo* mReflectProbeMaterial; + + SkylightMaterialInfo* mSkylightMaterial; + + GFXVertexBufferHandle getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives);; }; ProbeManager* ProbeManager::getProbeManager() diff --git a/Engine/source/renderInstance/renderPassManager.h b/Engine/source/renderInstance/renderPassManager.h index 38422329c..34c9908ce 100644 --- a/Engine/source/renderInstance/renderPassManager.h +++ b/Engine/source/renderInstance/renderPassManager.h @@ -477,86 +477,4 @@ struct OccluderRenderInst : public RenderInst void clear(); }; -struct ProbeRenderInst : public RenderInst -{ - LinearColorF mAmbient; - - MatrixF mTransform; - - F32 mRadius; - F32 mIntensity; - - Box3F mBounds; - Point3F mProbePosOffset; - - GFXCubemapHandle *mCubemap; - - GFXCubemapHandle *mIrradianceCubemap; - - GFXTexHandle *mBRDFTexture; - - /// The priority of this light used for - /// light and shadow scoring. - F32 mPriority; - - /// A temporary which holds the score used - /// when prioritizing lights for rendering. - F32 mScore; - - bool mIsSkylight; - - /// Whether to render debugging visualizations - /// for this light. - bool mDebugRender; - - GFXPrimitiveBufferHandle primBuffer; - GFXVertexBufferHandle vertBuffer; - U32 numPrims; - U32 numVerts; - Vector< U32 > numIndicesForPoly; - - ProbeInfo::ProbeShapeType mProbeShapeType; - - //Spherical Harmonics data - LinearColorF mSHTerms[9]; - F32 mSHConstants[5]; - -public: - - ProbeRenderInst(); - ~ProbeRenderInst(); - - // Copies data passed in from light - void set(const ProbeRenderInst *probeInfo); - void set(const ProbeInfo *probeInfo); - - // Accessors - const MatrixF& getTransform() const { return mTransform; } - void setTransform(const MatrixF &xfm) { mTransform = xfm; } - - Point3F getPosition() const { return mTransform.getPosition(); } - void setPosition(const Point3F &pos) { mTransform.setPosition(pos); } - - VectorF getDirection() const { return mTransform.getForwardVector(); } - void setDirection(const VectorF &val); - - const LinearColorF& getAmbient() const { return mAmbient; } - void setAmbient(const LinearColorF &val) { mAmbient = val; } - - void setPriority(F32 priority) { mPriority = priority; } - F32 getPriority() const { return mPriority; } - - void setScore(F32 score) { mScore = score; } - F32 getScore() const { return mScore; } - - bool isDebugRenderingEnabled() const { return mDebugRender; } - void enableDebugRendering(bool value) { mDebugRender = value; } - - // Builds the world to light view projection used for - // shadow texture and cookie lookups. - void getWorldToLightProj(MatrixF *outMatrix) const; - - void clear(); -}; - #endif // _RENDERPASSMANAGER_H_ diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 0101f2f7c..5c2b9ca46 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -46,7 +46,7 @@ S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b) PROFILE_SCOPE(AdvancedLightBinManager_AscendingReflectProbeInfluence); // Fetch asset definitions. - const ProbeRenderInst* pReflectProbeA = static_cast(((RenderBinManager::MainSortElem*)(a))->inst); + /*const ProbeRenderInst* pReflectProbeA = static_cast(((RenderBinManager::MainSortElem*)(a))->inst); const ProbeRenderInst* pReflectProbeB = static_cast(((RenderBinManager::MainSortElem*)(b))->inst); // Sort. @@ -59,22 +59,18 @@ S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b) if (pReflectProbeA->mScore > pReflectProbeB->mScore) return 1; else if (pReflectProbeA->mScore < pReflectProbeB->mScore) - return -1; + return -1;*/ return 0; } RenderProbeMgr::RenderProbeMgr() : RenderBinManager(RenderPassManager::RIT_Probes, 1.0f, 1.0f) { - mReflectProbeMaterial = nullptr; - mSkylightMaterial = nullptr; } RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder) : RenderBinManager(riType, renderOrder, processAddOrder) { - mReflectProbeMaterial = nullptr; - mSkylightMaterial = nullptr; } void RenderProbeMgr::initPersistFields() @@ -85,12 +81,12 @@ void RenderProbeMgr::initPersistFields() void RenderProbeMgr::addElement(RenderInst *inst) { // If this instance is translucent handle it in RenderTranslucentMgr - if (inst->translucentSort) + //if (inst->translucentSort) return; //AssertFatal(inst->defaultKey != 0, "RenderMeshMgr::addElement() - Got null sort key... did you forget to set it?"); - internalAddElement(inst); + /*internalAddElement(inst); ProbeRenderInst* probeInst = static_cast(inst); @@ -104,7 +100,7 @@ void RenderProbeMgr::addElement(RenderInst *inst) addSphereReflectionProbe(probeInst); else addConvexReflectionProbe(probeInst); - } + }*/ } //remove @@ -112,134 +108,6 @@ void RenderProbeMgr::addElement(RenderInst *inst) //Con::setIntVariable("lightMetrics::culledReflectProbes", 0/*mNumLightsCulled*/); // -GFXVertexBufferHandle RenderProbeMgr::getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives) -{ - static SphereMesh sSphereMesh; - - if (mSphereGeometry.isNull()) - { - const SphereMesh::TriangleMesh * sphereMesh = sSphereMesh.getMesh(3); - S32 numPoly = sphereMesh->numPoly; - mSpherePrimitiveCount = 0; - mSphereGeometry.set(GFX, numPoly * 3, GFXBufferTypeStatic); - mSphereGeometry.lock(); - S32 vertexIndex = 0; - - for (S32 i = 0; ipoly[i].pnt[0]; - mSphereGeometry[vertexIndex].color = ColorI::WHITE; - vertexIndex++; - - mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[1]; - mSphereGeometry[vertexIndex].color = ColorI::WHITE; - vertexIndex++; - - mSphereGeometry[vertexIndex].point = sphereMesh->poly[i].pnt[2]; - mSphereGeometry[vertexIndex].color = ColorI::WHITE; - vertexIndex++; - } - mSphereGeometry.unlock(); - } - - outNumPrimitives = mSpherePrimitiveCount; - outPrimitives = NULL; // For now - return mSphereGeometry; -} - -void RenderProbeMgr::addSkylightProbe(ProbeRenderInst *probeInfo) -{ - probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer); - - if (!mSkylightMaterial) - mSkylightMaterial = _getSkylightMaterial(); -} - -void RenderProbeMgr::addSphereReflectionProbe(ProbeRenderInst *probeInfo) -{ - probeInfo->vertBuffer = getSphereMesh(probeInfo->numPrims, probeInfo->primBuffer); - - if (!mReflectProbeMaterial) - mReflectProbeMaterial = _getReflectProbeMaterial(); -} - -void RenderProbeMgr::addConvexReflectionProbe(ProbeRenderInst *probeInfo) -{ - static const Point3F cubePoints[8] = - { - Point3F(1, -1, -1), Point3F(1, -1, 1), Point3F(1, 1, -1), Point3F(1, 1, 1), - Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1) - }; - - /*static const Point3F cubeNormals[6] = - { - Point3F(1, 0, 0), Point3F(-1, 0, 0), Point3F(0, 1, 0), - Point3F(0, -1, 0), Point3F(0, 0, 1), Point3F(0, 0, -1) - };*/ - - /*static const Point2F cubeTexCoords[4] = - { - Point2F(0, 0), Point2F(0, -1), - Point2F(1, 0), Point2F(1, -1) - };*/ - - static const U32 cubeFaces[36][3] = - { - { 3, 0, 3 },{ 0, 0, 0 },{ 1, 0, 1 }, - { 2, 0, 2 },{ 0, 0, 0 },{ 3, 0, 3 }, - { 7, 1, 1 },{ 4, 1, 2 },{ 5, 1, 0 }, - { 6, 1, 3 },{ 4, 1, 2 },{ 7, 1, 1 }, - { 3, 2, 1 },{ 5, 2, 2 },{ 2, 2, 0 }, - { 7, 2, 3 },{ 5, 2, 2 },{ 3, 2, 1 }, - { 1, 3, 3 },{ 4, 3, 0 },{ 6, 3, 1 }, - { 0, 3, 2 },{ 4, 3, 0 },{ 1, 3, 3 }, - { 3, 4, 3 },{ 6, 4, 0 },{ 7, 4, 1 }, - { 1, 4, 2 },{ 6, 4, 0 },{ 3, 4, 3 }, - { 2, 5, 1 },{ 4, 5, 2 },{ 0, 5, 0 }, - { 5, 5, 3 },{ 4, 5, 2 },{ 2, 5, 1 } - }; - - // Fill the vertex buffer - GFXVertexPC *pVert = NULL; - - probeInfo->numVerts = 36; - - probeInfo->vertBuffer.set(GFX, 36, GFXBufferTypeStatic); - pVert = probeInfo->vertBuffer.lock(); - - Point3F halfSize = Point3F(probeInfo->mRadius, probeInfo->mRadius, probeInfo->mRadius); - - for (U32 i = 0; i < 36; i++) - { - const U32& vdx = cubeFaces[i][0]; - pVert[i].point = cubePoints[vdx] * halfSize; - } - - probeInfo->vertBuffer.unlock(); - - // Fill the primitive buffer - U16 *pIdx = NULL; - - probeInfo->primBuffer.set(GFX, 36, 12, GFXBufferTypeStatic); - - probeInfo->primBuffer.lock(&pIdx); - - for (U16 i = 0; i < 36; i++) - pIdx[i] = i; - - probeInfo->primBuffer.unlock(); - - probeInfo->numPrims = 12; - - if (!mReflectProbeMaterial) - mReflectProbeMaterial = _getReflectProbeMaterial(); - // - - // mReflectProbeBin.push_back(pEntry); -} - void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state) { PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters); @@ -298,18 +166,22 @@ void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state) //inverseViewMatrix = MatrixF::Identity; // Parameters calculated, assign them to the materials - if (mSkylightMaterial != nullptr && mSkylightMaterial->matInstance != nullptr) + ProbeManager::SkylightMaterialInfo* skylightMat = PROBEMGR->getSkylightMaterial(); + + if (skylightMat != nullptr && skylightMat->matInstance != nullptr) { - mSkylightMaterial->setViewParameters(frustum.getNearDist(), + skylightMat->setViewParameters(frustum.getNearDist(), frustum.getFarDist(), frustum.getPosition(), farPlane, vsFarPlane, inverseViewMatrix); } - if (mReflectProbeMaterial != nullptr && mReflectProbeMaterial->matInstance != nullptr) + ProbeManager::ReflectProbeMaterialInfo* reflProbeMat = PROBEMGR->getReflectProbeMaterial(); + + if (reflProbeMat != nullptr && reflProbeMat->matInstance != nullptr) { - mReflectProbeMaterial->setViewParameters(frustum.getNearDist(), + reflProbeMat->setViewParameters(frustum.getNearDist(), frustum.getFarDist(), frustum.getPosition(), farPlane, @@ -325,7 +197,10 @@ void RenderProbeMgr::render( SceneRenderState *state ) PROFILE_SCOPE(RenderProbeMgr_render); // Early out if nothing to draw. - if(!mElementList.size()) + if (!ProbeRenderInst::all.size()) + return; + + if (!ProbeManager::smRenderReflectionProbes) return; GFXTransformSaver saver; @@ -345,6 +220,9 @@ void RenderProbeMgr::render( SceneRenderState *state ) if (probeLightingTargetRef.isNull()) return; + //Do a quick pass to update our probes if they're dirty + PROBEMGR->updateDirtyProbes(); + probeLightingTargetRef->attachTexture(GFXTextureTarget::Color0, diffuseLightingTarget->getTexture()); probeLightingTargetRef->attachTexture(GFXTextureTarget::Color1, specularLightingTarget->getTexture()); @@ -369,22 +247,28 @@ void RenderProbeMgr::render( SceneRenderState *state ) _setupPerFrameParameters(state); //Order the probes by size, biggest to smallest - dQsort(mElementList.address(), mElementList.size(), sizeof(const MainSortElem), AscendingReflectProbeInfluence); + //dQsort(mElementList.address(), mElementList.size(), sizeof(const MainSortElem), AscendingReflectProbeInfluence); //Specular PROFILE_START(RenderProbeManager_ReflectProbeRender); - for (U32 i = 0; igetSkylightMaterial(); + ProbeManager::ReflectProbeMaterialInfo* reflProbeMat = PROBEMGR->getReflectProbeMaterial(); + + for (U32 i = 0; i < ProbeRenderInst::all.size(); i++) { - ProbeRenderInst *curEntry = static_cast(mElementList[i].inst); + ProbeRenderInst* curEntry = ProbeRenderInst::all[i]; + + if (!curEntry->mIsEnabled) + continue; if (curEntry->numPrims == 0) continue; - if (curEntry->mIsSkylight && (!mSkylightMaterial || !mSkylightMaterial->matInstance)) + if (curEntry->mIsSkylight && (!skylightMat || !skylightMat->matInstance)) continue; - if (!curEntry->mIsSkylight && (!mReflectProbeMaterial || !mReflectProbeMaterial->matInstance)) + if (!curEntry->mIsSkylight && (!reflProbeMat || !reflProbeMat->matInstance)) break; //Setup @@ -392,7 +276,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) if (!curEntry->mIsSkylight) { - if (curEntry->mProbeShapeType == ProbeInfo::Sphere) + if (curEntry->mProbeShapeType == ProbeRenderInst::Sphere) probeTrans.scale(curEntry->mRadius * 1.01f); } else @@ -403,9 +287,9 @@ void RenderProbeMgr::render( SceneRenderState *state ) sgData.objTrans = &probeTrans; if(curEntry->mIsSkylight) - mSkylightMaterial->setSkylightParameters(curEntry, state, worldToCameraXfm); + skylightMat->setProbeParameters(curEntry, state, worldToCameraXfm); else - mReflectProbeMaterial->setProbeParameters(curEntry, state, worldToCameraXfm); + reflProbeMat->setProbeParameters(curEntry, state, worldToCameraXfm); // Set geometry GFX->setVertexBuffer(curEntry->vertBuffer); @@ -413,24 +297,24 @@ void RenderProbeMgr::render( SceneRenderState *state ) if (curEntry->mIsSkylight) { - while (mSkylightMaterial->matInstance->setupPass(state, sgData)) + while (skylightMat->matInstance->setupPass(state, sgData)) { // Set transforms matrixSet.setWorld(*sgData.objTrans); - mSkylightMaterial->matInstance->setTransforms(matrixSet, state); - mSkylightMaterial->matInstance->setSceneInfo(state, sgData); + skylightMat->matInstance->setTransforms(matrixSet, state); + skylightMat->matInstance->setSceneInfo(state, sgData); GFX->drawPrimitive(GFXTriangleList, 0, curEntry->numPrims); } } else { - while (mReflectProbeMaterial->matInstance->setupPass(state, sgData)) + while (reflProbeMat->matInstance->setupPass(state, sgData)) { // Set transforms matrixSet.setWorld(*sgData.objTrans); - mReflectProbeMaterial->matInstance->setTransforms(matrixSet, state); - mReflectProbeMaterial->matInstance->setSceneInfo(state, sgData); + reflProbeMat->matInstance->setTransforms(matrixSet, state); + reflProbeMat->matInstance->setSceneInfo(state, sgData); GFX->drawPrimitive(GFXTriangleList, 0, curEntry->numPrims); } @@ -440,7 +324,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) probeLightingTargetRef->resolve(); GFX->popActiveRenderTarget(); - PROBEMGR->unregisterAllProbes(); + //PROBEMGR->unregisterAllProbes(); PROFILE_END(); GFX->setVertexBuffer(NULL); @@ -448,514 +332,4 @@ void RenderProbeMgr::render( SceneRenderState *state ) // Fire off a signal to let others know that light-bin rendering is ending now //getRenderSignal().trigger(state, this); -} - -// -RenderProbeMgr::ReflectProbeMaterialInfo::ReflectProbeMaterialInfo(const String &matName, - const GFXVertexFormat *vertexFormat) - : matInstance(NULL), - zNearFarInvNearFar(NULL), - farPlane(NULL), - vsFarPlane(NULL), - negFarPlaneDotEye(NULL), - probeWSPos(NULL), - attenuation(NULL), - radius(NULL), - invViewMat(NULL) -{ - Material *mat = MATMGR->getMaterialDefinitionByName(matName); - if (!mat) - return; - - matInstance = new ReflectProbeMatInstance(*mat); - - const Vector ¯os = Vector(); - - for (U32 i = 0; i < macros.size(); i++) - matInstance->addShaderMacro(macros[i].name, macros[i].value); - - matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat); - - attenuation = matInstance->getMaterialParameterHandle("$attenuation"); - radius = matInstance->getMaterialParameterHandle("$radius"); - probeLSPos = matInstance->getMaterialParameterHandle("$probeLSPos"); - probeWSPos = matInstance->getMaterialParameterHandle("$probeWSPos"); - farPlane = matInstance->getMaterialParameterHandle("$farPlane"); - vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane"); - negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye"); - zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar"); - - invViewMat = matInstance->getMaterialParameterHandle("$invViewMat"); - - useCubemap = matInstance->getMaterialParameterHandle("$useCubemap"); - - cubemap = matInstance->getMaterialParameterHandle("$cubeMap"); - cubeMips = matInstance->getMaterialParameterHandle("$cubeMips"); - - eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld"); - bbMin = matInstance->getMaterialParameterHandle("$bbMin"); - bbMax = matInstance->getMaterialParameterHandle("$bbMax"); - - useSphereMode = matInstance->getMaterialParameterHandle("$useSphereMode"); - - for(U32 i=0; i < 9; i++) - shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d",i)); - - for (U32 i = 0; i < 5; i++) - shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i)); -} - -RenderProbeMgr::ReflectProbeMaterialInfo::~ReflectProbeMaterialInfo() -{ - SAFE_DELETE(matInstance); -} - -void RenderProbeMgr::ReflectProbeMaterialInfo::setViewParameters(const F32 _zNear, - const F32 _zFar, - const Point3F &_eyePos, - const PlaneF &_farPlane, - const PlaneF &_vsFarPlane, const MatrixF &_inverseViewMatrix) -{ - MaterialParameters *matParams = matInstance->getMaterialParameters(); - - matParams->setSafe(farPlane, *((const Point4F *)&_farPlane)); - - matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane)); - - if (negFarPlaneDotEye->isValid()) - { - // -dot( farPlane, eyePos ) - const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d); - matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal); - } - - matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar)); - - matParams->setSafe(invViewMat, _inverseViewMatrix); - - Point4F frPlane = *((const Point4F *)&_farPlane); - Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane); - Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar); - const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d); -} - -void RenderProbeMgr::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly) -{ - //Set up the params - MaterialParameters *matParams = matInstance->getMaterialParameters(); - - matParams->setSafe(radius, probeInfo->mRadius); - - Point3F probePos = probeInfo->getPosition() + probeInfo->mProbePosOffset; - //worldViewOnly.mulP(probeInfo->getPosition(), &probePos); - matParams->setSafe(probeWSPos, probePos); - - worldViewOnly.mulP(probeInfo->getPosition(), &probePos); - matParams->setSafe(probeLSPos, probePos); - - // Get the attenuation falloff ratio and normalize it. - Point3F attenRatio = Point3F(0.0f, 1.0f, 1.0f); - F32 total = attenRatio.x + attenRatio.y + attenRatio.z; - if (total > 0.0f) - attenRatio /= total; - - F32 radius = probeInfo->mRadius; - - Point2F attenParams((1.0f / radius) * attenRatio.y, - (1.0f / (radius * radius)) * attenRatio.z); - - matParams->setSafe(attenuation, attenParams); - - NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred"); - - GFXTextureObject *deferredTexObject = deferredTexTarget->getTexture(); - if (!deferredTexObject) return; - - GFX->setTexture(0, deferredTexObject); - - NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo"); - - GFXTextureObject *matInfoTexObject = matInfoTexTarget->getTexture(); - if (!matInfoTexObject) return; - - GFX->setTexture(1, matInfoTexObject); - - if (probeInfo->mCubemap && !probeInfo->mCubemap->isNull()) - { - GFX->setCubeTexture(2, probeInfo->mCubemap->getPointer()); - } - else - { - GFX->setCubeTexture(2, NULL); - } - - if (probeInfo->mIrradianceCubemap && !probeInfo->mIrradianceCubemap->isNull()) - { - GFX->setCubeTexture(3, probeInfo->mIrradianceCubemap->getPointer()); - } - else - { - GFX->setCubeTexture(3, NULL); - } - - if (probeInfo->mBRDFTexture && !probeInfo->mBRDFTexture->isNull()) - { - GFX->setTexture(4, probeInfo->mBRDFTexture->getPointer()); - } - else - { - GFX->setTexture(4, NULL); - } - - if(probeInfo->mCubemap->isValid()) - matParams->setSafe(cubeMips, mPow(probeInfo->mCubemap->getPointer()->getMipMapLevels(),2.0f)); - else - matParams->setSafe(cubeMips, F32(0.0)); - - matParams->setSafe(eyePosWorld, renderState->getCameraPosition()); - matParams->setSafe(bbMin, probeInfo->mBounds.minExtents); - matParams->setSafe(bbMax, probeInfo->mBounds.maxExtents); - - matParams->setSafe(useSphereMode, probeInfo->mProbeShapeType == ProbeInfo::Sphere ? 1.0f : 0.0f); - - //SH Terms - //static AlignedArray shTermsArray(9, sizeof(Point3F)); - //dMemset(shTermsArray.getBuffer(), 0, shTermsArray.getBufferSize()); - - for (U32 i = 0; i < 9; i++) - { - matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]); - } - - for (U32 i = 0; i < 5; i++) - { - matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]); - } -} - - -bool ReflectProbeMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat) -{ - bool success = Parent::init(features, vertexFormat); - - // If the initialization failed don't continue. - if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0) - return false; - return true; -} - -bool ReflectProbeMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData) -{ - // Go no further if the material failed to initialize properly. - if (!mProcessedMaterial || - mProcessedMaterial->getNumPasses() == 0) - return false; - - bool bRetVal = Parent::setupPass(state, sgData);; - - AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes"); - const RenderPassData *rpd = mProcessedMaterial->getPass(0); - AssertFatal(rpd, "No render pass data!"); - AssertFatal(rpd->mRenderStates[0], "No render state 0!"); - - if (!mProjectionState) - { - GFXStateBlockDesc desc; - desc.setZReadWrite(false); - desc.zWriteEnable = false; - desc.setCullMode(GFXCullNone); - desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendOne); - mProjectionState = GFX->createStateBlock(desc); - } - // Now override stateblock with our own - GFX->setStateBlock(mProjectionState); - - return bRetVal; -} - -RenderProbeMgr::ReflectProbeMaterialInfo* RenderProbeMgr::_getReflectProbeMaterial() -{ - PROFILE_SCOPE(AdvancedLightBinManager_getReflectProbeMaterial); - - //ReflectProbeMaterialInfo *info = NULL; - - if (!mReflectProbeMaterial) - - // Now create the material info object. - mReflectProbeMaterial = new ReflectProbeMaterialInfo("ReflectionProbeMaterial", - getGFXVertexFormat()); - - return mReflectProbeMaterial; -} - -// -RenderProbeMgr::SkylightMaterialInfo::SkylightMaterialInfo(const String &matName, - const GFXVertexFormat *vertexFormat) - : matInstance(NULL), - zNearFarInvNearFar(NULL), - farPlane(NULL), - vsFarPlane(NULL), - negFarPlaneDotEye(NULL), - invViewMat(NULL) -{ - Material *mat = MATMGR->getMaterialDefinitionByName(matName); - if (!mat) - return; - - matInstance = new SkylightMatInstance(*mat); - - const Vector ¯os = Vector(); - - for (U32 i = 0; i < macros.size(); i++) - matInstance->addShaderMacro(macros[i].name, macros[i].value); - - matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat); - - farPlane = matInstance->getMaterialParameterHandle("$farPlane"); - vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane"); - negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye"); - zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar"); - - invViewMat = matInstance->getMaterialParameterHandle("$invViewMat"); - - useCubemap = matInstance->getMaterialParameterHandle("$useCubemap"); - cubemap = matInstance->getMaterialParameterHandle("$cubeMap"); - - eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld"); - - for (U32 i = 0; i < 9; i++) - shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i)); - - for (U32 i = 0; i < 5; i++) - shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i)); -} - -RenderProbeMgr::SkylightMaterialInfo::~SkylightMaterialInfo() -{ - SAFE_DELETE(matInstance); -} - -void RenderProbeMgr::SkylightMaterialInfo::setViewParameters(const F32 _zNear, - const F32 _zFar, - const Point3F &_eyePos, - const PlaneF &_farPlane, - const PlaneF &_vsFarPlane, const MatrixF &_inverseViewMatrix) -{ - MaterialParameters *matParams = matInstance->getMaterialParameters(); - - matParams->setSafe(farPlane, *((const Point4F *)&_farPlane)); - - matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane)); - - if (negFarPlaneDotEye->isValid()) - { - // -dot( farPlane, eyePos ) - const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d); - matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal); - } - - matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar)); - - matParams->setSafe(invViewMat, _inverseViewMatrix); - - Point4F frPlane = *((const Point4F *)&_farPlane); - Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane); - Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar); - const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d); -} - -void RenderProbeMgr::SkylightMaterialInfo::setSkylightParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly) -{ - //Set up the params - MaterialParameters *matParams = matInstance->getMaterialParameters(); - - NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred"); - - GFXTextureObject *deferredTexObject = deferredTexTarget->getTexture(); - if (!deferredTexObject) return; - - GFX->setTexture(0, deferredTexObject); - - NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo"); - - GFXTextureObject *matInfoTexObject = matInfoTexTarget->getTexture(); - if (!matInfoTexObject) return; - - GFX->setTexture(1, matInfoTexObject); - - if (probeInfo->mCubemap && !probeInfo->mCubemap->isNull()) - { - GFX->setCubeTexture(2, probeInfo->mCubemap->getPointer()); - } - else - { - GFX->setCubeTexture(2, NULL); - } - - if (probeInfo->mIrradianceCubemap && !probeInfo->mIrradianceCubemap->isNull()) - { - GFX->setCubeTexture(3, probeInfo->mIrradianceCubemap->getPointer()); - } - else - { - GFX->setCubeTexture(3, NULL); - } - - if (probeInfo->mBRDFTexture && !probeInfo->mBRDFTexture->isNull()) - { - GFX->setTexture(4, probeInfo->mBRDFTexture->getPointer()); - } - else - { - GFX->setTexture(4, NULL); - } - - matParams->setSafe(eyePosWorld, renderState->getCameraPosition()); - - for (U32 i = 0; i < 9; i++) - { - matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]); - } - - for (U32 i = 0; i < 5; i++) - { - matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]); - } -} - - -bool SkylightMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat) -{ - bool success = Parent::init(features, vertexFormat); - - // If the initialization failed don't continue. - if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0) - return false; - - return true; -} - -bool SkylightMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData) -{ - // Go no further if the material failed to initialize properly. - if (!mProcessedMaterial || - mProcessedMaterial->getNumPasses() == 0) - return false; - - bool bRetVal = Parent::setupPass(state, sgData);; - - AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes"); - const RenderPassData *rpd = mProcessedMaterial->getPass(0); - AssertFatal(rpd, "No render pass data!"); - AssertFatal(rpd->mRenderStates[0], "No render state 0!"); - - if (!mProjectionState) - { - GFXStateBlockDesc desc; - desc.setZReadWrite(false); - desc.zWriteEnable = false; - desc.setCullMode(GFXCullNone); - desc.setBlend(true, GFXBlendOne, GFXBlendOne); - mProjectionState = GFX->createStateBlock(desc); - } - // Now override stateblock with our own - GFX->setStateBlock(mProjectionState); - - return bRetVal; -} - -RenderProbeMgr::SkylightMaterialInfo* RenderProbeMgr::_getSkylightMaterial() -{ - PROFILE_SCOPE(AdvancedLightBinManager_getSkylightMaterial); - - //ReflectProbeMaterialInfo *info = NULL; - - if (!mSkylightMaterial) - - // Now create the material info object. - mSkylightMaterial = new SkylightMaterialInfo("SklyightMaterial", - getGFXVertexFormat()); - - return mSkylightMaterial; -} - -// -// -ProbeRenderInst::ProbeRenderInst() - : mTransform(true), - mAmbient(0.0f, 0.0f, 0.0f, 1.0f), - mPriority(1.0f), - mScore(0.0f), - mDebugRender(false), - mCubemap(NULL), - mRadius(1.0f), - mIntensity(1.0f) -{ -} - -ProbeRenderInst::~ProbeRenderInst() -{ - SAFE_DELETE(mCubemap); -} - -void ProbeRenderInst::set(const ProbeRenderInst *probeInfo) -{ - mTransform = probeInfo->mTransform; - mAmbient = probeInfo->mAmbient; - mCubemap = probeInfo->mCubemap; - mIrradianceCubemap = probeInfo->mIrradianceCubemap; - mBRDFTexture = probeInfo->mBRDFTexture; - mRadius = probeInfo->mRadius; - mIntensity = probeInfo->mIntensity; - mProbeShapeType = probeInfo->mProbeShapeType; - numPrims = probeInfo->numPrims; - numVerts = probeInfo->numVerts; - numIndicesForPoly = probeInfo->numIndicesForPoly; - mBounds = probeInfo->mBounds; - mScore = probeInfo->mScore; - mIsSkylight = probeInfo->mIsSkylight; - - for (U32 i = 0; i < 9; i++) - { - mSHTerms[i] = probeInfo->mSHTerms[i]; - } - - for (U32 i = 0; i < 5; i++) - { - mSHConstants[i] = probeInfo->mSHConstants[i]; - } -} - -void ProbeRenderInst::set(const ProbeInfo *probeInfo) -{ - mTransform = probeInfo->mTransform; - mAmbient = probeInfo->mAmbient; - mCubemap = probeInfo->mCubemap; - mIrradianceCubemap = probeInfo->mIrradianceCubemap; - mBRDFTexture = probeInfo->mBRDFTexture; - mRadius = probeInfo->mRadius; - mIntensity = probeInfo->mIntensity; - mProbeShapeType = probeInfo->mProbeShapeType; - numPrims = probeInfo->numPrims; - numVerts = probeInfo->numVerts; - numIndicesForPoly = probeInfo->numIndicesForPoly; - mBounds = probeInfo->mBounds; - mScore = probeInfo->mScore; - mIsSkylight = probeInfo->mIsSkylight; - - for (U32 i = 0; i < 9; i++) - { - mSHTerms[i] = probeInfo->mSHTerms[i]; - } - - for (U32 i = 0; i < 5; i++) - { - mSHConstants[i] = probeInfo->mSHConstants[i]; - } -} - -void ProbeRenderInst::getWorldToLightProj(MatrixF *outMatrix) const -{ - *outMatrix = getTransform(); - outMatrix->inverse(); -} +} \ No newline at end of file diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index 31fdddffe..205678ed5 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -38,38 +38,6 @@ #include "gfx/gfxVertexBuffer.h" #endif -class ReflectProbeMatInstance : public MatInstance -{ - typedef MatInstance Parent; -protected: - MaterialParameterHandle *mProbeParamsSC; - bool mInternalPass; - - GFXStateBlockRef mProjectionState; - -public: - ReflectProbeMatInstance(Material &mat) : Parent(mat), mProbeParamsSC(NULL), mInternalPass(false), mProjectionState(NULL){} - - virtual bool init(const FeatureSet &features, const GFXVertexFormat *vertexFormat); - virtual bool setupPass(SceneRenderState *state, const SceneData &sgData); -}; - -class SkylightMatInstance : public MatInstance -{ - typedef MatInstance Parent; -protected: - MaterialParameterHandle * mSkylightParamsSC; - bool mInternalPass; - - GFXStateBlockRef mProjectionState; - -public: - SkylightMatInstance(Material &mat) : Parent(mat), mSkylightParamsSC(NULL), mInternalPass(false), mProjectionState(NULL) {} - - virtual bool init(const FeatureSet &features, const GFXVertexFormat *vertexFormat); - virtual bool setupPass(SceneRenderState *state, const SceneData &sgData); -}; - //************************************************************************** // RenderObjectMgr //************************************************************************** @@ -80,112 +48,9 @@ public: typedef GFXVertexPNTT FarFrustumQuadVert; protected: - struct ReflectProbeMaterialInfo - { - ReflectProbeMatInstance *matInstance; - - // { zNear, zFar, 1/zNear, 1/zFar } - MaterialParameterHandle *zNearFarInvNearFar; - - // Far frustum plane (World Space) - MaterialParameterHandle *farPlane; - - // Far frustum plane (View Space) - MaterialParameterHandle *vsFarPlane; - - // -dot( farPlane, eyePos ) - MaterialParameterHandle *negFarPlaneDotEye; - - // Inverse View matrix - MaterialParameterHandle *invViewMat; - - // Light Parameters - MaterialParameterHandle *probeLSPos; - MaterialParameterHandle *probeWSPos; - MaterialParameterHandle *attenuation; - MaterialParameterHandle *radius; - - MaterialParameterHandle *useCubemap; - MaterialParameterHandle *cubemap; - MaterialParameterHandle *cubeMips; - - MaterialParameterHandle *eyePosWorld; - MaterialParameterHandle *bbMin; - MaterialParameterHandle *bbMax; - - MaterialParameterHandle *useSphereMode; - - MaterialParameterHandle *shTerms[9]; - MaterialParameterHandle *shConsts[5]; - - ReflectProbeMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat); - - virtual ~ReflectProbeMaterialInfo(); - - - void setViewParameters(const F32 zNear, - const F32 zFar, - const Point3F &eyePos, - const PlaneF &farPlane, - const PlaneF &_vsFarPlane, - const MatrixF &_inverseViewMatrix); - - void setProbeParameters(const ProbeRenderInst *probe, const SceneRenderState* renderState, const MatrixF &worldViewOnly); - }; - - struct SkylightMaterialInfo - { - SkylightMatInstance *matInstance; - - // { zNear, zFar, 1/zNear, 1/zFar } - MaterialParameterHandle *zNearFarInvNearFar; - - // Far frustum plane (World Space) - MaterialParameterHandle *farPlane; - - // Far frustum plane (View Space) - MaterialParameterHandle *vsFarPlane; - - // -dot( farPlane, eyePos ) - MaterialParameterHandle *negFarPlaneDotEye; - - // Inverse View matrix - MaterialParameterHandle *invViewMat; - - MaterialParameterHandle *useCubemap; - MaterialParameterHandle *cubemap; - - MaterialParameterHandle *eyePosWorld; - - MaterialParameterHandle *shTerms[9]; - MaterialParameterHandle *shConsts[5]; - - SkylightMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat); - - virtual ~SkylightMaterialInfo(); - - - void setViewParameters(const F32 zNear, - const F32 zFar, - const Point3F &eyePos, - const PlaneF &farPlane, - const PlaneF &_vsFarPlane, - const MatrixF &_inverseViewMatrix); - - void setSkylightParameters(const ProbeRenderInst *probe, const SceneRenderState* renderState, const MatrixF &worldViewOnly); - }; GFXVertexBufferHandle mFarFrustumQuadVerts; - GFXVertexBufferHandle getSphereMesh(U32 &outNumPrimitives, GFXPrimitiveBufferHandle &outPrimitives); - - // Convex geometry for lights - GFXVertexBufferHandle mSphereGeometry; - - GFXPrimitiveBufferHandle mSphereIndices; - - U32 mSpherePrimitiveCount; - public: RenderProbeMgr(); RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder); @@ -198,17 +63,6 @@ public: // ConsoleObject static void initPersistFields(); DECLARE_CONOBJECT(RenderProbeMgr); - - ReflectProbeMaterialInfo* mReflectProbeMaterial; - ReflectProbeMaterialInfo* _getReflectProbeMaterial(); - - SkylightMaterialInfo* mSkylightMaterial; - SkylightMaterialInfo* _getSkylightMaterial(); - - // Add a reflection probe to the bin - void addSkylightProbe(ProbeRenderInst *probeInfo); - void addSphereReflectionProbe(ProbeRenderInst *probeInfo); - void addConvexReflectionProbe(ProbeRenderInst *probeInfo); }; #endif // RENDER_PROBE_MGR_H \ No newline at end of file diff --git a/Templates/Full/game/art/skies/hdrSky/hdrSky.dds b/Templates/Full/game/art/skies/hdrSky/hdrSky.dds new file mode 100644 index 000000000..6a6439de4 Binary files /dev/null and b/Templates/Full/game/art/skies/hdrSky/hdrSky.dds differ diff --git a/Templates/Full/game/art/skies/hdrSky/materials.cs b/Templates/Full/game/art/skies/hdrSky/materials.cs new file mode 100644 index 000000000..1a96a1dc9 --- /dev/null +++ b/Templates/Full/game/art/skies/hdrSky/materials.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton CubemapData( HdrSkyCubemap ) +{ + cubeMap = "./hdrSky.dds"; +}; + +singleton Material( HdrSky ) +{ + cubemap = HdrSkyCubemap; + materialTag0 = "Skies"; +}; diff --git a/Templates/Full/game/art/skies/skyNightHDR/materials.cs b/Templates/Full/game/art/skies/skyNightHDR/materials.cs new file mode 100644 index 000000000..66f32c766 --- /dev/null +++ b/Templates/Full/game/art/skies/skyNightHDR/materials.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton CubemapData( SkyNightHDRCubemap ) +{ + cubeMap = "./sky_night_hdr.dds"; +}; + +singleton Material( SkyNightHDR ) +{ + cubemap = SkyNightHDRCubemap; + materialTag0 = "Skies"; +}; diff --git a/Templates/Full/game/art/skies/skyNightHDR/sky_night_hdr.dds b/Templates/Full/game/art/skies/skyNightHDR/sky_night_hdr.dds new file mode 100644 index 000000000..4c83f160d Binary files /dev/null and b/Templates/Full/game/art/skies/skyNightHDR/sky_night_hdr.dds differ diff --git a/Templates/Full/game/art/skies/sky_day_hdr/materials.cs b/Templates/Full/game/art/skies/sky_day_hdr/materials.cs new file mode 100644 index 000000000..f4fe99ca0 --- /dev/null +++ b/Templates/Full/game/art/skies/sky_day_hdr/materials.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton CubemapData( sky_day_hdr_cubemap ) +{ + cubeMap = "./sky_day_hdr.dds"; +}; + +singleton Material( sky_day_hdr ) +{ + cubemap = sky_day_hdr_cubemap; + materialTag0 = "Skies"; +}; diff --git a/Templates/Full/game/art/skies/sky_day_hdr/sky_day_hdr.dds b/Templates/Full/game/art/skies/sky_day_hdr/sky_day_hdr.dds new file mode 100644 index 000000000..33726ec42 Binary files /dev/null and b/Templates/Full/game/art/skies/sky_day_hdr/sky_day_hdr.dds differ diff --git a/Templates/Full/game/core/art/grids/materials.cs b/Templates/Full/game/core/art/grids/materials.cs index c573019ce..99078ddfa 100644 --- a/Templates/Full/game/core/art/grids/materials.cs +++ b/Templates/Full/game/core/art/grids/materials.cs @@ -32,6 +32,12 @@ singleton Material( Grid512_Blue_Mat ) mapTo = "Grid512_Blue_Mat"; diffuseMap[0] = "512_blue"; materialTag0 = "TestMaterial"; + smoothness[0] = "1"; + metalness[0] = "0.803922"; + translucent = "1"; + translucentBlendOp = "Add"; + diffuseColor[0] = "1 1 1 1"; + effectColor[1] = "InvisibleBlack"; }; singleton Material( Grid512_ForestGreen_Mat ) diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/reflectionProbeP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/reflectionProbeP.glsl index df5659c50..7ad77ecae 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/reflectionProbeP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/reflectionProbeP.glsl @@ -119,18 +119,18 @@ float defineSphereSpaceInfluence(vec3 centroidPosVS, float rad, vec2 atten, vec3 float defineBoxSpaceInfluence(vec3 surfPosWS, vec3 probePos, float rad, vec2 atten) //atten currently unused { - vec3 boxMin = probePos-(vec3(0.5,0.5,0.5)*rad); - vec3 boxMax = probePos+(vec3(0.5,0.5,0.5)*rad); - //Try to clip anything that falls outside our box as well - //TODO: Make it support rotated boxes as well - if(surfPosWS.x > boxMax.x || surfPosWS.y > boxMax.y || surfPosWS.z > boxMax.z || - surfPosWS.x < boxMin.x || surfPosWS.y < boxMin.y || surfPosWS.z < boxMin.z) - return -1; - - float blendVal = 1; - //vec3 atten = min(boxMax-surfPosWS,surfPosWS-boxMin); - //blendVal = min(min(atten.x,atten.y),atten.z); - return blendVal; + vec3 surfPosLS = mul( worldToObj, vec4(surfPosWS,1.0)).xyz; + + vec3 lsBoxMin = mul(worldToObj, vec4(boxMin,1)).xyz; + vec3 lsBoxMax = mul(worldToObj, vec4(boxMax,1)).xyz; + + float boxOuterRange = length(lsBoxMax - lsBoxMin); + float boxInnerRange = boxOuterRange / 3.5; + + vec3 localDir = vec3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z)); + localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange); + + return max(localDir.x, max(localDir.y, localDir.z)); } float defineDepthInfluence(vec3 probePosWS, vec3 surfPosWS, samplerCube radianceCube) @@ -190,7 +190,18 @@ void main() } else { - blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, radius*2, attenuation); + if(worldPos.x > bbMax.x || worldPos.y > bbMax.y || worldPos.z > bbMax.z || + worldPos.x < bbMin.x || worldPos.y < bbMin.y || worldPos.z < bbMin.z) + { + OUT_col = vec4(0.0); + OUT_col1 = vec4(0.0); + return; + } + + blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, bbMin, bbMax, attenuation); + + //flip it around + blendVal *= -1; } if (blendVal<0) { diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl index a034f5133..eecc71500 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl @@ -125,24 +125,20 @@ float defineSphereSpaceInfluence(float3 centroidPosVS, float rad, float2 atten, return saturate( nDotL * attn ); } -float defineBoxSpaceInfluence(float3 surfPosWS, float3 probePos, float rad, float2 atten) //atten currently unused +float defineBoxSpaceInfluence(float3 surfPosWS, float3 probePos, float3 boxMin, float3 boxMax, float2 atten) { - float3 boxMin = probePos-(float3(0.5,0.5,0.5)*rad); - float3 boxMax = probePos+(float3(0.5,0.5,0.5)*rad); - - //rotated boxes - float3 surfPosLS = mul( worldToObj, float4(surfPosWS,1.0)).xyz; - - //Try to clip anything that falls outside our box as well - //was surfPosWS - if(surfPosLS.x > boxMax.x || surfPosLS.y > boxMax.y || surfPosLS.z > boxMax.z || - surfPosLS.x < boxMin.x || surfPosLS.y < boxMin.y || surfPosLS.z < boxMin.z) - return -1; - - float blendVal = 1; - //float3 atten = min(boxMax-surfPosWS,surfPosWS-boxMin); - //blendVal = min(min(atten.x,atten.y),atten.z); - return blendVal; + float3 surfPosLS = mul( worldToObj, float4(surfPosWS,1.0)).xyz; + + float3 lsBoxMin = mul(worldToObj, float4(boxMin,1)).xyz; + float3 lsBoxMax = mul(worldToObj, float4(boxMax,1)).xyz; + + float boxOuterRange = length(lsBoxMax - lsBoxMin); + float boxInnerRange = boxOuterRange / 3.5; + + float3 localDir = float3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z)); + localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange); + + return max(localDir.x, max(localDir.y, localDir.z)); } float defineDepthInfluence(float3 probePosWS, float3 surfPosWS, TORQUE_SAMPLERCUBE(radianceCube)) @@ -196,7 +192,15 @@ PS_OUTPUT main( ConvexConnectP IN ) } else { - blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, radius*2, attenuation); + if(worldPos.x > bbMax.x || worldPos.y > bbMax.y || worldPos.z > bbMax.z || + worldPos.x < bbMin.x || worldPos.y < bbMin.y || worldPos.z < bbMin.z) + clip(-1); + + blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, bbMin, bbMax, attenuation); + + //flip it around + blendVal *= -1; + //blendVal = defineBoxSpaceInfluence(worldPos, probeWSPos, radius*2, attenuation); } clip(blendVal);