diff --git a/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp b/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp index dd4e0980e..543ad0902 100644 --- a/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp +++ b/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp @@ -91,6 +91,8 @@ void BoxEnvironmentProbe::initPersistFields() { // SceneObject already handles exposing the transform Parent::initPersistFields(); + + removeField("radius"); } void BoxEnvironmentProbe::inspectPostApply() @@ -154,7 +156,7 @@ void BoxEnvironmentProbe::updateProbeParams() mProbeInfo->mProbeShapeType = ProbeRenderInst::Box; } -void BoxEnvironmentProbe::prepRenderImage(SceneRenderState *state) +/*void BoxEnvironmentProbe::prepRenderImage(SceneRenderState *state) { if (!mEnabled || !ReflectionProbe::smRenderPreviewProbes) return; @@ -223,7 +225,7 @@ void BoxEnvironmentProbe::prepRenderImage(SceneRenderState *state) ri->type = RenderPassManager::RIT_Editor; state->getRenderPass()->addInst(ri); } -} +}*/ void BoxEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat) { diff --git a/Engine/source/T3D/lighting/boxEnvironmentProbe.h b/Engine/source/T3D/lighting/boxEnvironmentProbe.h index 742472f97..d43c2cd8a 100644 --- a/Engine/source/T3D/lighting/boxEnvironmentProbe.h +++ b/Engine/source/T3D/lighting/boxEnvironmentProbe.h @@ -108,7 +108,7 @@ public: virtual void updateProbeParams(); // This is the function that allows this object to submit itself for rendering - void prepRenderImage(SceneRenderState *state); + //void prepRenderImage(SceneRenderState *state); void setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat); }; diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index 82c6a6ca4..fcc1864ea 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -106,6 +106,7 @@ ReflectionProbe::ReflectionProbe() mDirty = false; mRadius = 10; + mObjScale = Point3F::One * 10; mProbeRefScale = Point3F::One*10; mUseCubemap = false; @@ -159,17 +160,19 @@ void ReflectionProbe::initPersistFields() addGroup("Rendering"); addProtectedField("enabled", TypeBool, Offset(mEnabled, ReflectionProbe), &_setEnabled, &defaultProtectedGetFn, "Regenerate Voxel Grid"); - - addField("radius", TypeF32, Offset(mRadius, ReflectionProbe), "The name of the material used to render the mesh."); - - //addProtectedField("EditPosOffset", TypeBool, Offset(mEditPosOffset, ReflectionProbe), - // &_toggleEditPosOffset, &defaultProtectedGetFn, "Toggle Edit Pos Offset Mode", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors); endGroup("Rendering"); addGroup("Reflection"); + addProtectedField("radius", TypeF32, Offset(mRadius, ReflectionProbe), &_setRadius, &defaultProtectedGetFn, + "The name of the material used to render the mesh."); + + addProtectedField("EditPosOffset", TypeBool, Offset(mEditPosOffset, ReflectionProbe), + &_toggleEditPosOffset, &defaultProtectedGetFn, "Toggle Edit Pos Offset Mode", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors); + addField("refOffset", TypePoint3F, Offset(mProbeRefOffset, ReflectionProbe), ""); addField("refScale", TypePoint3F, Offset(mProbeRefScale, ReflectionProbe), ""); - addField("ReflectionMode", TypeReflectionModeEnum, Offset(mReflectionModeType, ReflectionProbe), + + addProtectedField("ReflectionMode", TypeReflectionModeEnum, Offset(mReflectionModeType, ReflectionProbe), &_setReflectionMode, &defaultProtectedGetFn, "The type of mesh data to use for collision queries."); addField("StaticCubemap", TypeCubemapName, Offset(mCubemapName, ReflectionProbe), "Cubemap used instead of reflection texture if fullReflect is off."); @@ -217,15 +220,7 @@ bool ReflectionProbe::_doBake(void *object, const char *index, const char *data) { ReflectionProbe* probe = reinterpret_cast< ReflectionProbe* >(object); - //if (probe->mDirty) - // probe->bake(probe->mReflectionPath, 256); - - ReflectionProbe *clientProbe = (ReflectionProbe*)probe->getClientObject(); - - if (clientProbe) - { - clientProbe->bake(); - } + probe->bake(); return false; } @@ -236,12 +231,39 @@ bool ReflectionProbe::_toggleEditPosOffset(void *object, const char *index, cons probe->mEditPosOffset = !probe->mEditPosOffset; - //if (probe->mDirty) - // probe->bake(probe->mReflectionPath, 256); - return false; } +bool ReflectionProbe::_setRadius(void *object, const char *index, const char *data) +{ + ReflectionProbe* probe = reinterpret_cast(object); + + if (probe->mProbeShapeType != ProbeRenderInst::Sphere) + return false; + + probe->mObjScale = Point3F(probe->mRadius, probe->mRadius, probe->mRadius); + + return true; +} + +bool ReflectionProbe::_setReflectionMode(void *object, const char *index, const char *data) +{ + ReflectionProbe* probe = reinterpret_cast(object); + + if (data == "Static Cubemap") + { + probe->mReflectionModeType = StaticCubemap; + } + else if (data == "Baked Cubemap") + { + //Clear our cubemap if we changed it to be baked, just for cleanliness + probe->mReflectionModeType = BakedCubemap; + probe->mCubemapName = ""; + } + + return true; +} + bool ReflectionProbe::onAdd() { if (!Parent::onAdd()) @@ -249,9 +271,8 @@ bool ReflectionProbe::onAdd() mEditPosOffset = false; - mObjBox.minExtents.set(-1, -1, -1); - mObjBox.maxExtents.set(1, 1, 1); - //mObjScale.set(mRadius/2, mRadius/2, mRadius/2); + mObjBox.minExtents.set(-0.5, -0.5, -0.5); + mObjBox.maxExtents.set(0.5, 0.5, 0.5); // Skip our transform... it just dirties mask bits. Parent::setTransform(mObjToWorld); @@ -266,7 +287,7 @@ bool ReflectionProbe::onAdd() if (!mPersistentId) mPersistentId = getOrCreatePersistentId(); - mProbeUniqueID = std::to_string(mPersistentId->getUUID().getHash()).c_str(); + mProbeUniqueID = String::ToString(mPersistentId->getUUID().getHash()); } // Refresh this object's material (if any) @@ -330,6 +351,49 @@ void ReflectionProbe::setTransform(const MatrixF & mat) setMaskBits(TransformMask); } +const MatrixF& ReflectionProbe::getTransform() const +{ + if (!mEditPosOffset) + return mObjToWorld; + else + { + MatrixF transformMat = MatrixF::Identity; + transformMat.setPosition(mProbeRefOffset); + + return transformMat; + } +} + +void ReflectionProbe::setScale(const VectorF &scale) +{ + if (!mEditPosOffset) + Parent::setScale(scale); + else + mProbeRefScale = scale; + + mDirty = true; + + // Dirty our network mask so that the new transform gets + // transmitted to the client object + setMaskBits(TransformMask); +} + +const VectorF& ReflectionProbe::getScale() const +{ + if (!mEditPosOffset) + return mObjScale; + else + return mProbeRefScale; +} + +bool ReflectionProbe::writeField(StringTableEntry fieldname, const char *value) +{ + if (fieldname == StringTable->insert("Bake") || fieldname == StringTable->insert("EditPosOffset")) + return false; + + return Parent::writeField(fieldname, value); +} + U32 ReflectionProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream) { // Allow the Parent to get a crack at writing its info @@ -338,8 +402,9 @@ U32 ReflectionProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream // Write our transform information if (stream->writeFlag(mask & TransformMask)) { - mathWrite(*stream, getTransform()); - mathWrite(*stream, getScale()); + stream->writeFlag(mEditPosOffset); + mathWrite(*stream, mObjToWorld); + mathWrite(*stream, mObjScale); mathWrite(*stream, mProbeRefOffset); mathWrite(*stream, mProbeRefScale); } @@ -385,10 +450,13 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) if (stream->readFlag()) // TransformMask { + mEditPosOffset = stream->readFlag(); mathRead(*stream, &mObjToWorld); mathRead(*stream, &mObjScale); - setTransform(mObjToWorld); + Parent::setTransform(mObjToWorld); + + resetWorldBox(); mathRead(*stream, &mProbeRefOffset); mathRead(*stream, &mProbeRefScale); @@ -491,7 +559,9 @@ void ReflectionProbe::updateProbeParams() mProbeInfo->mTransform = getWorldTransform(); mProbeInfo->mPosition = getPosition(); - mObjScale.set(mRadius, mRadius, mRadius); + + if(mProbeShapeType == ProbeRenderInst::Sphere) + mObjScale.set(mRadius, mRadius, mRadius); // Skip our transform... it just dirties mask bits. Parent::setTransform(mObjToWorld); @@ -783,19 +853,24 @@ void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri, // Base the sphere color on the light color. ColorI color = ColorI(255, 0, 255, 63); - const MatrixF worldToObjectXfm = getTransform(); + const MatrixF worldToObjectXfm = mObjToWorld; if (mProbeShapeType == ProbeRenderInst::Sphere) { draw->drawSphere(desc, mRadius, getPosition(), color); } else { - Box3F projCube(-Point3F(mRadius, mRadius, mRadius),Point3F(mRadius, mRadius, mRadius)); + Point3F tscl = worldToObjectXfm.getScale(); + + Box3F projCube(-mObjScale/2, mObjScale / 2); projCube.setCenter(getPosition()); draw->drawCube(desc, projCube, color, &worldToObjectXfm); } - Box3F refCube = Box3F(-mProbeRefScale/2, mProbeRefScale/2); - refCube.setCenter(getPosition()+mProbeRefOffset); + + Point3F renderPos = getRenderTransform().getPosition(); + + Box3F refCube = Box3F(-mProbeRefScale / 2, mProbeRefScale / 2); + refCube.setCenter(renderPos + mProbeRefOffset); color = ColorI(0, 255, 255, 63); draw->drawCube(desc, refCube, color, &worldToObjectXfm); } diff --git a/Engine/source/T3D/lighting/reflectionProbe.h b/Engine/source/T3D/lighting/reflectionProbe.h index bd9a1b99d..544b2ec81 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.h +++ b/Engine/source/T3D/lighting/reflectionProbe.h @@ -186,6 +186,8 @@ public: static bool _setEnabled(void *object, const char *index, const char *data); static bool _doBake(void *object, const char *index, const char *data); static bool _toggleEditPosOffset(void *object, const char *index, const char *data); + static bool _setRadius(void *object, const char *index, const char *data); + static bool _setReflectionMode(void *object, const char *index, const char *data); // Handle when we are added to the scene and removed from the scene bool onAdd(); @@ -194,7 +196,12 @@ public: virtual void handleDeleteAction(); // Override this so that we can dirty the network flag when it is called - void setTransform(const MatrixF &mat); + virtual void setTransform(const MatrixF &mat); + virtual const MatrixF& getTransform() const; + virtual void setScale(const VectorF &scale); + virtual const VectorF& getScale() const; + + virtual bool writeField(StringTableEntry fieldname, const char *value); // This function handles sending the relevant data from the server // object to the client object diff --git a/Engine/source/T3D/lighting/skylight.cpp b/Engine/source/T3D/lighting/skylight.cpp index 20564222e..a6450f234 100644 --- a/Engine/source/T3D/lighting/skylight.cpp +++ b/Engine/source/T3D/lighting/skylight.cpp @@ -91,6 +91,12 @@ void Skylight::initPersistFields() { // SceneObject already handles exposing the transform Parent::initPersistFields(); + + removeField("radius"); + removeField("scale"); + removeField("EditPosOffset"); + removeField("refOffset"); + removeField("refScale"); } void Skylight::inspectPostApply() @@ -151,7 +157,7 @@ void Skylight::updateProbeParams() { Parent::updateProbeParams(); - mProbeInfo->mProbeShapeType = ProbeRenderInst::Sphere; + mProbeInfo->mProbeShapeType = ProbeRenderInst::Skylight; mProbeInfo->setPosition(getPosition()); diff --git a/Engine/source/T3D/lighting/skylight.h b/Engine/source/T3D/lighting/skylight.h index f43c95821..5fbe02419 100644 --- a/Engine/source/T3D/lighting/skylight.h +++ b/Engine/source/T3D/lighting/skylight.h @@ -43,7 +43,6 @@ class BaseMatInstance; - //----------------------------------------------------------------------------- // This class implements a basic SceneObject that can exist in the world at a // 3D position and render itself. There are several valid ways to render an diff --git a/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp b/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp index c0588b31b..3c683d54d 100644 --- a/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp +++ b/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp @@ -91,6 +91,8 @@ void SphereEnvironmentProbe::initPersistFields() { // SceneObject already handles exposing the transform Parent::initPersistFields(); + + removeField("scale"); } void SphereEnvironmentProbe::inspectPostApply() diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 36a66698b..f27ad4a97 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -333,8 +333,8 @@ void RenderProbeMgr::_setupStaticParameters() if (!curEntry.mIrradianceCubemap->isInitialised()) continue; - if (curEntry.mIsSkylight) - continue; + //if (curEntry.mIsSkylight) + // continue; mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels(); @@ -350,7 +350,7 @@ void RenderProbeMgr::_setupStaticParameters() probeBBMinData[mEffectiveProbeCount] = Point4F(bbMin.x, bbMin.y, bbMin.z, 0); probeBBMaxData[mEffectiveProbeCount] = Point4F(bbMax.x, bbMax.y, bbMax.z, 0); - probeConfigData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, + probeConfigData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType, curEntry.mRadius, attenuation, 1); @@ -690,6 +690,8 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe *probe) { GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE); + bool serverObj = probe->isServerObject(); + Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!"); U32 startMSTime = Platform::getRealMilliseconds(); @@ -700,6 +702,9 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe *probe) ReflectionProbe *clientProbe = static_cast(probe->getClientObject()); + if (clientProbe == nullptr) + return; + String probePrefilterPath = clientProbe->getPrefilterMapPath(); String probeIrradPath = clientProbe->getIrradianceMapPath(); diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index 89c1df4be..4503d9309 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -88,8 +88,9 @@ struct ProbeRenderInst : public SystemInterface enum ProbeShapeType { - Sphere = 0, ///< Sphere shaped - Box = 1, ///< Box-based shape + Box = 0, ///< Sphere shaped + Sphere = 1, ///< Box-based shape + Skylight = 2 }; ProbeShapeType mProbeShapeType; diff --git a/Engine/source/scene/sceneObject.h b/Engine/source/scene/sceneObject.h index 34060acce..be0a7b745 100644 --- a/Engine/source/scene/sceneObject.h +++ b/Engine/source/scene/sceneObject.h @@ -484,7 +484,7 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce const MatrixF& getWorldTransform() const { return mWorldToObj; } /// Returns the scale of the object - const VectorF& getScale() const { return mObjScale; } + virtual const VectorF& getScale() const { return mObjScale; } /// Returns the bounding box for this object in local coordinates. const Box3F& getObjBox() const { return mObjBox; } diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl index 9fcbb4bfa..133f89103 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl @@ -53,6 +53,32 @@ uniform float4 probeContribColors[MAX_PROBES]; return posonbox - boxWSPos; }*/ +float3 iblSkylightDiffuse(Surface surface, ProbeData probe) +{ + float lod = surface.roughness*cubeMips; + float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.N, probe.probeIdx, lod).xyz; + + return color; +} + +float3 iblSkylightSpecular(Surface surface, ProbeData probe) +{ + // BRDF + float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV, 0.0, 0.0)).xy; + + // Radiance (Specular) +#if DEBUGVIZ_SPECCUBEMAP == 0 + float lod = surface.roughness*cubeMips; +#elif DEBUGVIZ_SPECCUBEMAP == 1 + float lod = 0; +#endif + + float3 color = TORQUE_TEXCUBEARRAYLOD(cubeMapAR, surface.N, probe.probeIdx, 0).xyz * (brdf.x + brdf.y); + //float3 color = float3(1, 1, 1); + + return color; +} + float3 iblBoxDiffuse( Surface surface, ProbeData probe) { @@ -126,10 +152,15 @@ float4 main( PFXVertToPix IN ) : SV_TARGET { blendVal[i] = defineBoxSpaceInfluence(surface, probes[i], IN.wsEyeRay); } - else + else if (probes[i].type == 1) //sphere { blendVal[i] = defineSphereSpaceInfluence(surface, probes[i], IN.wsEyeRay); } + else //skylight + { + // + blendVal[i] = 1; + } blendVal[i] = saturate(blendVal[i]); blendSum += blendVal[i]; @@ -202,9 +233,18 @@ float4 main( PFXVertToPix IN ) : SV_TARGET if (blendVal[i] == 0) continue; - irradiance += blendFactor[i]*iblBoxDiffuse(surface, probes[i]); - - specular += blendFactor[i]*F*iblBoxSpecular(surface, probes[i]); + if (probes[i].type == 2) //skylight + { + irradiance += blendFactor[i] * iblSkylightDiffuse(surface, probes[i]); + + specular += blendFactor[i] * F * iblSkylightSpecular(surface, probes[i]); + } + else + { + irradiance += blendFactor[i] * iblBoxDiffuse(surface, probes[i]); + + specular += blendFactor[i] * F*iblBoxSpecular(surface, probes[i]); + } } //final diffuse color @@ -217,7 +257,14 @@ float4 main( PFXVertToPix IN ) : SV_TARGET float3 cubeColor = float3(0, 0, 0); for (i = 0; i < numProbes; ++i) { - cubeColor += blendFactor[i] * iblBoxSpecular(surface, probes[i]); + //if (probes[i].type == 2) //skylight + //{ + cubeColor += blendFactor[i] * iblSkylightSpecular(surface, probes[i]); + /*} + else + { + cubeColor += blendFactor[i] * iblBoxSpecular(surface, probes[i]); + }*/ } return float4(cubeColor, 1); @@ -225,7 +272,14 @@ float4 main( PFXVertToPix IN ) : SV_TARGET float3 cubeColor = float3(0, 0, 0); for (i = 0; i < numProbes; ++i) { - cubeColor += blendFactor[i] * iblBoxDiffuse(surface, probes[i]); + //if (probes[i].type == 2) //skylight + //{ + cubeColor += blendFactor[i] * iblSkylightDiffuse(surface, probes[i]); + /*} + else + { + cubeColor += blendFactor[i] * iblBoxDiffuse(surface, probes[i]); + }*/ } return float4(cubeColor, 1);