Explorar o código

Begun hook-in of skylight into array
Reworked the reflection reference offset/scale behavior to re-integrate into the editor interface via button(and work)
Hid irrelevent fields from given probe types.
Filter out editPosOffset and bake button fields from being saved to avoid weird loading behavior

Areloch %!s(int64=6) %!d(string=hai) anos
pai
achega
70d85d2241

+ 4 - 2
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)
 {

+ 1 - 1
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);
 };

+ 105 - 30
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<ReflectionProbe*>(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<ReflectionProbe*>(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);
 }

+ 8 - 1
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

+ 7 - 1
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());
 

+ 0 - 1
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

+ 2 - 0
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()

+ 8 - 3
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<ReflectionProbe*>(probe->getClientObject());
 
+   if (clientProbe == nullptr)
+      return;
+
    String probePrefilterPath = clientProbe->getPrefilterMapPath();
    String probeIrradPath = clientProbe->getIrradianceMapPath();
 

+ 3 - 2
Engine/source/renderInstance/renderProbeMgr.h

@@ -88,8 +88,9 @@ struct ProbeRenderInst : public SystemInterface<ProbeRenderInst>
 
    enum ProbeShapeType
    {
-      Sphere = 0,            ///< Sphere shaped
-      Box = 1,               ///< Box-based shape
+      Box = 0,            ///< Sphere shaped
+      Sphere = 1,               ///< Box-based shape
+      Skylight = 2
    };
 
    ProbeShapeType mProbeShapeType;

+ 1 - 1
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; }

+ 60 - 6
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);