Selaa lähdekoodia

Merge pull request #1478 from Areloch/VolFog2

Volumetric Fog Take 2
Areloch 9 vuotta sitten
vanhempi
commit
ff2df5c43f
66 muutettua tiedostoa jossa 3988 lisäystä ja 6 poistoa
  1. 1319 0
      Engine/source/environment/VolumetricFog.cpp
  2. 243 0
      Engine/source/environment/VolumetricFog.h
  3. 299 0
      Engine/source/environment/VolumetricFogRTManager.cpp
  4. 92 0
      Engine/source/environment/VolumetricFogRTManager.h
  5. 3 0
      Engine/source/gui/core/guiCanvas.cpp
  6. 10 0
      Engine/source/gui/core/guiCanvas.h
  7. 1 0
      Engine/source/renderInstance/renderPassManager.cpp
  8. 1 0
      Engine/source/renderInstance/renderPassManager.h
  9. 10 0
      Engine/source/renderInstance/renderTranslucentMgr.cpp
  10. 6 1
      Engine/source/windowManager/platformWindow.cpp
  11. 8 3
      Engine/source/windowManager/platformWindow.h
  12. 2 0
      Engine/source/windowManager/win32/win32Window.cpp
  13. BIN
      Templates/Empty/game/art/environment/FogMod_heavy.dds
  14. BIN
      Templates/Empty/game/art/environment/FogMod_light.dds
  15. BIN
      Templates/Empty/game/art/environment/FogMod_med.dds
  16. 97 0
      Templates/Empty/game/art/environment/Fog_Cube.DAE
  17. 8 0
      Templates/Empty/game/art/environment/Fog_Cube.cs
  18. 76 0
      Templates/Empty/game/core/scripts/client/postFx/glow.cs
  19. 1 0
      Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.settings.cs
  20. 2 0
      Templates/Empty/game/core/scripts/client/renderManager.cs
  21. 106 0
      Templates/Empty/game/scripts/server/VolumetricFog.cs
  22. 1 0
      Templates/Empty/game/scripts/server/scriptExec.cs
  23. 87 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogP.hlsl
  24. 39 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogPreP.hlsl
  25. 46 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogPreV.hlsl
  26. 36 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogRefl.hlsl
  27. 45 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogV.hlsl
  28. 87 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogP.glsl
  29. 37 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogPreP.glsl
  30. 42 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogPreV.glsl
  31. 33 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogRefl.glsl
  32. 38 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogV.glsl
  33. 74 0
      Templates/Empty/game/shaders/common/postFx/VolFogGlowP.hlsl
  34. 67 0
      Templates/Empty/game/shaders/common/postFx/gl/VolFogGlowP.glsl
  35. BIN
      Templates/Empty/game/tools/classIcons/VolumetricFog.png
  36. 13 1
      Templates/Empty/game/tools/worldEditor/gui/objectBuilderGui.ed.gui
  37. 1 0
      Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs
  38. BIN
      Templates/Full/game/art/environment/FogMod_heavy.dds
  39. BIN
      Templates/Full/game/art/environment/FogMod_light.dds
  40. BIN
      Templates/Full/game/art/environment/FogMod_med.dds
  41. 97 0
      Templates/Full/game/art/environment/Fog_Cube.DAE
  42. 8 0
      Templates/Full/game/art/environment/Fog_Cube.cs
  43. 77 0
      Templates/Full/game/art/environment/LightVolume_Sphere.DAE
  44. 8 0
      Templates/Full/game/art/environment/LightVolume_Sphere.cs
  45. BIN
      Templates/Full/game/art/environment/LightVolume_Sphere.dts
  46. 76 0
      Templates/Full/game/core/scripts/client/postFx/glow.cs
  47. 1 0
      Templates/Full/game/core/scripts/client/postFx/postFxManager.gui.settings.cs
  48. 2 0
      Templates/Full/game/core/scripts/client/renderManager.cs
  49. 36 0
      Templates/Full/game/core/scripts/client/shaders.cs
  50. 106 0
      Templates/Full/game/scripts/server/VolumetricFog.cs
  51. 1 0
      Templates/Full/game/scripts/server/scriptExec.cs
  52. 87 0
      Templates/Full/game/shaders/common/VolumetricFog/VFogP.hlsl
  53. 39 0
      Templates/Full/game/shaders/common/VolumetricFog/VFogPreP.hlsl
  54. 46 0
      Templates/Full/game/shaders/common/VolumetricFog/VFogPreV.hlsl
  55. 37 0
      Templates/Full/game/shaders/common/VolumetricFog/VFogRefl.hlsl
  56. 45 0
      Templates/Full/game/shaders/common/VolumetricFog/VFogV.hlsl
  57. 87 0
      Templates/Full/game/shaders/common/VolumetricFog/gl/VFogP.glsl
  58. 37 0
      Templates/Full/game/shaders/common/VolumetricFog/gl/VFogPreP.glsl
  59. 42 0
      Templates/Full/game/shaders/common/VolumetricFog/gl/VFogPreV.glsl
  60. 33 0
      Templates/Full/game/shaders/common/VolumetricFog/gl/VFogRefl.glsl
  61. 38 0
      Templates/Full/game/shaders/common/VolumetricFog/gl/VFogV.glsl
  62. 74 0
      Templates/Full/game/shaders/common/postFx/VolFogGlowP.hlsl
  63. 67 0
      Templates/Full/game/shaders/common/postFx/gl/VolFogGlowP.glsl
  64. BIN
      Templates/Full/game/tools/classIcons/VolumetricFog.png
  65. 13 1
      Templates/Full/game/tools/worldEditor/gui/objectBuilderGui.ed.gui
  66. 1 0
      Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs

+ 1319 - 0
Engine/source/environment/VolumetricFog.cpp

@@ -0,0 +1,1319 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "environment/VolumetricFog.h"
+#include "windowManager/platformWindowMgr.h"
+#include "gfx/gfxTransformSaver.h"
+#include "renderInstance/renderPassManager.h"
+#include "math/mathIO.h"
+#include "materials/shaderData.h"
+#include "math/util/matrixSet.h"
+#include "core/resourceManager.h"
+#include "core/stream/bitStream.h"
+#include "T3D/gameBase/gameConnection.h"
+#include "T3D/shapeBase.h"
+#include "ts/tsShapeInstance.h"
+#include "console/engineAPI.h"
+#include "gui/core/guiCanvas.h"
+#include "VolumetricFogRTManager.h"
+#include "lighting/lightInfo.h"
+#include "lighting/lightManager.h"
+
+#define COLBOX_SCALE Point3F(1.02f, 1.02f, 1.02f)
+
+IMPLEMENT_CO_NETOBJECT_V1(VolumetricFog);
+
+ConsoleDocClass(VolumetricFog,
+"@brief Volumetric Fog Object class. Main class defining the Volumetric\n"
+"Fog objects in the scene. Used in conjunction with the VolumetricFogRTManager\n"
+"class which is responsible for the required rendertargets.\n\n"
+"Methods (exposed to script):\n"
+" setFogColorF(color) Changes the overall fog color (color.rgba range 0.0 - 1.0).\n;"
+" setFogColor(color) Changes the overall fog color color.rgba range 0 - 255).\n;"
+" setFogDensity(density) Changes the overall fog density.\n"
+" setFogModulation(strength, speed1, speed2) changes the strength\n"
+" and the speeds of the 2 animation layers.\n\n"
+"Callbacks:\n"
+"onEnterFog triggered whenever the controlobject (Player or Camera) enters the Fog.\n"
+" (current Fog object and the controlobject are exposed to script.\n"
+"onLeaveFog triggered whenever the controlobject (Player or Camera) left the Fog.\n"
+" (current Fog object and the controlobject are exposed to script.\n\n"
+"@tsexample\n"
+" new VolumetricFog()\n"
+" {\n"
+" shapeName = \"art/environment/FogRCube.dts\";\n"
+" fogColor = \"200 200 200 128\";\n"
+" fogDensity = \"0.2\";\n"
+" ignoreWater = \"0\";\n"
+" MinSize = \"250\";\n"
+" FadeSize = \"750\";\n"
+" texture = \"art/environment/FogMod_heavy.dds\";\n"
+" tiles = \"1.5\";\n"
+" modStrength = \"0.2\";\n"
+" PrimSpeed = \"-0.01 0.04\";\n"
+" SecSpeed = \"0.02 -0.02\";\n"
+" position = \"748.644 656.371 65.3506\"; \n"
+" rotation = \"0 0 1 20.354\";\n"
+" scale = \"40 30 6\";\n"
+" };\n"
+"@endtsexample\n"
+);
+
+IMPLEMENT_CALLBACK(VolumetricFog, onEnterFog, void, (SimObjectId obj), (obj),
+"@brief Called when an object enters the volume of the Fog instance.\n\n"
+
+"@param obj the controlobject entering the fog.");
+
+IMPLEMENT_CALLBACK(VolumetricFog, onLeaveFog, void, (SimObjectId obj), (obj),
+"@brief Called when an object left the volume of the Fog instance.\n\n"
+
+"@param obj the controlobject leaving the fog.");
+
+
+VolumetricFog::VolumetricFog()
+{
+   AssertFatal(VFRTM != NULL, "VolumetricFog Fatal Error: No Manager found");
+
+   if (!VFRTM->IsInitialized())
+   VFRTM->Init();
+
+   mNetFlags.set(Ghostable | ScopeAlways);
+
+   mTypeMask |= EnvironmentObjectType | StaticObjectType;
+
+   mPrepassTarget = NULL;
+   mDepthBufferTarget = NULL;
+   mFrontBufferTarget = NULL;
+
+   z_buf = NULL;
+   mTexture = NULL;
+
+   mIsVBDirty = false;
+   mIsPBDirty = false;
+
+   mFogColor.set(200, 200, 200, 255);
+   mFogDensity = 0.3f;
+   mIgnoreWater = false;
+   mReflect = false;
+   mCamInFog = false;
+   mResizing = false;
+   mFogReflStrength = 20.0;
+   mUseGlow = false;
+   mGlowStrength = 0.3f;
+   mGlowing = 0;
+   mModifLightRays = false;
+   mLightRayMod = 1.0f;
+   mOldLightRayStrength = 0.1f;
+
+   mShapeName = "";
+   mShapeLoaded = false;
+   mMinDisplaySize = 10.0f;
+   mFadeSize = 0.0f;
+   mCurDetailLevel = 0;
+   mNumDetailLevels = 0;
+   det_size.clear();
+
+   mTextureName = "";
+   mIsTextured = false;
+   mStrength = 0.5f;
+   mTexTiles = 1.0f;
+   mSpeed1.set(0.5f, 0.0f);
+   mSpeed2.set(0.1f, 0.1f);
+}
+
+VolumetricFog::~VolumetricFog()
+{
+   if (isClientObject())
+      return;
+
+   for (S32 i = 0; i < det_size.size(); i++)
+   {
+      if (det_size[i].indices != NULL)
+         delete(det_size[i].indices);
+      if (det_size[i].piArray != NULL)
+         delete(det_size[i].piArray);
+      if (det_size[i].verts != NULL)
+         delete(det_size[i].verts);
+   }
+   det_size.clear();
+
+   if (z_buf.isValid())
+      SAFE_DELETE(z_buf);
+
+   if (!mTexture.isNull())
+      mTexture.free();
+}
+
+void VolumetricFog::initPersistFields()
+{
+   addGroup("VolumetricFogData");
+   addField("shapeName", TypeShapeFilename, Offset(mShapeName, VolumetricFog),
+      "Path and filename of the model file (.DTS, .DAE) to use for this Volume.");
+   addField("FogColor", TypeColorI, Offset(mFogColor, VolumetricFog),
+      "Fog color RGBA (Alpha is ignored)");
+   addField("FogDensity", TypeF32, Offset(mFogDensity, VolumetricFog), 
+      "Overal fog density value (0 disables the fog).");
+   addField("IgnoreWater", TypeBool, Offset(mIgnoreWater, VolumetricFog), 
+      "Set to true if volumetric fog should continue while submerged.");
+   addField("MinSize", TypeF32, Offset(mMinDisplaySize, VolumetricFog), 
+      "Min size (in pixels) for fog to be rendered.");
+   addField("FadeSize", TypeF32, Offset(mFadeSize, VolumetricFog), 
+      "Object size in pixels at which the FX-fading kicks in (0 disables fading).");
+   endGroup("VolumetricFogData");
+
+   addGroup("VolumetricFogModulation");
+   addField("texture", TypeImageFilename, Offset(mTextureName, VolumetricFog),
+      "A texture which contains Fogdensity modulator in the red channel and color with 1-green channel. No texture disables modulation.");
+   addField("tiles", TypeF32, Offset(mTexTiles, VolumetricFog), 
+      "How many times the texture is mapped to the object.");
+   addField("modStrength", TypeF32, Offset(mStrength, VolumetricFog),
+      "Overall strength of the density modulation (0 disables modulation).");
+   addField("PrimSpeed", TypePoint2F, Offset(mSpeed1, VolumetricFog),
+      "Overall primary speed of the density modulation (x-speed(u) y-speed(v))");
+   addField("SecSpeed", TypePoint2F, Offset(mSpeed2, VolumetricFog),
+      "Overall secundary speed of the density modulation (x-speed(u) y-speed(v))");
+   endGroup("VolumetricFogModulation");
+
+   addGroup("Reflections");
+   addField("Reflectable", TypeBool, Offset(mReflect, VolumetricFog), 
+      "Set to true if volumetric fog should be reflected.");
+   addField("ReflectStrength", TypeF32, Offset(mFogReflStrength, VolumetricFog), 
+      "Strength of the reflections (0 disables the fog).");
+   endGroup("Reflections");
+
+   addGroup("PostFX");
+   addField("useGlow", TypeBool, Offset(mUseGlow, VolumetricFog), 
+      "Set to true if volumetric fog should use glow PostFX.");
+   addField("glowStrength", TypeF32, Offset(mGlowStrength, VolumetricFog),
+      "Overall strength of the glow PostFX.");
+   addField("modLightRay", TypeBool, Offset(mModifLightRays, VolumetricFog), 
+      "Set to true if volumetric fog should modify the brightness of the Lightrays.");
+   addField("lightRayMod", TypeF32, Offset(mLightRayMod, VolumetricFog),
+      "Modifier for LightRay PostFX when inside Fog.");
+   endGroup("PostFX");
+   Parent::initPersistFields();
+}
+
+void VolumetricFog::inspectPostApply()
+{
+   Parent::inspectPostApply();
+   mSpeed.set(mSpeed1.x, mSpeed1.y, mSpeed2.x, mSpeed2.y);
+   setMaskBits(VolumetricFogMask | FogColorMask | FogDensityMask | FogModulationMask | FogPostFXMask | FogShapeMask);
+}
+
+bool VolumetricFog::onAdd()
+{
+   if (!Parent::onAdd())
+      return false;
+
+   if (!VFRTM->IsInitialized())
+   {
+      Con::errorf("No VolumetricFogRTManager present!!");
+      return false;
+   }
+
+   resetWorldBox();
+
+   mShapeLoaded = LoadShape();
+
+   setRenderTransform(mObjToWorld);
+
+   addToScene();
+   ColBox.set(getTransform(), (mObjBox.getExtents() * getScale() * COLBOX_SCALE));
+   mObjSize = mWorldBox.getGreatestDiagonalLength();
+   mObjScale = getScale();
+   mTexTiles = mAbs(mTexTiles);
+   mSpeed.set(mSpeed1.x, mSpeed1.y, mSpeed2.x, mSpeed2.y);
+   mInvScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
+
+   if (isClientObject())
+   {
+      conn = GameConnection::getConnectionToServer();
+      if (!conn)
+      {  
+         Con::errorf("VolumetricFog::onAdd - No Serverconnection");
+         return false;
+      }
+
+      glowFX = static_cast<PostEffect*>(Sim::findObject("VolFogGlowPostFx"));
+
+      mOldLightRayStrength = Con::getFloatVariable("$LightRayPostFX::brightScalar",1.0f);
+
+      GuiCanvas* cv = dynamic_cast<GuiCanvas*>(Sim::findObject("Canvas"));
+      if (cv == NULL)
+      {
+         Con::errorf("VolumetricFog::onAdd - Canvas not found!!");
+         return false;
+      }
+      mPlatformWindow = cv->getPlatformWindow();
+      VolumetricFogRTManager::getVolumetricFogRTMResizeSignal().notify(this, &VolumetricFog::handleResize);
+      GuiCanvas::getCanvasSizeChangeSignal().notify(this, &VolumetricFog::handleCanvasResize);
+
+      InitTexture();
+      return setupRenderer();
+   }
+
+   VFRTM->IncFogObjects();
+   
+   return true;
+}
+
+void VolumetricFog::onRemove()
+{
+   if (isClientObject())
+   {
+      if (isTicking())
+      {
+         setProcessTick(false);
+         if (mGlowing != 0)
+         {
+            mGlowing = 0;
+            glowFX->disable();
+         }
+         _leaveFog(static_cast<ShapeBase*>(conn->getControlObject()));
+      }
+      VolumetricFogRTManager::getVolumetricFogRTMResizeSignal().remove(this, &VolumetricFog::handleResize);
+      GuiCanvas::getCanvasSizeChangeSignal().remove(this, &VolumetricFog::handleCanvasResize);
+   }
+   removeFromScene();
+   VFRTM->DecFogObjects();
+   Parent::onRemove();
+}
+void VolumetricFog::handleCanvasResize(GuiCanvas* canvas)
+{
+   UpdateBuffers(0,true);
+}
+
+void VolumetricFog::handleResize(VolumetricFogRTManager *RTM, bool resize)
+{
+   if (resize)
+   {
+      mResizing = true;
+      RTM->FogAnswered();
+   }
+   else
+      mResizing = false;
+
+   if (mIsTextured)
+   {
+      F32 width = (F32)mPlatformWindow->getClientExtent().x;
+      F32 height = (F32)mPlatformWindow->getClientExtent().y;
+      if (!mPlatformWindow->isFullscreen())
+         height -= 20;//subtract caption bar from rendertarget size.
+      mTexScale.x = 2.0f - ((F32)mTexture.getWidth() / width);
+      mTexScale.y = 2.0f - ((F32)mTexture.getHeight() / height);
+   }
+
+   UpdateBuffers(0,true);
+}
+
+//-----------------------------------------------------------------------------
+// Loadshape extracted from TSMesh and TSShapeInstance
+//-----------------------------------------------------------------------------
+
+bool VolumetricFog::LoadShape()
+{
+   GFXPrimitiveType GFXdrawTypes[] = { GFXTriangleList, GFXTriangleStrip };
+   if (!mShapeName || mShapeName[0] == '\0')
+   {
+      Con::errorf("VolumetricFog::LoadShape() - No shape name! Volumetric Fog will not be rendered!");
+      return false;
+   }
+
+   // Load shape, server side only reads bounds and radius
+
+   Resource<TSShape> mShape;
+   mShape = ResourceManager::get().load(mShapeName);
+   if (bool(mShape) == false)
+   {
+      Con::errorf("VolumetricFog::LoadShape() - Unable to load shape: %s", mShapeName);
+      return false;
+   }
+
+   mObjBox = mShape->bounds;
+   mRadius = mShape->radius;
+   resetWorldBox();
+
+   if (!isClientObject())
+      return false;
+
+   TSShapeInstance *mShapeInstance = new TSShapeInstance(mShape, false);
+   meshes mesh_detail;
+
+   for (S32 i = 0; i < det_size.size(); i++)
+   {
+      if (det_size[i].indices != NULL)
+         delete(det_size[i].indices);
+      if (det_size[i].piArray != NULL)
+         delete(det_size[i].piArray);
+      if (det_size[i].verts != NULL)
+         delete(det_size[i].verts);
+   }
+   det_size.clear();
+
+   // browsing model for detail levels
+
+   for (U32 i = 0; i < mShape->details.size(); i++)
+   {
+      const TSDetail *detail = &mShape->details[i];
+      mesh_detail.det_size = detail->size;
+      mesh_detail.sub_shape = detail->subShapeNum;
+      mesh_detail.obj_det = detail->objectDetailNum;
+      mesh_detail.verts = NULL;
+      mesh_detail.piArray = NULL;
+      mesh_detail.indices = NULL;
+      if (detail->size >= 0.0f && detail->subShapeNum >= 0)
+         det_size.push_back(mesh_detail);
+   }
+
+   for (U32 i = 0; i < det_size.size(); i++)
+   {
+      const S32 ss = det_size[i].sub_shape;
+      if (ss >= 0)
+      {
+         const S32 start = mShape->subShapeFirstObject[ss];
+         const S32 end = start + mShape->subShapeNumObjects[ss];
+         for (S32 j = start; j < end; j++)
+         {
+            // Loading shape, only the first mesh for each detail will be used!
+            TSShapeInstance::MeshObjectInstance *meshObj = &mShapeInstance->mMeshObjects[j];
+            if (!meshObj)
+               continue;
+            TSMesh *mesh = meshObj->getMesh(det_size[i].obj_det);
+            if (mesh != NULL)
+            {
+               const U32 numNrms = mesh->mNumVerts;
+               GFXVertexPNTT *tmpVerts = NULL;
+               tmpVerts = new GFXVertexPNTT[numNrms];
+               mIsVBDirty = true;
+               for (U32 k = 0; k < numNrms; k++)
+                  {
+                     Point3F norm = mesh->mVertexData[k].normal();
+                     Point3F vert = mesh->mVertexData[k].vert();
+                     Point2F uv = mesh->mVertexData[k].tvert();
+                     tmpVerts[k].point = vert;
+                     tmpVerts[k].texCoord = uv;
+                     tmpVerts[k].normal = norm;
+                  }
+               det_size[i].verts = tmpVerts;
+               det_size[i].num_verts = numNrms;
+
+               det_size[i].piArray = new Vector<GFXPrimitive>();
+               GFXPrimitive pInfo;
+
+               det_size[i].indices = new Vector<U32>();
+
+               for (U32 k = 0; k < mesh->indices.size(); k++)
+                  det_size[i].indices->push_back(mesh->indices[k]);
+
+               U32 primitivesSize = mesh->primitives.size();
+               for (U32 k = 0; k < primitivesSize; k++)
+               {
+                  const TSDrawPrimitive & draw = mesh->primitives[k];
+                  GFXPrimitiveType drawType = GFXdrawTypes[draw.matIndex >> 30];
+                  switch (drawType)
+                  {
+                     case GFXTriangleList:
+                        pInfo.type = drawType;
+                        pInfo.numPrimitives = draw.numElements / 3;
+                        pInfo.startIndex = draw.start;
+                        // Use the first index to determine which 16-bit address space we are operating in
+                        pInfo.startVertex = mesh->indices[draw.start] & 0xFFFF0000;
+                        pInfo.minIndex = pInfo.startVertex;
+                        pInfo.numVertices = getMin((U32)0x10000, mesh->mNumVerts - pInfo.startVertex);
+                        break;
+                     case GFXTriangleStrip:
+                        pInfo.type = drawType;
+                        pInfo.numPrimitives = draw.numElements - 2;
+                        pInfo.startIndex = draw.start;
+                        // Use the first index to determine which 16-bit address space we are operating in
+                        pInfo.startVertex = mesh->indices[draw.start] & 0xFFFF0000;
+                        pInfo.minIndex = pInfo.startVertex;
+                        pInfo.numVertices = getMin((U32)0x10000, mesh->mNumVerts - pInfo.startVertex);
+                        break;
+                     default:
+                        Con::errorf("VolumetricFog::LoadShape Unknown drawtype!?!");
+                        return false;
+                        break;
+                  }
+               det_size[i].piArray->push_back(pInfo);
+               j = end;
+            }
+         }
+         else
+         {
+            Con::errorf("VolumetricFog::LoadShape Error loading mesh from shape!");
+            delete mShapeInstance;
+            return false;
+         }
+         mIsVBDirty = true;
+         mIsPBDirty = true;
+         }
+      }
+   }
+
+   mNumDetailLevels = det_size.size();
+   mCurDetailLevel = 0;
+   UpdateBuffers(mCurDetailLevel);
+   delete mShapeInstance;
+
+   return true;
+}
+
+//-----------------------------------------------------------------------------
+// UpdateBuffers called whenever detaillevel changes (LOD)
+//-----------------------------------------------------------------------------
+
+
+bool VolumetricFog::UpdateBuffers(U32 dl, bool force)
+{
+   if (mVB.isNull() || mIsVBDirty || dl != mCurDetailLevel || force)
+   {
+      mVB.set(GFX, det_size[dl].num_verts, GFXBufferTypeDynamic);
+      mIsVBDirty = false;
+   }
+   GFXVertexPNTT *vertPtr = mVB.lock();
+   if (!vertPtr)
+   {
+      mVB.unlock();
+      return false;
+   }
+   dMemcpy(vertPtr, det_size[dl].verts, sizeof (GFXVertexPNTT)* det_size[dl].num_verts);
+   mVB.unlock();
+
+   if (mIsPBDirty || mPB.isNull() || dl != mCurDetailLevel || force)
+   {
+      #ifdef TORQUE_DEBUG
+      mPB.set(GFX, det_size[dl].indices->size(), det_size[dl].piArray->size(), GFXBufferTypeDynamic, avar("%s() - VolFogPrimBuffer (line %d)", __FUNCTION__, __LINE__));
+      #else
+      mPB.set(GFX, det_size[dl].indices->size(), det_size[dl].piArray->size(), GFXBufferTypeDynamic);
+      #endif
+      U16 *ibIndices = NULL;
+      GFXPrimitive *piInput = NULL;
+      mPB.lock(&ibIndices, &piInput);
+      dCopyArray(ibIndices, det_size[dl].indices->address(), det_size[dl].indices->size());
+      dMemcpy(piInput, det_size[dl].piArray->address(), det_size[dl].piArray->size() * sizeof(GFXPrimitive));
+      mPB.unlock();
+      mIsPBDirty = false;
+   }
+   mCurDetailLevel = dl;
+   return true;
+}
+
+U32 VolumetricFog::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
+{
+   U32 retMask = Parent::packUpdate(con, mask, stream);
+   if (stream->writeFlag(mask & FogColorMask))
+      stream->write(mFogColor);
+   if (stream->writeFlag(mask & FogDensityMask))
+      stream->write(mFogDensity);
+   if (stream->writeFlag(mask & FogModulationMask))
+   {
+      stream->write(mTextureName);
+      mTexTiles = mFabs(mTexTiles);
+      stream->write(mTexTiles);
+      stream->write(mStrength);
+      mathWrite(*stream, mSpeed);
+   }
+   if (stream->writeFlag(mask & FogPostFXMask))
+   {
+      stream->writeFlag(mUseGlow);
+      stream->write(mGlowStrength);
+      stream->writeFlag(mModifLightRays);
+      stream->write(mLightRayMod);
+   }
+   if (stream->writeFlag(mask & VolumetricFogMask))
+   {
+      stream->writeFlag(mIgnoreWater);
+      stream->writeFlag(mReflect);
+      stream->write(mFogReflStrength);
+      stream->writeFlag(mResizing);
+      stream->write(mMinDisplaySize);
+      stream->write(mFadeSize);
+   }
+   if (stream->writeFlag(mask & FogShapeMask))
+   {
+      stream->writeString(mShapeName);
+      mathWrite(*stream, getTransform());
+      mathWrite(*stream, getScale());
+      if (!mShapeName || mShapeName[0] == '\0')
+         return retMask;
+      Resource<TSShape> mShape;
+      mShape = ResourceManager::get().load(mShapeName);
+      if (bool(mShape) == false)
+         return retMask;
+      mObjBox = mShape->bounds;
+      mRadius = mShape->radius;
+      resetWorldBox();
+      mObjSize = mWorldBox.getGreatestDiagonalLength();
+      mObjScale = getScale();
+      mInvScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
+   }
+   return retMask;
+}
+
+void VolumetricFog::unpackUpdate(NetConnection *con, BitStream *stream)
+{
+   Parent::unpackUpdate(con, stream);
+   MatrixF mat;
+   VectorF scale;
+   VectorF mOldScale = getScale();
+   String oldTextureName = mTextureName;
+   StringTableEntry oldShape = mShapeName;
+
+   if (stream->readFlag())// Fog color
+      stream->read(&mFogColor);
+   if (stream->readFlag())// Fog Density
+   {
+      stream->read(&mFogDensity);
+      if (isTicking())
+      {
+         char buf[20];
+         dSprintf(buf, sizeof(buf), "%3.7f", mFogDensity);
+         Con::setVariable("$VolumetricFog::density", buf);
+      }
+   }
+   if (stream->readFlag())// Fog Modulation
+   {
+      stream->read(&mTextureName);
+      stream->read(&mTexTiles);
+      mTexTiles = mFabs(mTexTiles);
+      stream->read(&mStrength);
+      mathRead(*stream, &mSpeed);
+      mSpeed1.set(mSpeed.x, mSpeed.y);
+      mSpeed2.set(mSpeed.z, mSpeed.w);
+
+      if (isProperlyAdded())
+      {
+         if (oldTextureName != mTextureName)
+            InitTexture();
+         if (oldTextureName.isNotEmpty() && mTextureName.isEmpty())
+         {
+            mIsTextured = false;
+            mTexture.free();
+         }
+      }
+   }
+   if (stream->readFlag())//Fog PostFX
+   {
+      mUseGlow = stream->readFlag();
+      stream->read(&mGlowStrength);
+      mModifLightRays = stream->readFlag();
+      stream->read(&mLightRayMod);
+      if (isTicking())
+      {
+         char buf[20];
+         dSprintf(buf, sizeof(buf), "%3.7f", mGlowStrength);
+         Con::setVariable("$VolFogGlowPostFx::glowStrength", buf);
+         if (mUseGlow && !glowFX->isEnabled())
+            glowFX->enable();
+         if (!mUseGlow && glowFX->isEnabled())
+            glowFX->disable();
+         if (mModifLightRays)
+         {
+            char buf[20];
+            dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength * mLightRayMod);
+            Con::setVariable("$LightRayPostFX::brightScalar", buf);
+         }
+         if (!mModifLightRays)
+         {
+            char buf[20];
+            dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength);
+            Con::setVariable("$LightRayPostFX::brightScalar", buf);
+         }
+      }
+   }
+   if (stream->readFlag())//Volumetric Fog
+   {
+      mIgnoreWater = stream->readFlag();
+      mReflect = stream->readFlag();
+      stream->read(&mFogReflStrength);
+      mResizing = stream->readFlag();
+      stream->read(&mMinDisplaySize);
+      stream->read(&mFadeSize);
+   }
+   if (stream->readFlag())//Fog shape
+   {
+      mShapeName = stream->readSTString();
+      mathRead(*stream, &mat);
+      mathRead(*stream, &scale);
+      if (strcmp(oldShape, mShapeName) != 0)
+      {
+         mIsVBDirty = true;
+         mShapeLoaded = LoadShape();
+      }
+      setScale(scale);
+      setTransform(mat);
+      ColBox.set(getTransform(), (mObjBox.getExtents() * getScale() * COLBOX_SCALE));
+      mObjSize = mWorldBox.getGreatestDiagonalLength();
+      mObjScale = getScale();
+      mInvScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
+   }
+}
+
+void VolumetricFog::processTick(const Move* move)
+{
+   Parent::processTick(move);
+   mCounter++;
+   if ( mGlowing==1 && mCurGlow < mGlowStrength )
+   {
+      mCurGlow += (mGlowStrength / 10.0);
+      char buf[20];
+      dSprintf(buf, sizeof(buf), "%3.7f", mCurGlow);
+      Con::setVariable("$VolFogGlowPostFx::glowStrength", buf);
+   }
+   else if ( mGlowing == 2 && mCurGlow > 0.0f )
+   {
+      mCurGlow -= (mGlowStrength / 5.0f);
+      if (mCurGlow <= 0.0f)
+      {
+         glowFX->disable();
+         mGlowing = 0;
+         setProcessTick(false);
+         return;
+      }
+      else
+      {
+         char buf[20];
+         dSprintf(buf, sizeof(buf), "%3.7f", mCurGlow);
+         Con::setVariable("$VolFogGlowPostFx::glowStrength", buf);
+      }
+   }
+   if (mCounter == 3)
+   {
+      ShapeBase* control = static_cast<ShapeBase*>(conn->getControlObject());
+      MatrixF xfm;
+      control->getRenderEyeTransform(&xfm);
+      Point3F pos = xfm.getPosition();
+      if (!ColBox.isContained(pos))
+         _leaveFog(control);
+      mCounter = 0;
+   }
+}
+
+void VolumetricFog::_enterFog(ShapeBase *control)
+{
+   if (mUseGlow)
+   {
+      if (glowFX)
+      {
+         mCurGlow = 0.0f;
+         Con::setVariable("$VolFogGlowPostFx::glowStrength", "0.0");
+         glowFX->enable();
+         mGlowing = 1;
+      }
+   }
+   if (mModifLightRays)
+   {
+      char buf[20];
+      dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength * mLightRayMod);
+      Con::setVariable("$LightRayPostFX::brightScalar", buf);
+   }
+   mCounter = 0;
+   char buf[20];
+   dSprintf(buf, sizeof(buf), "%3.7f", mFogDensity);
+   Con::setVariable("$VolumetricFog::density", buf);
+   setProcessTick(true);
+   if (control)
+      onEnterFog_callback(control->getId());
+}
+
+void VolumetricFog::_leaveFog(ShapeBase *control)
+{
+   mCamInFog = false;
+   Con::setVariable("$VolumetricFog::density", "0.0");
+   if (mModifLightRays)
+   {
+      char buf[20];
+      dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength);
+      Con::setVariable("$LightRayPostFX::brightScalar", buf);
+   }
+   if (mUseGlow)
+   {
+      if (glowFX && mGlowing != 2)
+      {
+         mCurGlow = mGlowStrength;
+         mGlowing = 2;
+         if (control)
+            onLeaveFog_callback(control->getId());
+      }
+   }
+   else
+   {
+      setProcessTick(false);
+      if (control)
+         onLeaveFog_callback(control->getId());
+   }
+}
+
+//-----------------------------------------------------------------------------
+// Setting up the renderers
+//-----------------------------------------------------------------------------
+
+bool VolumetricFog::setupRenderer()
+{
+   // Search for the prepass rendertarget and shadermacros.
+   mPrepassTarget = NamedTexTarget::find("prepass");
+   if (!mPrepassTarget.isValid())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find PrepassTarget");
+      return false;
+   }
+
+   Vector<GFXShaderMacro> macros;
+   if (mPrepassTarget)
+      mPrepassTarget->getShaderMacros(&macros);
+
+   // Search the depth and frontbuffers which are created by the VolumetricFogRTManager
+
+   mDepthBufferTarget = NamedTexTarget::find("volfogdepth");
+   if (!mDepthBufferTarget.isValid())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find depthbuffer");
+      return false;
+   }
+
+   mFrontBufferTarget = NamedTexTarget::find("volfogfront");
+   if (!mFrontBufferTarget.isValid())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find frontbuffer");
+      return false;
+   }
+
+   // Find and setup the prepass Shader
+
+   ShaderData *shaderData;
+   mPrePassShader = Sim::findObject("VolumetricFogPrePassShader", shaderData) ?
+   shaderData->getShader() : NULL;
+   if (!mPrePassShader)
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find VolumetricFogPrePassShader");
+      return false;
+   }
+
+   // Create ShaderConstBuffer and Handles
+
+   mPPShaderConsts = mPrePassShader->allocConstBuffer();
+   if (mPPShaderConsts.isNull())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not allocate ShaderConstants 1.");
+      return false;
+   }
+
+   mPPModelViewProjSC = mPrePassShader->getShaderConstHandle("$modelView");
+
+   // Find and setup the VolumetricFog Shader
+
+   shaderData = NULL;
+   mShader = Sim::findObject("VolumetricFogShader", shaderData) ?
+   shaderData->getShader(macros) : NULL;
+   if (!mShader)
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find VolumetricFogShader");
+      return false;
+   }
+
+   // Create ShaderConstBuffer and Handles
+
+   mShaderConsts = mShader->allocConstBuffer();
+   if (mShaderConsts.isNull())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not allocate ShaderConstants 2.");
+      return false;
+   }
+
+   mModelViewProjSC = mShader->getShaderConstHandle("$modelView");
+   mFadeSizeSC = mShader->getShaderConstHandle("$fadesize");
+   mFogColorSC = mShader->getShaderConstHandle("$fogColor");
+   mFogDensitySC = mShader->getShaderConstHandle("$fogDensity");
+   mPreBias = mShader->getShaderConstHandle("$preBias");
+   mAccumTime = mShader->getShaderConstHandle("$accumTime");
+   mIsTexturedSC = mShader->getShaderConstHandle("$textured");
+   mTexTilesSC = mShader->getShaderConstHandle("$numtiles");
+   mModStrengthSC = mShader->getShaderConstHandle("$modstrength");
+   mModSpeedSC = mShader->getShaderConstHandle("$modspeed");
+   mViewPointSC = mShader->getShaderConstHandle("$viewpoint");
+   mTexScaleSC = mShader->getShaderConstHandle("$texscale");
+   mAmbientColorSC = mShader->getShaderConstHandle("$ambientColor");
+
+   // Find and setup the reflection Shader
+
+   shaderData = NULL;
+   mReflectionShader = Sim::findObject("VolumetricFogReflectionShader", shaderData) ?
+   shaderData->getShader() : NULL;
+   if (!mReflectionShader)
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find VolumetricFogReflectionShader");
+      return false;
+   }
+
+   mReflShaderConsts = mReflectionShader->allocConstBuffer();
+   if (mReflShaderConsts.isNull())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not allocate ShaderConstants for VolumetricFogReflectionShader.");
+      return false;
+   }
+
+   mReflModelViewProjSC = mReflectionShader->getShaderConstHandle("$modelView");
+   mReflFogColorSC = mReflectionShader->getShaderConstHandle("$fogColor");
+   mReflFogDensitySC = mReflectionShader->getShaderConstHandle("$fogDensity");
+   mReflFogStrengthSC = mReflectionShader->getShaderConstHandle("$reflStrength");
+
+   // Create the prepass StateBlock
+
+   desc_preD.setCullMode(GFXCullCW);
+   desc_preD.setBlend(true);
+   desc_preD.setZReadWrite(false, false);
+   desc_preD.stencilEnable = false;
+   desc_preF.setCullMode(GFXCullCCW);
+   desc_preF.setBlend(true);
+   desc_preF.setZReadWrite(true, false);
+   desc_preF.stencilEnable = false;
+   
+   // Create the VolumetricFog StateBlock
+
+   descD.setCullMode(GFXCullCW);
+   descD.setBlend(true);
+   descD.setZReadWrite(false, false);// desc.setZReadWrite(true, false);
+
+   // prepassBuffer sampler
+   descD.samplersDefined = true;
+   descD.samplers[0].addressModeU = GFXAddressClamp;
+   descD.samplers[0].addressModeV = GFXAddressClamp;
+   descD.samplers[0].addressModeW = GFXAddressClamp;
+   descD.samplers[0].magFilter = GFXTextureFilterLinear;
+   descD.samplers[0].minFilter = GFXTextureFilterLinear;
+   descD.samplers[0].mipFilter = GFXTextureFilterLinear;
+   descD.samplers[0].textureColorOp = GFXTOPDisable;
+
+   // DepthBuffer sampler
+   descD.samplers[1].addressModeU = GFXAddressClamp;
+   descD.samplers[1].addressModeV = GFXAddressClamp;
+   descD.samplers[1].addressModeW = GFXAddressClamp;
+   descD.samplers[1].magFilter = GFXTextureFilterLinear;
+   descD.samplers[1].minFilter = GFXTextureFilterLinear;
+   descD.samplers[1].mipFilter = GFXTextureFilterLinear;
+   descD.samplers[1].textureColorOp = GFXTOPModulate;
+
+   // FrontBuffer sampler
+   descD.samplers[2].addressModeU = GFXAddressClamp;
+   descD.samplers[2].addressModeV = GFXAddressClamp;
+   descD.samplers[2].addressModeW = GFXAddressClamp;
+   descD.samplers[2].magFilter = GFXTextureFilterLinear;
+   descD.samplers[2].minFilter = GFXTextureFilterLinear;
+   descD.samplers[2].mipFilter = GFXTextureFilterLinear;
+   descD.samplers[2].textureColorOp = GFXTOPModulate;
+
+   // animated density modifier map sampler
+   descD.samplers[3].addressModeU = GFXAddressWrap;
+   descD.samplers[3].addressModeV = GFXAddressWrap;
+   descD.samplers[3].addressModeW = GFXAddressWrap;
+   descD.samplers[3].magFilter = GFXTextureFilterLinear;
+   descD.samplers[3].minFilter = GFXTextureFilterLinear;
+   descD.samplers[3].mipFilter = GFXTextureFilterLinear;
+   descD.samplers[3].textureColorOp = GFXTOPModulate;
+
+   dMemcpy(&descF, &descD, sizeof(GFXStateBlockDesc));
+   descF.setCullMode(GFXCullCCW);
+   descF.setBlend(true);
+   descF.setZReadWrite(true, false);
+
+   desc_refl.setCullMode(GFXCullCCW);
+   desc_refl.setBlend(true);
+   desc_refl.setZReadWrite(true, false);
+
+   mStateblock_preD = GFX->createStateBlock(desc_preD);
+   mStateblock_preF = GFX->createStateBlock(desc_preF);
+   mStateblockD = GFX->createStateBlock(descD);
+   mStateblockF = GFX->createStateBlock(descF);
+   mStateblock_refl = GFX->createStateBlock(desc_refl);
+
+   // Create Rendertarget
+
+   z_buf = GFX->allocRenderToTextureTarget();
+   if (z_buf == NULL)
+   {
+      Con::errorf("VolumetricFog::setupRenderer - Could not create Render Target");
+      return false;
+   }
+
+   return true;
+}
+
+void VolumetricFog::prepRenderImage(SceneRenderState *state)
+{
+   if (!mShapeLoaded || mFogDensity <= 0.0f || mResizing)
+      return;
+
+   if (!state->isDiffusePass())
+   {
+      if (!state->isReflectPass())
+      return;
+   }
+   
+   PROFILE_SCOPE(VolumetricFog_prepRenderImage);
+
+   // Time critical therefore static_cast
+   ShapeBase* control = static_cast<ShapeBase*>(conn->getControlObject());
+   if (control->getWaterCoverage() >= 0.9f && !mIgnoreWater)
+      return;
+
+   camPos = state->getCameraPosition();
+   F32 dist = (camPos - getBoxCenter()).len();
+   F32 scaleFactor = dist * mInvScale;
+   if (scaleFactor <= 0.0f)
+   {
+      if (mCurDetailLevel != 0)
+         UpdateBuffers(0);
+   }
+   const F32 pixelScale = state->getViewport().extent.y / 300.0f;
+
+   mPixelSize = (mRadius / scaleFactor) * state->getWorldToScreenScale().y * pixelScale;
+   if (mPixelSize < mMinDisplaySize)
+      return;
+   if (mNumDetailLevels > 1)
+   {
+      if ((det_size[mCurDetailLevel].det_size > mPixelSize) && (mCurDetailLevel < mNumDetailLevels - 1))
+         UpdateBuffers(mCurDetailLevel + 1);
+      else if (mCurDetailLevel > 0)
+      {
+         if (mPixelSize >= det_size[mCurDetailLevel - 1].det_size)
+            UpdateBuffers(mCurDetailLevel - 1);
+      }
+   }
+
+   if (state->isReflectPass() && mReflect)
+   {
+      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
+      ri->renderDelegate.bind(this, &VolumetricFog::reflect_render);
+      ri->type = RenderPassManager::RIT_VolumetricFog;
+      ri->translucentSort = true;
+      ri->sortDistSq = getRenderWorldBox().getSqDistanceToPoint(camPos);
+      if (dist < 1.0f)
+         ri->defaultKey = 1;
+      else
+         ri->defaultKey = U32(dist);
+      state->getRenderPass()->addInst(ri);
+      return;
+   }
+   else if (state->isDiffusePass())
+   {
+      viewDist = state->getFarPlane();
+      mFOV = state->getCameraFrustum().getFov() / M_PI_F;
+      Point3F mEyeVec = state->getVectorEye() * viewDist;
+
+      mViewPoint.x = ((mAtan2(mEyeVec.x, mEyeVec.y) / M_PI_F) + 1.0f) * mTexTiles;
+      mViewPoint.y = (0.5f - (mAsin(mEyeVec.z) / M_PI_F)) * mTexTiles;
+
+      bool isInside = ColBox.isContained(camPos);
+      if (isInside && !mCamInFog)
+      {
+         mCamInFog = true;
+         _enterFog(control);
+      }
+      else if (!isInside && mCamInFog)
+         mCamInFog = false;
+
+      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
+      ri->renderDelegate.bind(this, &VolumetricFog::render);
+      ri->type = RenderPassManager::RIT_VolumetricFog;
+      ri->translucentSort = true;
+      ri->sortDistSq = getRenderWorldBox().getSqDistanceToPoint(camPos);
+      if (dist < 1.0f)
+         ri->defaultKey = 1;
+      else
+         ri->defaultKey = U32(dist);
+      state->getRenderPass()->addInst(ri);
+      return;
+   }
+   return;
+}
+
+void VolumetricFog::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat)
+{
+   if (overrideMat || !mShapeLoaded || !isClientObject() || mResizing)
+      return;
+
+   PROFILE_SCOPE(VolumetricFog_Render);
+
+   GFXTransformSaver saver;
+   GFX->setVertexBuffer(mVB);
+   GFX->setPrimitiveBuffer(mPB);
+
+   MatrixF mat = getRenderTransform();
+   mat.scale(mObjScale);
+   GFX->multWorld(mat);
+
+   GFX->setShader(mPrePassShader);
+   GFX->setShaderConstBuffer(mPPShaderConsts);
+   GFX->setStateBlock(mStateblock_preD);
+
+   // Set all the shader consts...
+
+   MatrixF xform(GFX->getProjectionMatrix());
+   xform *= GFX->getViewMatrix();
+   xform *= GFX->getWorldMatrix();
+
+   mPPShaderConsts->setSafe(mPPModelViewProjSC, xform);
+
+   LightInfo *lightinfo = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);
+   const ColorF &sunlight = state->getAmbientLightColor();
+
+   Point3F ambientColor(sunlight.red, sunlight.green, sunlight.blue);
+   mShaderConsts->setSafe(mAmbientColorSC, ambientColor);
+
+   GFXTextureObject *mDepthBuffer = mDepthBufferTarget ? mDepthBufferTarget->getTexture(0) : NULL;
+   GFXTextureObject *mFrontBuffer = mFrontBufferTarget ? mFrontBufferTarget->getTexture(0) : NULL;
+
+   GFX->pushActiveRenderTarget();
+
+   //render backside to target mDepthBuffer
+   z_buf->attachTexture(GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil);
+   z_buf->attachTexture(GFXTextureTarget::Color0, mDepthBuffer);
+
+   GFX->setActiveRenderTarget(z_buf);
+   GFX->clear(GFXClearStencil | GFXClearTarget , ColorI(0,0,0,0), 1.0f, 0);
+
+   GFX->drawPrimitive(0);
+   z_buf->resolve();
+
+   //render frontside to target mFrontBuffer
+   z_buf->attachTexture(GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil);
+   z_buf->attachTexture(GFXTextureTarget::Color0, mFrontBuffer);
+   GFX->clear(GFXClearStencil | GFXClearTarget, ColorI(0, 0, 0, 0), 1.0f, 0);
+
+   GFX->setStateBlock(mStateblock_preF);
+
+   GFX->drawPrimitive(0);
+   z_buf->resolve();
+
+   GFX->popActiveRenderTarget();
+   z_buf->attachTexture(GFXTextureTarget::Color0, NULL);
+
+   //render Volumetric Fog
+   GFX->setShader(mShader);
+   GFX->setShaderConstBuffer(mShaderConsts);
+
+   mShaderConsts->setSafe(mModelViewProjSC, xform);
+   if (mFadeSize > 0.0f)
+      mShaderConsts->setSafe(mFadeSizeSC, mClampF(mPixelSize / mFadeSize, 0.0f, 1.0f));
+   else
+      mShaderConsts->setSafe(mFadeSizeSC, 1.0f);
+   mShaderConsts->setSafe(mFogColorSC, mFogColor);
+   mShaderConsts->setSafe(mFogDensitySC, mFogDensity);
+   mShaderConsts->setSafe(mPreBias, viewDist);
+   mShaderConsts->setSafe(mAccumTime, (F32)Sim::getCurrentTime() / 1000.0f);
+   mShaderConsts->setSafe(mModStrengthSC, mStrength);
+   mShaderConsts->setSafe(mModSpeedSC, mSpeed);
+   mShaderConsts->setSafe(mViewPointSC, mViewPoint);
+   mShaderConsts->setSafe(mTexScaleSC, mTexScale * mFOV);
+   mShaderConsts->setSafe(mTexTilesSC, mTexTiles);
+
+   GFXTextureObject *prepasstex = mPrepassTarget ? mPrepassTarget->getTexture(0) : NULL;
+
+   GFX->setTexture(0, prepasstex);
+   GFX->setTexture(1, mDepthBuffer);
+   GFX->setTexture(2, mFrontBuffer);
+
+   if (mIsTextured && mStrength > 0.0f)
+   {
+      GFX->setTexture(3, mTexture);
+      mShaderConsts->setSafe(mIsTexturedSC, 1.0f);
+   }
+   else
+      mShaderConsts->setSafe(mIsTexturedSC, 0.0f);
+
+   if (mCamInFog)
+   {
+      /*GFXLockedRect *rect=mDepthBuffer->lock();
+      U32 pixoffset = 0;// 1572864 + (512 * 4);
+      U8 red = rect->bits[pixoffset];
+      U8 green = rect->bits[pixoffset+1];
+      U8 blue = rect->bits[pixoffset+2];
+      U8 alpha = rect->bits[pixoffset+3];
+      mDepthBuffer->unlock();
+      S32 lval = ((alpha << 24) + (blue << 16) + (green << 8) + (red));
+      F32 fval = ((F32)lval / S32_MAX);
+      Con::printf("Color %d %d %d %d %d %f", red, green, blue, alpha, lval, fval);*/
+      GFX->setStateBlock(mStateblockD);
+   }
+   else
+      GFX->setStateBlock(mStateblockF);
+
+   GFX->drawPrimitive(0);
+}
+
+void VolumetricFog::reflect_render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat)
+{
+   if (overrideMat || !mShapeLoaded || !isClientObject() || mResizing || (mFogReflStrength==0.0f))
+      return;
+
+   GFXTransformSaver saver;
+   GFX->setVertexBuffer(mVB);
+   GFX->setPrimitiveBuffer(mPB);
+
+   MatrixF mat = getRenderTransform();
+   mat.scale(mObjScale);
+   GFX->multWorld(mat);
+
+   GFX->setShader(mReflectionShader);
+   GFX->setShaderConstBuffer(mReflShaderConsts);
+   GFX->setStateBlock(mStateblock_refl);
+
+   // Set all the shader consts...
+   MatrixF xform(GFX->getProjectionMatrix());
+   xform *= GFX->getViewMatrix();
+   xform *= GFX->getWorldMatrix();
+
+   mReflShaderConsts->setSafe(mReflModelViewProjSC, xform);
+   mReflShaderConsts->setSafe(mReflFogColorSC, mFogColor);
+   mReflShaderConsts->setSafe(mReflFogDensitySC, mFogDensity);
+   mReflShaderConsts->setSafe(mReflFogStrengthSC, mFogReflStrength);
+
+   GFX->drawPrimitive(0);
+}
+
+//-----------------------------------------------------------------------------
+// InitTexture is called whenever a modulation texture is added to the object
+//-----------------------------------------------------------------------------
+
+void VolumetricFog::InitTexture()
+{
+   mIsTextured = false;
+
+   if (mTextureName.isNotEmpty())
+      mTexture.set(mTextureName, &GFXDefaultStaticDiffuseProfile, "VolumetricFogMod");
+
+   if (!mTexture.isNull())
+   {
+      mIsTextured = true;
+
+      F32 width = (F32)mPlatformWindow->getClientExtent().x;
+      F32 height = (F32)mPlatformWindow->getClientExtent().y;
+
+      if (!mPlatformWindow->isFullscreen())
+         height -= 20;//subtract caption bar from rendertarget size.
+
+      mTexScale.x = 2.0f - ((F32)mTexture.getWidth() / width);
+      mTexScale.y = 2.0f - ((F32)mTexture.getHeight() / height);
+   }
+}
+
+void VolumetricFog::setFogColor(ColorF color)
+{
+   mFogColor.set(255 * color.red,255 * color.green,255 * color.blue);
+   setMaskBits(FogColorMask);
+}
+
+void VolumetricFog::setFogColor(ColorI color)
+{
+   mFogColor = color;
+   setMaskBits(FogColorMask);
+}
+
+void VolumetricFog::setFogDensity(F32 density)
+{
+   if (density < 0.0f)
+      density = 0.0f;
+   mFogDensity = density;
+   setMaskBits(FogDensityMask);
+}
+
+void VolumetricFog::setFogModulation(F32 strength,Point2F speed1,Point2F speed2)
+{
+   mStrength = strength;
+   mSpeed1 = speed1;
+   mSpeed2 = speed2;
+   mSpeed.set(speed1.x, speed1.y, speed2.x, speed2.y);
+   setMaskBits(FogModulationMask);
+}
+
+void VolumetricFog::setFogGlow(bool on_off, F32 strength)
+{
+   mUseGlow = on_off;
+   mGlowStrength = strength;
+   setMaskBits(FogPostFXMask);
+}
+
+void VolumetricFog::setFogLightray(bool on_off, F32 strength)
+{
+   mModifLightRays = on_off;
+   mLightRayMod = strength;
+   setMaskBits(FogPostFXMask);
+}
+
+bool VolumetricFog::isInsideFog()
+{
+   return mCamInFog;
+}
+
+DefineEngineMethod(VolumetricFog, SetFogColorF, void, (ColorF new_color), ,
+"@brief Changes the color of the fog\n\n."
+"@params new_color the new fog color (rgb 0.0 - 1.0, a is ignored.")
+{
+   object->setFogColor(new_color);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogColor, void, (ColorI new_color), ,
+"@brief Changes the color of the fog\n\n."
+"@params new_color the new fog color (rgb 0-255, a is ignored.")
+{
+   object->setFogColor(new_color);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogDensity, void, (F32 new_density), ,
+"@brief Changes the density of the fog\n\n."
+"@params new_density the new fog density.")
+{
+   object->setFogDensity(new_density);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogModulation, void, (F32 new_strenght, Point2F new_speed1, Point2F new_speed2), ,
+"@brief Changes the modulation of the fog\n\n."
+"@params new_strenght the new strength of the modulation.\n"
+"@params new_speed1 the new speed (x y) of the modulation layer 1.\n"
+"@params new_speed2 the new speed (x y) of the modulation layer 2.\n")
+{
+   object->setFogModulation(new_strenght, new_speed1, new_speed2);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogGlow, void, (bool on_off,F32 strength), ,
+"@brief Changes the glow postfx when inside the fog\n\n."
+"@params on_off set to true to enable glow.\n"
+"@params strength glow strength.\n")
+{
+   object->setFogGlow(on_off, strength);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogLightray, void, (bool on_off, F32 strength), ,
+"@brief Changes the lightrays postfx when inside the fog\n\n."
+"@params on_off set to true to modification of the lightray postfx.\n"
+"@params strength lightray strength.\n")
+{
+   object->setFogLightray(on_off, strength);
+}
+
+DefineEngineMethod(VolumetricFog, isInsideFog, bool, (), ,
+"@brief returns true if control object is inside the fog\n\n.")
+{
+   return object->isInsideFog();
+}

+ 243 - 0
Engine/source/environment/VolumetricFog.h

@@ -0,0 +1,243 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+   
+#ifndef _VolumetricFog_H_
+#define _VolumetricFog_H_
+   
+#ifndef _SCENEOBJECT_H_
+#include "scene/sceneObject.h"
+#endif
+#ifndef _MATTEXTURETARGET_H_
+#include "materials/matTextureTarget.h"
+#endif
+#ifndef _GFXSHADER_H_
+#include "gfx/gfxShader.h"
+#endif
+#ifndef _GFXTARGET_H_
+#include "gfx/gfxTarget.h"
+#endif
+#ifndef _GFXVERTEXBUFFER_H_
+#include "gfx/gfxVertexBuffer.h"
+#endif
+#ifndef _TSSHAPE_H_
+#include "ts/tsShape.h"
+#endif
+#ifndef _POST_EFFECT_H_
+#include "postFx/postEffect.h"
+#endif
+   
+#include "gui/core/guiCanvas.h"
+   
+class VolumetricFogRTManager;
+   
+class VolumetricFog : public SceneObject
+{
+   typedef SceneObject Parent;
+   
+   // Maskbits for updating
+   enum
+   {
+      VolumetricFogMask = Parent::NextFreeMask,
+      FogColorMask = Parent::NextFreeMask << 1,
+      FogDensityMask = Parent::NextFreeMask << 2,
+      FogModulationMask = Parent::NextFreeMask << 3,
+      FogPostFXMask = Parent::NextFreeMask << 4,
+      FogShapeMask = Parent::NextFreeMask << 5,
+      NextFreeMask = Parent::NextFreeMask << 6
+   };
+   
+// Struct which holds the shape details
+   struct meshes
+   {
+      F32 det_size;
+      S32 sub_shape;
+      S32 obj_det;
+      U32 num_verts;
+      GFXVertexPNTT *verts;
+      Vector <GFXPrimitive> *piArray;
+      Vector <U32> *indices;
+   };
+   
+   protected:
+      // Rendertargets;
+      GFXTextureTargetRef z_buf;
+      NamedTexTargetRef mPrepassTarget;
+      NamedTexTargetRef mDepthBufferTarget;
+      NamedTexTargetRef mFrontBufferTarget;
+   
+      // Fog Modulation texture
+      GFXTexHandle mTexture;
+   
+      // Shaders
+      GFXShaderRef mShader;
+      GFXShaderRef mPrePassShader;
+      GFXShaderRef mReflectionShader;
+   
+      // Stateblocks
+      GFXStateBlockDesc descD;
+      GFXStateBlockDesc descF;
+      GFXStateBlockDesc desc_preD;
+      GFXStateBlockDesc desc_preF;
+      GFXStateBlockDesc desc_refl;
+   
+      GFXStateBlockRef mStateblockD;
+      GFXStateBlockRef mStateblockF;
+      GFXStateBlockRef mStateblock_preD;
+      GFXStateBlockRef mStateblock_preF;
+      GFXStateBlockRef mStateblock_refl;
+   
+      // Shaderconstants
+      GFXShaderConstBufferRef mShaderConsts;
+      GFXShaderConstHandle *mModelViewProjSC;
+      GFXShaderConstHandle *mFadeSizeSC;
+      GFXShaderConstHandle *mFogColorSC;
+      GFXShaderConstHandle *mFogDensitySC;
+      GFXShaderConstHandle *mPreBias;
+      GFXShaderConstHandle *mAccumTime;
+      GFXShaderConstHandle *mIsTexturedSC;
+      GFXShaderConstHandle *mModSpeedSC;
+      GFXShaderConstHandle *mModStrengthSC;
+      GFXShaderConstHandle *mViewPointSC;
+      GFXShaderConstHandle *mTexScaleSC;
+      GFXShaderConstHandle *mTexTilesSC;
+   
+      GFXShaderConstBufferRef mPPShaderConsts;
+      GFXShaderConstHandle *mPPModelViewProjSC;
+
+      GFXShaderConstHandle *mAmbientColorSC;
+   
+      GFXShaderConstBufferRef mReflShaderConsts;
+      GFXShaderConstHandle *mReflModelViewProjSC;
+      GFXShaderConstHandle *mReflFogColorSC;
+      GFXShaderConstHandle *mReflFogDensitySC;
+      GFXShaderConstHandle *mReflFogStrengthSC;
+   
+      // Vertex and Prim. Buffer
+      GFXVertexBufferHandle<GFXVertexPNTT> mVB;
+      GFXPrimitiveBufferHandle mPB;
+   
+      // Fog volume data;
+      StringTableEntry mShapeName;
+      ColorI mFogColor;
+      F32 mFogDensity;
+      bool mIgnoreWater;
+      bool mReflect;
+      Vector<meshes> det_size;
+      bool mShapeLoaded;
+      F32 mPixelSize;
+      F32 mFadeSize;
+      U32 mCurDetailLevel;
+      U32 mNumDetailLevels;
+      F32 mObjSize;
+      F32 mRadius;
+      OrientedBox3F ColBox;
+      VectorF mObjScale;
+      F32 mMinDisplaySize;
+      F32 mInvScale;
+   
+      // Fog Modulation data
+      String mTextureName;
+      bool mIsTextured;
+      F32 mTexTiles;
+      F32 mStrength;
+      Point2F mSpeed1;
+      Point2F mSpeed2;
+      Point4F mSpeed;
+      Point2F mTexScale;
+   
+      // Fog Rendering data
+      Point3F camPos;
+      Point2F mViewPoint;
+      F32 mFOV;
+      F32 viewDist;
+      bool mIsVBDirty;
+      bool mIsPBDirty;
+      bool mCamInFog;
+      bool mResizing;
+      PlatformWindow *mPlatformWindow;
+   
+      // Reflections
+      F32 mFogReflStrength;
+   
+      // PostFX
+      PostEffect *glowFX;
+      bool mUseGlow;
+      F32 mGlowStrength;
+      U8 mGlowing;
+      F32 mCurGlow;
+   
+      bool mModifLightRays;
+      F32 mLightRayMod;
+      F32 mOldLightRayStrength;
+   
+      GameConnection* conn;
+      U32 mCounter;
+   
+      void ResizeRT(PlatformWindow *win, bool resize);
+   
+   protected:
+      // Protected methods
+      bool onAdd();
+      void onRemove();
+      void handleResize(VolumetricFogRTManager *RTM, bool resize);
+      void handleCanvasResize(GuiCanvas* canvas);
+   
+      bool LoadShape();
+      bool setupRenderer();
+      void InitTexture();
+      bool UpdateBuffers(U32 dl,bool force=true);
+   
+      void processTick(const Move *move);
+      void _enterFog(ShapeBase *control);
+      void _leaveFog(ShapeBase *control);
+   
+   public:
+      // Public methods
+      VolumetricFog();
+      ~VolumetricFog();
+   
+      static void initPersistFields();
+      virtual void inspectPostApply();
+   
+      U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream);
+      void unpackUpdate(NetConnection *conn, BitStream *stream);
+   
+      void prepRenderImage(SceneRenderState* state);
+      void render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat);
+      void reflect_render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat);
+   
+      // Methods for modifying & networking various fog elements
+      // Used in script
+      void setFogColor(ColorF color);
+      void setFogColor(ColorI color);
+      void setFogDensity(F32 density);
+      void setFogModulation(F32 strength, Point2F speed1, Point2F speed2);
+      void setFogGlow(bool on_off, F32 strength);
+      void setFogLightray(bool on_off, F32 strength);
+      bool isInsideFog();
+   
+      DECLARE_CONOBJECT(VolumetricFog);
+   
+      DECLARE_CALLBACK(void, onEnterFog, (SimObjectId obj));
+      DECLARE_CALLBACK(void, onLeaveFog, (SimObjectId obj));
+};
+#endif

+ 299 - 0
Engine/source/environment/VolumetricFogRTManager.cpp

@@ -0,0 +1,299 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+   
+//-----------------------------------------------------------------------------
+// Volumetric Fog Rendertarget Manager
+//
+// Creates and maintains one set of rendertargets to be used by every
+// VolumetricFog object in the scene.
+//
+// Will be loaded at startup end removed when ending game.
+//
+//-----------------------------------------------------------------------------
+   
+#include "VolumetricFogRTManager.h"
+#include "core/module.h"
+#include "scene/sceneManager.h"
+#include "windowManager/platformWindowMgr.h"
+#include "console/engineAPI.h"
+#include "gui/core/guiCanvas.h"
+   
+MODULE_BEGIN(VolumetricFogRTManager)
+   
+MODULE_INIT_AFTER(Scene)
+MODULE_SHUTDOWN_BEFORE(Scene)
+   
+MODULE_INIT
+{
+   gVolumetricFogRTManager = new VolumetricFogRTManager;
+   gClientSceneGraph->addObjectToScene(gVolumetricFogRTManager);
+}
+   
+MODULE_SHUTDOWN
+{
+   gClientSceneGraph->removeObjectFromScene(gVolumetricFogRTManager);
+   SAFE_DELETE(gVolumetricFogRTManager);
+}
+   
+MODULE_END;
+   
+ConsoleDocClass( VolumetricFogRTManager,
+"@brief Creates and maintains one set of rendertargets to be used by every\n"
+"VolumetricFog object in the scene.\n\n"
+"Will be loaded at startup end removed when ending game.\n\n"
+"Methods:\n"
+" get() returns the currently loaded VolumetricFogRTManager, also accessible\n"
+" through VFRTM define.\n"
+" Init() Initializes the rendertargets, called when a VolumetricFog object is\n"
+" added to the scene.\n"
+" isInitialed() returns true if Rendertargets are present, false if not, then\n"
+" Init() should be called to create the rendertargets.\n"
+" setQuality(U32 Quality) Normally a rendertarget has the same size as the view,\n"
+" with this method you can scale down the size of it.\n"
+" Be aware that scaling down will introduce renderartefacts.\n"
+"@ingroup Atmosphere"
+);
+   
+VolumetricFogRTMResizeSignal VolumetricFogRTManager::smVolumetricFogRTMResizeSignal;
+   
+VolumetricFogRTManager *gVolumetricFogRTManager = NULL;
+
+S32 VolumetricFogRTManager::mTargetScale = 1;
+   
+IMPLEMENT_CONOBJECT(VolumetricFogRTManager);
+   
+VolumetricFogRTManager::VolumetricFogRTManager()
+{
+   setGlobalBounds();
+   mTypeMask |= EnvironmentObjectType;
+   mNetFlags.set(IsGhost);
+   mIsInitialized = false;
+   mNumFogObjects = 0;
+}
+   
+VolumetricFogRTManager::~VolumetricFogRTManager()
+{
+   if (mFrontTarget.isRegistered())
+      mFrontTarget.unregister();
+   
+   if (mDepthTarget.isRegistered())
+      mDepthTarget.unregister();
+   
+   if (mDepthBuffer.isValid())
+      mDepthBuffer->kill();
+   
+   if (mFrontBuffer.isValid())
+      mFrontBuffer->kill();
+}
+   
+void VolumetricFogRTManager::onSceneRemove()
+{
+   if (mIsInitialized)
+      mPlatformWindow->getScreenResChangeSignal().remove(this, &VolumetricFogRTManager::ResizeRT);
+}
+   
+void VolumetricFogRTManager::onRemove()
+{
+   removeFromScene();
+   Parent::onRemove();
+}
+   
+void VolumetricFogRTManager::consoleInit()
+{
+   Con::addVariable("$pref::VolumetricFog::Quality", TypeS32, &mTargetScale,
+   "The scale of the rendertargets.\n"
+   "@ingroup Rendering\n");
+}
+   
+bool VolumetricFogRTManager::Init()
+{
+   if (mIsInitialized)
+      {
+      Con::errorf("VolumetricFogRTManager allready initialized!!");
+      return true;
+      }
+   
+   GuiCanvas* cv = dynamic_cast<GuiCanvas*>(Sim::findObject("Canvas"));
+   if (cv == NULL)
+   {
+      Con::errorf("VolumetricFogRTManager::Init() - Canvas not found!!");
+      return false;
+   }
+   
+   mPlatformWindow = cv->getPlatformWindow();
+   mPlatformWindow->getScreenResChangeSignal().notify(this,&VolumetricFogRTManager::ResizeRT);
+   
+   if (mTargetScale < 1)
+      mTargetScale = 1;
+   
+   mWidth = mFloor(mPlatformWindow->getClientExtent().x / mTargetScale);
+   mHeight = mPlatformWindow->getClientExtent().y;
+   mFullScreen = mPlatformWindow->isFullscreen();
+   if (!mFullScreen)
+      mHeight -= 20;//subtract caption bar from rendertarget size.
+   mHeight = mFloor(mHeight / mTargetScale);
+   
+   mDepthBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
+   &GFXDefaultRenderTargetProfile, avar("%s() - mDepthBuffer (line %d)", __FUNCTION__, __LINE__));
+   if (!mDepthBuffer.isValid())
+   {
+      Con::errorf("VolumetricFogRTManager Fatal Error: Unable to create Depthbuffer");
+      return false;
+   }
+   if (!mDepthTarget.registerWithName("volfogdepth"))
+   {
+      Con::errorf("VolumetricFogRTManager Fatal Error : Unable to register Depthbuffer");
+      return false;
+   }
+   mDepthTarget.setTexture(mDepthBuffer);
+   
+   mFrontBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
+   &GFXDefaultRenderTargetProfile, avar("%s() - mFrontBuffer (line %d)", __FUNCTION__, __LINE__));
+   if (!mFrontBuffer.isValid())
+   {
+      Con::errorf("VolumetricFogRTManager Fatal Error: Unable to create front buffer");
+      return false;
+   }
+   if (!mFrontTarget.registerWithName("volfogfront"))
+   {
+      Con::errorf("VolumetricFogRTManager Fatal Error : Unable to register Frontbuffer");
+      return false;
+   }
+   
+   mFrontTarget.setTexture(mFrontBuffer);
+   
+   Con::setVariable("$VolumetricFog::density", "0.0");
+   
+   mIsInitialized = true;
+   
+   return true;
+}
+   
+U32 VolumetricFogRTManager::IncFogObjects()
+{
+   mNumFogObjects++;
+   return mNumFogObjects;
+}
+   
+U32 VolumetricFogRTManager::DecFogObjects()
+{
+   if (mNumFogObjects > 0)
+      mNumFogObjects--;
+   return mNumFogObjects;
+}
+   
+void VolumetricFogRTManager::ResizeRT(PlatformWindow* win,bool resize)
+{
+   mFogHasAnswered = 0;
+   smVolumetricFogRTMResizeSignal.trigger(this, true);
+}
+   
+void VolumetricFogRTManager::FogAnswered()
+{
+   mFogHasAnswered++;
+   if (mFogHasAnswered == mNumFogObjects)
+   {
+      if (Resize())
+         smVolumetricFogRTMResizeSignal.trigger(this, false);
+      else
+         Con::errorf("VolumetricFogRTManager::FogAnswered - Error resizing rendertargets!");
+   }
+}
+   
+bool VolumetricFogRTManager::Resize()
+{
+   if (mTargetScale < 1)
+      mTargetScale = 1;
+   mWidth = mFloor(mPlatformWindow->getClientExtent().x / mTargetScale);
+   mHeight = mPlatformWindow->getClientExtent().y;
+     
+   if (!mPlatformWindow->isFullscreen())
+      mHeight -= 20;//subtract caption bar from rendertarget size.
+   mHeight = mFloor(mHeight / mTargetScale);
+   
+   if (mWidth < 16 || mHeight < 16)
+      return false;
+   
+   if (mFrontTarget.isRegistered())
+      mFrontTarget.setTexture(NULL);
+   
+   if (mDepthTarget.isRegistered())
+      mDepthTarget.setTexture(NULL);
+   
+   if (mDepthBuffer.isValid())
+      mDepthBuffer->kill();
+   
+   if (mFrontBuffer.isValid())
+      mFrontBuffer->kill();
+   
+   mFrontBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
+   &GFXDefaultRenderTargetProfile, avar("%s() - mFrontBuffer (line %d)", __FUNCTION__, __LINE__));
+   if (!mFrontBuffer.isValid())
+      {
+      Con::errorf("VolumetricFogRTManager::Resize() Fatal Error: Unable to create front buffer");
+      return false;
+      }
+   mFrontTarget.setTexture(mFrontBuffer);
+   
+   mDepthBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
+   &GFXDefaultRenderTargetProfile, avar("%s() - mDepthBuffer (line %d)", __FUNCTION__, __LINE__));
+   if (!mDepthBuffer.isValid())
+      {
+         Con::errorf("VolumetricFogRTManager::Resize() Fatal Error: Unable to create Depthbuffer");
+         return false;
+      }
+   mDepthTarget.setTexture(mDepthBuffer);
+   return true;
+}
+   
+S32 VolumetricFogRTManager::setQuality(U32 Quality)
+{
+   if (!mIsInitialized)
+      return (mTargetScale = Quality);
+      
+   if (Quality < 1)
+      Quality = 1;
+   
+   if (Quality == mTargetScale)
+      return mTargetScale;
+   
+   mTargetScale = Quality;
+   
+   mFogHasAnswered = 0;
+   smVolumetricFogRTMResizeSignal.trigger(this, true);
+   
+   return mTargetScale;
+}
+   
+VolumetricFogRTManager* VolumetricFogRTManager::get()
+{
+   return gVolumetricFogRTManager;
+}
+   
+DefineConsoleFunction(SetFogVolumeQuality, S32, (U32 new_quality), ,
+"@brief Resizes the rendertargets of the Volumetric Fog object.\n"
+"@params new_quality new quality for the rendertargets 1 = full size, 2 = halfsize, 3 = 1/3, 4 = 1/4 ...")
+{
+   if (VFRTM == NULL)
+      return -1;
+   return VFRTM->setQuality(new_quality);
+}

+ 92 - 0
Engine/source/environment/VolumetricFogRTManager.h

@@ -0,0 +1,92 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+   
+#ifndef _VolumetricFogRTManager_H_
+#define _VolumetricFogRTManager_H_
+   
+#ifndef _SCENEOBJECT_H_
+#include "scene/sceneObject.h"
+#endif
+#ifndef _MATTEXTURETARGET_H_
+#include "materials/matTextureTarget.h"
+#endif
+#ifndef _GFXTARGET_H_
+#include "gfx/gfxTarget.h"
+#endif
+#ifndef _SIGNAL_H_
+#include "core/util/tSignal.h"
+#endif
+   
+class VolumetricFogRTManager;
+   
+typedef Signal<void(VolumetricFogRTManager *VolumetricFogRTManager, bool resize)> VolumetricFogRTMResizeSignal;
+   
+#define VFRTM VolumetricFogRTManager::get()
+   
+class VolumetricFogRTManager : public SceneObject
+{
+   public:
+      typedef SceneObject Parent;
+   
+   protected:
+      GFXTexHandle mDepthBuffer;
+      GFXTexHandle mFrontBuffer;
+   
+      NamedTexTarget mDepthTarget;
+      NamedTexTarget mFrontTarget;
+   
+      PlatformWindow* mPlatformWindow;
+   
+      static S32 mTargetScale;
+      bool mIsInitialized;
+      U32 mNumFogObjects;
+      U32 mFogHasAnswered;
+      U32 mWidth;
+      U32 mHeight;
+      bool mFullScreen;
+   
+      void onRemove();
+      void onSceneRemove();
+      void ResizeRT(PlatformWindow *win, bool resize);
+   
+      static VolumetricFogRTMResizeSignal smVolumetricFogRTMResizeSignal;
+
+   public:
+      VolumetricFogRTManager();
+      ~VolumetricFogRTManager();
+      static VolumetricFogRTManager *get();
+      bool Init();
+      bool IsInitialized() { return mIsInitialized; }
+      static void consoleInit();
+      static VolumetricFogRTMResizeSignal& getVolumetricFogRTMResizeSignal() { return smVolumetricFogRTMResizeSignal; }
+      void FogAnswered();
+      S32 setQuality(U32 Quality);
+      bool Resize();
+      U32 IncFogObjects();
+      U32 DecFogObjects();
+   
+   DECLARE_CONOBJECT(VolumetricFogRTManager);
+};
+   
+extern VolumetricFogRTManager* gVolumetricFogRTManager;
+   
+#endif

+ 3 - 0
Engine/source/gui/core/guiCanvas.cpp

@@ -321,8 +321,11 @@ void GuiCanvas::setWindowTitle(const char *newTitle)
       mPlatformWindow->setCaption(newTitle);
 }
 
+CanvasSizeChangeSignal GuiCanvas::smCanvasSizeChangeSignal;
+
 void GuiCanvas::handleResize( WindowId did, S32 width, S32 height )
 {
+   getCanvasSizeChangeSignal().trigger(this);
 	if (Journal::IsPlaying() && mPlatformWindow)
 	{
 		mPlatformWindow->lockSize(false);

+ 10 - 0
Engine/source/gui/core/guiCanvas.h

@@ -33,6 +33,10 @@
 #include "platform/platformInput.h"
 #endif
 
+#ifndef _SIGNAL_H_
+#include "core/util/tSignal.h"
+#endif
+
 #include "component/interfaces/IProcessInput.h"
 #include "windowManager/platformWindowMgr.h"
 #include "gfx/gfxFence.h"
@@ -74,6 +78,8 @@
 /// screen will be painted normally. If you are making an animated GuiControl
 /// you need to add your control to the dirty areas of the canvas.
 ///
+class guiCanvas;
+typedef Signal<void(GuiCanvas* canvas)> CanvasSizeChangeSignal;
 class GuiCanvas : public GuiControl, public IProcessInput
 {
 
@@ -183,6 +189,8 @@ protected:
    virtual void setupFences();
    
    void checkLockMouseMove( const GuiEvent& event );
+   //Signal used to let others know this canvas has changed size.
+	static CanvasSizeChangeSignal smCanvasSizeChangeSignal;
 
    GuiControl *mMenuBarCtrl;
 
@@ -200,6 +208,8 @@ public:
 
    static void initPersistFields();
 
+   static CanvasSizeChangeSignal& getCanvasSizeChangeSignal() { return smCanvasSizeChangeSignal; }
+
    /// @name Rendering methods
    ///
    /// @{

+ 1 - 0
Engine/source/renderInstance/renderPassManager.cpp

@@ -53,6 +53,7 @@ const RenderInstType RenderPassManager::RIT_ObjectTranslucent("ObjectTranslucent
 const RenderInstType RenderPassManager::RIT_Decal("Decal");
 const RenderInstType RenderPassManager::RIT_Water("Water");
 const RenderInstType RenderPassManager::RIT_Foliage("Foliage");
+const RenderInstType RenderPassManager::RIT_VolumetricFog("ObjectVolumetricFog");
 const RenderInstType RenderPassManager::RIT_Translucent("Translucent");
 const RenderInstType RenderPassManager::RIT_Begin("Begin");
 const RenderInstType RenderPassManager::RIT_Custom("Custom");

+ 1 - 0
Engine/source/renderInstance/renderPassManager.h

@@ -110,6 +110,7 @@ public:
    static const RenderInstType RIT_Decal;
    static const RenderInstType RIT_Water;
    static const RenderInstType RIT_Foliage;
+   static const RenderInstType RIT_VolumetricFog;
    static const RenderInstType RIT_Translucent;
    static const RenderInstType RIT_Begin;
    static const RenderInstType RIT_Custom;

+ 10 - 0
Engine/source/renderInstance/renderTranslucentMgr.cpp

@@ -51,6 +51,7 @@ RenderTranslucentMgr::RenderTranslucentMgr()
 {
    notifyType( RenderPassManager::RIT_ObjectTranslucent );
    notifyType( RenderPassManager::RIT_Particle );
+   notifyType( RenderPassManager::RIT_VolumetricFog);
 }
 
 RenderTranslucentMgr::~RenderTranslucentMgr()
@@ -187,6 +188,15 @@ void RenderTranslucentMgr::render( SceneRenderState *state )
          j++;
          continue;
       }
+      else if (baseRI->type == RenderPassManager::RIT_VolumetricFog)
+	   {
+	      ObjectRenderInst* objRI = static_cast<ObjectRenderInst*>(baseRI);
+	      objRI->renderDelegate(objRI, state, NULL);
+	      lastVB = NULL;
+	      lastPB = NULL;
+	      j++;
+	      continue;
+	   }
       else if ( baseRI->type == RenderPassManager::RIT_Particle )
       {
          ParticleRenderInst *ri = static_cast<ParticleRenderInst*>(baseRI);

+ 6 - 1
Engine/source/windowManager/platformWindow.cpp

@@ -22,7 +22,7 @@
 
 #include "windowManager/platformWindow.h"
 
-
+ScreenResChangeSignal PlatformWindow::smScreenResChangeSignal;
 //-----------------------------------------------------------------------------
 
 void PlatformWindow::setFullscreen( const bool fullscreen )
@@ -48,3 +48,8 @@ bool PlatformWindow::shouldNotTranslate( U32 modifiers, U32 keyCode ) const
    else
       return false;
 }
+void PlatformWindow::setVideoMode(const GFXVideoMode &mode)
+{
+   _setVideoMode(mode);
+	getScreenResChangeSignal().trigger(this, true);
+}

+ 8 - 3
Engine/source/windowManager/platformWindow.h

@@ -28,6 +28,9 @@
 #include "core/util/safeDelete.h"
 #include "windowManager/platformCursorController.h"
 #include "windowManager/windowInputGenerator.h"
+#ifndef _SIGNAL_H_ //Volumetric Fog
+#include "core/util/tSignal.h"
+#endif
 
 //forward decl's
 class PlatformWindowManager;
@@ -35,7 +38,7 @@ class GFXDevice;
 struct GFXVideoMode;
 class GFXWindowTarget;
 class IProcessInput;
-
+typedef Signal<void(PlatformWindow *PlatformWindow, bool resize)> ScreenResChangeSignal;
 /// Abstract representation of a native OS window.
 ///
 /// Every windowing system has its own representations and conventions as
@@ -110,7 +113,7 @@ protected:
       // This controller maps window input (Mouse/Keyboard) to a generic input consumer
       mWindowInputGenerator = new WindowInputGenerator( this );
    }
-
+   static ScreenResChangeSignal smScreenResChangeSignal;
 public:
 
    /// To get rid of a window, just delete it. Make sure the GFXDevice is
@@ -158,7 +161,7 @@ public:
    virtual GFXWindowTarget *getGFXTarget()=0;
 
    /// Set the video mode for this window.
-   virtual void setVideoMode(const GFXVideoMode &mode)=0;
+   virtual void setVideoMode(const GFXVideoMode &mode);
 
    /// Get our current video mode - if the window has been resized, it will
    /// reflect this.
@@ -497,6 +500,7 @@ public:
    IdleEvent         idleEvent;
 
    /// @}
+   static ScreenResChangeSignal& getScreenResChangeSignal() { return smScreenResChangeSignal; }
    
    /// Get the platform specific object needed to create or attach an accelerated
    /// graohics drawing context on or to the window
@@ -507,6 +511,7 @@ public:
    virtual void* getPlatformDrawable() const = 0;
 protected:
    virtual void _setFullscreen(const bool fullScreen) {};
+   virtual void _setVideoMode(const GFXVideoMode &mode) {};
 };
 
 #endif

+ 2 - 0
Engine/source/windowManager/win32/win32Window.cpp

@@ -287,6 +287,8 @@ void Win32Window::setVideoMode( const GFXVideoMode &mode )
 		mOwningManager->raiseCurtain();
 
 	SetForegroundWindow(getHWND());
+
+   getScreenResChangeSignal().trigger(this, true);
 }
 
 bool Win32Window::clearFullscreen()

BIN
Templates/Empty/game/art/environment/FogMod_heavy.dds


BIN
Templates/Empty/game/art/environment/FogMod_light.dds


BIN
Templates/Empty/game/art/environment/FogMod_med.dds


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 97 - 0
Templates/Empty/game/art/environment/Fog_Cube.DAE


+ 8 - 0
Templates/Empty/game/art/environment/Fog_Cube.cs

@@ -0,0 +1,8 @@
+
+singleton TSShapeConstructor(Fog_CubeDAE)
+{
+   baseShape = "./Fog_Cube.DAE";
+   lodType = "TrailingNumber";
+   neverImport = "env*";
+   loadLights = "0";
+};

+ 76 - 0
Templates/Empty/game/core/scripts/client/postFx/glow.cs

@@ -106,3 +106,79 @@ singleton PostEffect( GlowPostFx )
       target = "$backBuffer";
    };
 };
+
+singleton ShaderData( PFX_VolFogGlowBlurVertShader )
+{
+	DXVertexShaderFile = "shaders/common/postFx/glowBlurV.hlsl";
+	DXPixelShaderFile = "shaders/common/postFx/VolFogGlowP.hlsl";
+	
+	OGLVertexShaderFile = "shaders/common/postFx/gl/glowBlurV.glsl";
+	OGLPixelShaderFile = "shaders/common/postFx/gl/VolFogGlowP.glsl";	
+	
+	defines = "BLUR_DIR=float2(0.0,1.0)";
+	samplerNames[0] = "$diffuseMap";
+	pixVersion = 2.0;
+};
+singleton ShaderData( PFX_VolFogGlowBlurHorzShader : PFX_VolFogGlowBlurVertShader )
+{
+	DXVertexShaderFile = "shaders/common/postFx/glowBlurV.hlsl";
+	DXPixelShaderFile = "shaders/common/postFx/VolFogGlowP.hlsl";
+	
+	OGLVertexShaderFile = "shaders/common/postFx/gl/glowBlurV.glsl";
+	OGLPixelShaderFile = "shaders/common/postFx/gl/VolFogGlowP.glsl";
+	
+	defines = "BLUR_DIR=float2(1.0,0.0)";
+};
+
+$VolFogGlowPostFx::glowStrength = 0.3;
+
+singleton PostEffect( VolFogGlowPostFx )
+{
+	// Do not allow the glow effect to work in reflection
+	// passes by default so we don't do the extra drawing.
+	allowReflectPass = false;
+	renderTime = "PFXAfterBin";
+	renderBin = "FogBin";
+	renderPriority = 1;
+	// First we down sample the glow buffer.
+	shader = PFX_PassthruShader;
+	stateBlock = PFX_DefaultStateBlock;
+	texture[0] = "$backbuffer";
+	target = "$outTex";
+	targetScale = "0.5 0.5";
+	isEnabled = true;
+	// Blur vertically
+	new PostEffect()
+	{
+		shader = PFX_VolFogGlowBlurVertShader;
+		stateBlock = PFX_DefaultStateBlock;
+		internalName = "vert";
+		texture[0] = "$inTex";
+		target = "$outTex";
+	};
+	// Blur horizontally
+	new PostEffect()
+	{
+		shader = PFX_VolFogGlowBlurHorzShader;
+		stateBlock = PFX_DefaultStateBlock;
+		internalName = "hor";
+		texture[0] = "$inTex";
+		target = "$outTex";
+	};
+	// Upsample and combine with the back buffer.
+	new PostEffect()
+	{
+		shader = PFX_PassthruShader;
+		stateBlock = PFX_GlowCombineStateBlock;
+		texture[0] = "$inTex";
+		target = "$backBuffer";
+	};
+};
+
+function VolFogGlowPostFx::setShaderConsts( %this )
+{
+	%vp=%this-->vert;
+	%vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength );
+	%vp=%this-->hor;
+	%vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength );
+}

+ 1 - 0
Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.settings.cs

@@ -70,6 +70,7 @@ function PostFXManager::settingsSetEnabled(%this, %bEnablePostFX)
       
       postVerbose("% - PostFX Manager - PostFX disabled");
    }
+   VolFogGlowPostFx.disable();
 }
 
 function PostFXManager::settingsEffectSetEnabled(%this, %sName, %bEnable)

+ 2 - 0
Templates/Empty/game/core/scripts/client/renderManager.cs

@@ -75,6 +75,8 @@ function initRenderManager()
 	DiffuseRenderPassManager.addManager( new RenderParticleMgr()            { renderOrder = 1.35; processAddOrder = 1.35; } );
    DiffuseRenderPassManager.addManager( new RenderTranslucentMgr()         { renderOrder = 1.4; processAddOrder = 1.4; } );
    
+   DiffuseRenderPassManager.addManager(new RenderObjectMgr(FogBin){ bintype = "ObjectVolumetricFog"; renderOrder = 1.45; processAddOrder = 1.45; } );
+   
    // Note that the GlowPostFx is triggered after this bin.
    DiffuseRenderPassManager.addManager( new RenderGlowMgr(GlowBin) { renderOrder = 1.5; processAddOrder = 1.5; } );
    

+ 106 - 0
Templates/Empty/game/scripts/server/VolumetricFog.cs

@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+function VolumetricFog::onEnterFog(%this,%obj)
+{
+   // This method is called whenever the control object (Camera or Player)
+   // %obj enters the fog area.
+   
+   // echo("Control Object " @ %obj @ " enters fog " @ %this);
+}
+
+function VolumetricFog::onLeaveFog(%this,%obj)
+{
+   // This method is called whenever the control object (Camera or Player)
+   // %obj leaves the fog area.
+   
+   // echo("Control Object " @ %obj @ " left fog " @ %this);
+}
+
+function VolumetricFog::Dissolve(%this,%speed,%delete)
+{
+   // This method dissolves the fog at speed milliseconds
+   %this.isBuilding = true;
+   if (%this.FogDensity > 0)
+   {
+      %this.setFogDensity(%this.FogDensity - 0.005);
+      %this.schedule(%speed,Dissolve,%speed,%delete);
+   }
+   else
+   {
+      %this.isBuilding = false;
+      %this.SetFogDensity(0.0);
+      if (%delete !$= "" && %delete !$="0" && %delete !$="false")
+         %this.schedule(250,delete);
+   }
+}
+
+function VolumetricFog::Thicken(%this,%speed, %end_density)
+{
+   // This method thickens the fog at speed milliseconds to a density of %end_density
+
+   %this.isBuilding = true;
+   if (%this.FogDensity + 0.005 < %end_density)
+   {
+      %this.setFogDensity(%this.FogDensity + 0.005);
+      %this.schedule(%speed,Thicken,%speed, %end_density);
+   }
+   else
+   {
+      %this.setFogDensity(%end_density);
+      %this.isBuilding = false;
+   }
+}
+ 
+function GenerateFog(%pos,%scale,%color,%density)
+{
+   // This function can be used to generate some fog caused by massive gunfire etc.
+   // Change shape and modulation data to your likings.
+   
+   %fog=new VolumetricFog() {
+      shapeName = "art/environment/Fog_Sphere.dts";
+      fogColor = %color;
+      fogDensity = "0.0";
+      ignoreWater = "0";
+      MinSize = "250";
+      FadeSize = "750";
+      texture = "art/environment/FogMod_heavy.dds";
+      tiles = "1";
+      modStrength = "0.2";
+      PrimSpeed = "-0.01 0.04";
+      SecSpeed = "0.02 0.02";
+      position = %pos;
+      rotation = "0 0 1 20.354";
+      scale = %scale;
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   
+   if (isObject(%fog))
+   {
+      MissionCleanup.add(%fog);
+      
+      %fog.Thicken(500,%density);
+   }
+   
+   return %fog;
+}

+ 1 - 0
Templates/Empty/game/scripts/server/scriptExec.cs

@@ -22,3 +22,4 @@
 
 // Load up all scripts.  This function is called when
 // a server is constructed.
+exec("./VolumetricFog.cs");

+ 87 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogP.hlsl

@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog final pixel shader V2.00
+
+#include "shadergen:/autogenConditioners.h"
+#include "../torque.hlsl"
+
+uniform sampler2D prepassTex : register(S0);
+uniform sampler2D depthBuffer : register(S1);
+uniform sampler2D frontBuffer : register(S2);
+uniform sampler2D density : register(S3);
+  
+uniform float accumTime;
+uniform float4 fogColor;
+uniform float fogDensity;
+uniform float preBias;
+uniform float textured;
+uniform float modstrength;
+uniform float4 modspeed;//xy speed layer 1, zw speed layer 2
+uniform float2 viewpoint;
+uniform float2 texscale;
+uniform float3 ambientColor;
+uniform float numtiles;
+uniform float fadesize;
+uniform float2 PixelSize;
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 htpos : TEXCOORD0;
+   float2 uv0 : TEXCOORD1;
+};
+
+float4 main( ConnectData IN ) : COLOR0
+{
+	float2 uvscreen=((IN.htpos.xy/IN.htpos.w) + 1.0 ) / 2.0;
+	uvscreen.y = 1.0 - uvscreen.y;
+	
+	float obj_test = prepassUncondition( prepassTex, uvscreen).w * preBias;
+	float depth = tex2D(depthBuffer,uvscreen).r;
+	float front = tex2D(frontBuffer,uvscreen).r;
+
+	if (depth <= front)
+		return float4(0,0,0,0);
+	else if ( obj_test < depth )
+		depth = obj_test;
+	if ( front >= 0.0)
+		depth -= front;
+
+	float diff = 1.0;
+	float3 col = fogColor.rgb;
+	if (textured != 0.0)
+	{
+		float2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles);
+
+		float2 mod1 = tex2D(density,(offset + (modspeed.xy*accumTime))).rg;
+		float2 mod2= tex2D(density,(offset + (modspeed.zw*accumTime))).rg;
+		diff = (mod2.r + mod1.r) * modstrength;
+		col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0;
+	}
+
+	col *= ambientColor;
+
+	float4 resultColor = float4(col, 1.0 - saturate(exp(-fogDensity  * depth * diff * fadesize)));
+
+	return hdrEncode(resultColor);
+}

+ 39 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogPreP.hlsl

@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog prepass pixel shader V1.00
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 pos : TEXCOORD0;
+};
+
+float4 main( ConnectData IN ) : COLOR0
+{
+   float OUT;
+   
+   clip( IN.pos.w );
+   OUT = IN.pos.w;
+
+   return float4(OUT,0,0,1);
+}

+ 46 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogPreV.hlsl

@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog prepass vertex shader V1.00
+
+#include "shaders/common/hlslstructs.h"
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 pos : TEXCOORD0;
+};
+
+uniform float4x4 modelView;
+
+ConnectData main( VertexIn_P IN)    
+{
+	ConnectData OUT;
+	
+	float4 inPos = IN.pos;
+	inPos.w = 1.0;
+ 
+	OUT.hpos = mul( modelView, inPos );
+    OUT.pos = OUT.hpos;
+
+    return OUT;  
+}

+ 36 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogRefl.hlsl

@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+uniform float4 fogColor;
+uniform float fogDensity;
+uniform float reflStrength;
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 pos : TEXCOORD0;
+};
+
+float4 main( ConnectData IN ) : COLOR0
+{
+   return float4(fogColor.rgb,saturate(fogDensity*reflStrength));
+}

+ 45 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogV.hlsl

@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog final vertex shader V1.00
+
+#include "shaders/common/hlslstructs.h"
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 htpos : TEXCOORD0;
+   float2 uv0 : TEXCOORD1;
+};
+
+uniform float4x4 modelView;
+
+ConnectData main( VertexIn_PNT IN)    
+{  
+    ConnectData OUT;
+	
+	OUT.hpos = mul(modelView, IN.pos);
+	OUT.htpos = OUT.hpos;
+	OUT.uv0 = IN.uv0;
+	
+    return OUT;  
+}

+ 87 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogP.glsl

@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+#include "shadergen:/autogenConditioners.h"
+#include "../../gl/torque.glsl"
+
+uniform sampler2D prepassTex;
+uniform sampler2D depthBuffer;
+uniform sampler2D frontBuffer;
+uniform sampler2D density;
+  
+uniform float accumTime;
+uniform vec4 fogColor;
+uniform float fogDensity;
+uniform float preBias;
+uniform float textured;
+uniform float modstrength;
+uniform vec4 modspeed;//xy speed layer 1, zw speed layer 2
+uniform vec2 viewpoint;
+uniform vec2 texscale;
+uniform vec3 ambientColor;
+uniform float numtiles;
+uniform float fadesize;
+uniform vec2 PixelSize;
+
+in vec4 _hpos;
+#define IN_hpos _hpos
+out vec4 OUT_col;
+
+void main()
+{
+	vec2 uvscreen=((IN_hpos.xy/IN_hpos.w) + 1.0 ) / 2.0;
+	uvscreen.y = 1.0 - uvscreen.y;
+	
+	float obj_test = prepassUncondition( prepassTex, uvscreen).w * preBias;
+	float depth = tex2D(depthBuffer,uvscreen).r;
+	float front = tex2D(frontBuffer,uvscreen).r;
+
+	if (depth <= front)
+	{
+		OUT_col = vec4(0,0,0,0);
+		return;
+	}
+	
+	else if ( obj_test < depth )
+		depth = obj_test;
+	if ( front >= 0.0)
+		depth -= front;
+
+	float diff = 1.0;
+	vec3 col = fogColor.rgb;
+	if (textured != 0.0)
+	{
+		vec2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles);
+
+		vec2 mod1 = tex2D(density,(offset + (modspeed.xy*accumTime))).rg;
+		vec2 mod2= tex2D(density,(offset + (modspeed.zw*accumTime))).rg;
+		diff = (mod2.r + mod1.r) * modstrength;
+		col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0;
+	}
+
+   col *= ambientColor;
+
+   vec4 returnColor = vec4(col, 1.0 - saturate(exp(-fogDensity  * depth * diff * fadesize)));
+
+	OUT_col = hdrEncode(returnColor);
+}

+ 37 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogPreP.glsl

@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+in vec4 _hpos;
+#define IN_hpos _hpos
+
+out vec4 OUT_col;
+
+void main()
+{
+   float OUT;
+   clip( IN_hpos.w );
+   OUT = IN_hpos.w;
+
+   OUT_col = vec4(OUT,0,0,1);
+}

+ 42 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogPreV.glsl

@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+#define IN_position vPosition
+
+out vec4 _hpos;
+#define OUT_hpos _hpos
+
+uniform mat4 modelView;
+
+void main()
+{
+	vec4 inPos = IN_position;
+	inPos.w = 1.0;
+ 
+	OUT_hpos = tMul( modelView, inPos );
+
+	gl_Position = OUT_hpos;
+	correctSSP(gl_Position);
+}

+ 33 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogRefl.glsl

@@ -0,0 +1,33 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+uniform vec4 fogColor;
+uniform float fogDensity;
+uniform float reflStrength;
+out vec4 OUT_col;
+
+void main()
+{
+   OUT_col = vec4(fogColor.rgb,saturate(fogDensity*reflStrength));
+}

+ 38 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogV.glsl

@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+#define IN_position vPosition
+
+out vec4 _hpos;
+#define OUT_hpos _hpos
+
+uniform mat4 modelView;
+
+void main()    
+{  
+	OUT_hpos = tMul(modelView, IN_position);
+	gl_Position = OUT_hpos;
+	correctSSP(gl_Position);
+}

+ 74 - 0
Templates/Empty/game/shaders/common/postFx/VolFogGlowP.hlsl

@@ -0,0 +1,74 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 R.G.S. - Richards Game Studio, the Netherlands
+//					  http://www.richardsgamestudio.com/
+//
+// If you find this code useful or you are feeling particularly generous I
+// would ask that you please go to http://www.richardsgamestudio.com/ then
+// choose Donations from the menu on the left side and make a donation to
+// Richards Game Studio. It will be highly appreciated.
+//
+// The MIT License:
+//
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog Glow postFx pixel shader V1.00
+
+#include "./postFx.hlsl"
+
+uniform sampler2D diffuseMap : register(S0);
+uniform float strength;
+
+struct VertToPix
+{
+   float4 hpos       : POSITION;
+
+   float2 uv0        : TEXCOORD0;
+   float2 uv1        : TEXCOORD1;
+   float2 uv2        : TEXCOORD2;
+   float2 uv3        : TEXCOORD3;
+
+   float2 uv4        : TEXCOORD4;
+   float2 uv5        : TEXCOORD5;
+   float2 uv6        : TEXCOORD6;
+   float2 uv7        : TEXCOORD7;
+};
+
+float4 main( VertToPix IN ) : COLOR
+{
+   float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * strength;
+
+   float4 OUT = 0;
+   OUT += tex2D( diffuseMap, IN.uv0 ) * kernel.x;
+   OUT += tex2D( diffuseMap, IN.uv1 ) * kernel.y;
+   OUT += tex2D( diffuseMap, IN.uv2 ) * kernel.z;
+   OUT += tex2D( diffuseMap, IN.uv3 ) * kernel.w;
+
+   OUT += tex2D( diffuseMap, IN.uv4 ) * kernel.x;
+   OUT += tex2D( diffuseMap, IN.uv5 ) * kernel.y;
+   OUT += tex2D( diffuseMap, IN.uv6 ) * kernel.z;
+   OUT += tex2D( diffuseMap, IN.uv7 ) * kernel.w;
+
+   // Calculate a lumenance value in the alpha so we
+   // can use alpha test to save fillrate.
+   float3 rgb2lum = float3( 0.30, 0.59, 0.11 );
+   OUT.a = dot( OUT.rgb, rgb2lum );
+
+   return OUT;
+}

+ 67 - 0
Templates/Empty/game/shaders/common/postFx/gl/VolFogGlowP.glsl

@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 R.G.S. - Richards Game Studio, the Netherlands
+//					  http://www.richardsgamestudio.com/
+//
+// If you find this code useful or you are feeling particularly generous I
+// would ask that you please go to http://www.richardsgamestudio.com/ then
+// choose Donations from the menu on the left side and make a donation to
+// Richards Game Studio. It will be highly appreciated.
+//
+// The MIT License:
+//
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog Glow postFx pixel shader V1.00
+
+uniform sampler2D diffuseMap;
+uniform float strength;
+
+out vec4 OUT_col;
+
+in vec2 uv0;
+in vec2 uv1;
+in vec2 uv2;
+in vec2 uv3;
+
+in vec2 uv4;
+in vec2 uv5;
+in vec2 uv6;
+in vec2 uv7;
+
+void main()
+{
+   vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ) * strength;
+
+   OUT_col = vec4(0);
+   OUT_col += texture( diffuseMap, uv0 ) * kernel.x;
+   OUT_col += texture( diffuseMap, uv1 ) * kernel.y;
+   OUT_col += texture( diffuseMap, uv2 ) * kernel.z;
+   OUT_col += texture( diffuseMap, uv3 ) * kernel.w;
+
+   OUT_col += texture( diffuseMap, uv4 ) * kernel.x;
+   OUT_col += texture( diffuseMap, uv5 ) * kernel.y;
+   OUT_col += texture( diffuseMap, uv6 ) * kernel.z;
+   OUT_col += texture( diffuseMap, uv7 ) * kernel.w;
+
+   // Calculate a lumenance value in the alpha so we
+   // can use alpha test to save fillrate.
+   vec3 rgb2lum = vec3( 0.30, 0.59, 0.11 );
+   OUT_col.a = dot( OUT_col.rgb, rgb2lum );
+}

BIN
Templates/Empty/game/tools/classIcons/VolumetricFog.png


+ 13 - 1
Templates/Empty/game/tools/worldEditor/gui/objectBuilderGui.ed.gui

@@ -980,7 +980,19 @@ function ObjectBuilderGui::buildObserverDropPoint(%this)
 //------------------------------------------------------------------------------
 // System
 //------------------------------------------------------------------------------
-
+function ObjectBuilderGui::buildVolumetricFog(%this)
+{
+	// Change this if you want to default to another Folder
+	// Otherwise every time you want to add a Fog you will go this.
+	%defShape = "/art/environment/Fog_Cube.dts";
+	%this.lastPath=getMainDotCsDir() @ %defShape;
+	OBObjectName.setValue( "" );
+	%this.objectClassName = "VolumetricFog";
+	%this.addField( "shapeName", "TypeFile", "Shape (Fog volume)", "", "*.dts;*.dae");
+	%this.addField("Scale", "TypePoint3", "Scale", "1 1 1");
+	%this.addField("FogColor", "TypeColorI", "FogColor", "200 200 200 255");
+	%this.process();
+}
 function ObjectBuilderGui::buildPhysicsEntity(%this)
 {
    %this.objectClassName = "PhysicsEntity";

+ 1 - 0
Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs

@@ -46,6 +46,7 @@ function EWCreatorWindow::init( %this )
       %this.registerMissionObject( "SFXEmitter",          "Sound Emitter" );
       %this.registerMissionObject( "Precipitation" );
       %this.registerMissionObject( "ParticleEmitterNode", "Particle Emitter" );
+      %this.registerMissionObject( "VolumetricFog",       "Volumetric Fog" );
       %this.registerMissionObject( "RibbonNode", "Ribbon" );
       
       // Legacy features. Users should use Ground Cover and the Forest Editor.   

BIN
Templates/Full/game/art/environment/FogMod_heavy.dds


BIN
Templates/Full/game/art/environment/FogMod_light.dds


BIN
Templates/Full/game/art/environment/FogMod_med.dds


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 97 - 0
Templates/Full/game/art/environment/Fog_Cube.DAE


+ 8 - 0
Templates/Full/game/art/environment/Fog_Cube.cs

@@ -0,0 +1,8 @@
+
+singleton TSShapeConstructor(Fog_CubeDAE)
+{
+   baseShape = "./Fog_Cube.DAE";
+   lodType = "TrailingNumber";
+   neverImport = "env*";
+   loadLights = "0";
+};

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 77 - 0
Templates/Full/game/art/environment/LightVolume_Sphere.DAE


+ 8 - 0
Templates/Full/game/art/environment/LightVolume_Sphere.cs

@@ -0,0 +1,8 @@
+
+singleton TSShapeConstructor(LightVolume_SphereDAE)
+{
+   baseShape = "./LightVolume_Sphere.DAE";
+   lodType = "TrailingNumber";
+   neverImport = "env*";
+   loadLights = "0";
+};

BIN
Templates/Full/game/art/environment/LightVolume_Sphere.dts


+ 76 - 0
Templates/Full/game/core/scripts/client/postFx/glow.cs

@@ -106,3 +106,79 @@ singleton PostEffect( GlowPostFx )
       target = "$backBuffer";
    };
 };
+
+singleton ShaderData( PFX_VolFogGlowBlurVertShader )
+{
+	DXVertexShaderFile = "shaders/common/postFx/glowBlurV.hlsl";
+	DXPixelShaderFile = "shaders/common/postFx/VolFogGlowP.hlsl";
+	
+	OGLVertexShaderFile = "shaders/common/postFx/gl/glowBlurV.glsl";
+	OGLPixelShaderFile = "shaders/common/postFx/gl/VolFogGlowP.glsl";	
+	
+	defines = "BLUR_DIR=float2(0.0,1.0)";
+	samplerNames[0] = "$diffuseMap";
+	pixVersion = 2.0;
+};
+singleton ShaderData( PFX_VolFogGlowBlurHorzShader : PFX_VolFogGlowBlurVertShader )
+{
+	DXVertexShaderFile = "shaders/common/postFx/glowBlurV.hlsl";
+	DXPixelShaderFile = "shaders/common/postFx/VolFogGlowP.hlsl";
+	
+	OGLVertexShaderFile = "shaders/common/postFx/gl/glowBlurV.glsl";
+	OGLPixelShaderFile = "shaders/common/postFx/gl/VolFogGlowP.glsl";
+	
+	defines = "BLUR_DIR=float2(1.0,0.0)";
+};
+
+$VolFogGlowPostFx::glowStrength = 0.3;
+
+singleton PostEffect( VolFogGlowPostFx )
+{
+	// Do not allow the glow effect to work in reflection
+	// passes by default so we don't do the extra drawing.
+	allowReflectPass = false;
+	renderTime = "PFXAfterBin";
+	renderBin = "FogBin";
+	renderPriority = 1;
+	// First we down sample the glow buffer.
+	shader = PFX_PassthruShader;
+	stateBlock = PFX_DefaultStateBlock;
+	texture[0] = "$backbuffer";
+	target = "$outTex";
+	targetScale = "0.5 0.5";
+	isEnabled = true;
+	// Blur vertically
+	new PostEffect()
+	{
+		shader = PFX_VolFogGlowBlurVertShader;
+		stateBlock = PFX_DefaultStateBlock;
+		internalName = "vert";
+		texture[0] = "$inTex";
+		target = "$outTex";
+	};
+	// Blur horizontally
+	new PostEffect()
+	{
+		shader = PFX_VolFogGlowBlurHorzShader;
+		stateBlock = PFX_DefaultStateBlock;
+		internalName = "hor";
+		texture[0] = "$inTex";
+		target = "$outTex";
+	};
+	// Upsample and combine with the back buffer.
+	new PostEffect()
+	{
+		shader = PFX_PassthruShader;
+		stateBlock = PFX_GlowCombineStateBlock;
+		texture[0] = "$inTex";
+		target = "$backBuffer";
+	};
+};
+
+function VolFogGlowPostFx::setShaderConsts( %this )
+{
+	%vp=%this-->vert;
+	%vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength );
+	%vp=%this-->hor;
+	%vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength );
+}

+ 1 - 0
Templates/Full/game/core/scripts/client/postFx/postFxManager.gui.settings.cs

@@ -70,6 +70,7 @@ function PostFXManager::settingsSetEnabled(%this, %bEnablePostFX)
       
       postVerbose("% - PostFX Manager - PostFX disabled");
    }
+   VolFogGlowPostFx.disable();
 }
 
 function PostFXManager::settingsEffectSetEnabled(%this, %sName, %bEnable)

+ 2 - 0
Templates/Full/game/core/scripts/client/renderManager.cs

@@ -75,6 +75,8 @@ function initRenderManager()
 	DiffuseRenderPassManager.addManager( new RenderParticleMgr()            { renderOrder = 1.35; processAddOrder = 1.35; } );
    DiffuseRenderPassManager.addManager( new RenderTranslucentMgr()         { renderOrder = 1.4; processAddOrder = 1.4; } );
    
+   DiffuseRenderPassManager.addManager(new RenderObjectMgr(FogBin){ bintype = "ObjectVolumetricFog"; renderOrder = 1.45; processAddOrder = 1.45; } );
+   
    // Note that the GlowPostFx is triggered after this bin.
    DiffuseRenderPassManager.addManager( new RenderGlowMgr(GlowBin) { renderOrder = 1.5; processAddOrder = 1.5; } );
    

+ 36 - 0
Templates/Full/game/core/scripts/client/shaders.cs

@@ -101,4 +101,40 @@ new ShaderData( fxFoliageReplicatorShader )
    samplerNames[1] = "$alphaMap";
    
    pixVersion = 1.4;
+};
+
+singleton ShaderData( VolumetricFogPrePassShader )
+{
+   DXVertexShaderFile = "shaders/common/VolumetricFog/VFogPreV.hlsl";
+   DXPixelShaderFile = "shaders/common/VolumetricFog/VFogPreP.hlsl";
+	
+   OGLVertexShaderFile  = "shaders/common/VolumetricFog/gl/VFogPreV.glsl";
+   OGLPixelShaderFile   = "shaders/common/VolumetricFog/gl/VFogPreP.glsl";
+   
+   pixVersion = 3.0;
+};
+singleton ShaderData( VolumetricFogShader )
+{
+   DXVertexShaderFile = "shaders/common/VolumetricFog/VFogV.hlsl";
+   DXPixelShaderFile = "shaders/common/VolumetricFog/VFogP.hlsl";
+	
+   OGLVertexShaderFile  = "shaders/common/VolumetricFog/gl/VFogV.glsl";
+   OGLPixelShaderFile   = "shaders/common/VolumetricFog/gl/VFogP.glsl";	
+	
+   samplerNames[0] = "$prepassTex";
+   samplerNames[1] = "$depthBuffer";
+   samplerNames[2] = "$frontBuffer";
+   samplerNames[3] = "$density";
+   
+   pixVersion = 3.0;
+};
+singleton ShaderData( VolumetricFogReflectionShader )
+{
+   DXVertexShaderFile = "shaders/common/VolumetricFog/VFogPreV.hlsl";
+   DXPixelShaderFile = "shaders/common/VolumetricFog/VFogRefl.hlsl";
+	
+   OGLVertexShaderFile  = "shaders/common/VolumetricFog/gl/VFogPreV.glsl";
+   OGLPixelShaderFile   = "shaders/common/VolumetricFog/gl/VFogRefl.glsl";
+	
+   pixVersion = 3.0;
 };

+ 106 - 0
Templates/Full/game/scripts/server/VolumetricFog.cs

@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+function VolumetricFog::onEnterFog(%this,%obj)
+{
+   // This method is called whenever the control object (Camera or Player)
+   // %obj enters the fog area.
+   
+   // echo("Control Object " @ %obj @ " enters fog " @ %this);
+}
+
+function VolumetricFog::onLeaveFog(%this,%obj)
+{
+   // This method is called whenever the control object (Camera or Player)
+   // %obj leaves the fog area.
+   
+   // echo("Control Object " @ %obj @ " left fog " @ %this);
+}
+
+function VolumetricFog::Dissolve(%this,%speed,%delete)
+{
+   // This method dissolves the fog at speed milliseconds
+   %this.isBuilding = true;
+   if (%this.FogDensity > 0)
+   {
+      %this.setFogDensity(%this.FogDensity - 0.005);
+      %this.schedule(%speed,Dissolve,%speed,%delete);
+   }
+   else
+   {
+      %this.isBuilding = false;
+      %this.SetFogDensity(0.0);
+      if (%delete !$= "" && %delete !$="0" && %delete !$="false")
+         %this.schedule(250,delete);
+   }
+}
+
+function VolumetricFog::Thicken(%this,%speed, %end_density)
+{
+   // This method thickens the fog at speed milliseconds to a density of %end_density
+
+   %this.isBuilding = true;
+   if (%this.FogDensity + 0.005 < %end_density)
+   {
+      %this.setFogDensity(%this.FogDensity + 0.005);
+      %this.schedule(%speed,Thicken,%speed, %end_density);
+   }
+   else
+   {
+      %this.setFogDensity(%end_density);
+      %this.isBuilding = false;
+   }
+}
+ 
+function GenerateFog(%pos,%scale,%color,%density)
+{
+   // This function can be used to generate some fog caused by massive gunfire etc.
+   // Change shape and modulation data to your likings.
+   
+   %fog=new VolumetricFog() {
+      shapeName = "art/environment/Fog_Sphere.dts";
+      fogColor = %color;
+      fogDensity = "0.0";
+      ignoreWater = "0";
+      MinSize = "250";
+      FadeSize = "750";
+      texture = "art/environment/FogMod_heavy.dds";
+      tiles = "1";
+      modStrength = "0.2";
+      PrimSpeed = "-0.01 0.04";
+      SecSpeed = "0.02 0.02";
+      position = %pos;
+      rotation = "0 0 1 20.354";
+      scale = %scale;
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   
+   if (isObject(%fog))
+   {
+      MissionCleanup.add(%fog);
+      
+      %fog.Thicken(500,%density);
+   }
+   
+   return %fog;
+}

+ 1 - 0
Templates/Full/game/scripts/server/scriptExec.cs

@@ -24,6 +24,7 @@
 // a server is constructed.
 exec("./camera.cs");
 exec("./triggers.cs");
+exec("./VolumetricFog.cs");
 exec("./inventory.cs");
 exec("./shapeBase.cs");
 exec("./item.cs");

+ 87 - 0
Templates/Full/game/shaders/common/VolumetricFog/VFogP.hlsl

@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog final pixel shader V2.00
+
+#include "shadergen:/autogenConditioners.h"
+#include "../torque.hlsl"
+
+uniform sampler2D prepassTex : register(S0);
+uniform sampler2D depthBuffer : register(S1);
+uniform sampler2D frontBuffer : register(S2);
+uniform sampler2D density : register(S3);
+  
+uniform float accumTime;
+uniform float4 fogColor;
+uniform float fogDensity;
+uniform float preBias;
+uniform float textured;
+uniform float modstrength;
+uniform float4 modspeed;//xy speed layer 1, zw speed layer 2
+uniform float2 viewpoint;
+uniform float2 texscale;
+uniform float3 ambientColor;
+uniform float numtiles;
+uniform float fadesize;
+uniform float2 PixelSize;
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 htpos : TEXCOORD0;
+   float2 uv0 : TEXCOORD1;
+};
+
+float4 main( ConnectData IN ) : COLOR0
+{
+	float2 uvscreen=((IN.htpos.xy/IN.htpos.w) + 1.0 ) / 2.0;
+	uvscreen.y = 1.0 - uvscreen.y;
+	
+	float obj_test = prepassUncondition( prepassTex, uvscreen).w * preBias;
+	float depth = tex2D(depthBuffer,uvscreen).r;
+	float front = tex2D(frontBuffer,uvscreen).r;
+
+	if (depth <= front)
+		return float4(0,0,0,0);
+	else if ( obj_test < depth )
+		depth = obj_test;
+	if ( front >= 0.0)
+		depth -= front;
+
+	float diff = 1.0;
+	float3 col = fogColor.rgb;
+	if (textured != 0.0)
+	{
+		float2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles);
+
+		float2 mod1 = tex2D(density,(offset + (modspeed.xy*accumTime))).rg;
+		float2 mod2= tex2D(density,(offset + (modspeed.zw*accumTime))).rg;
+		diff = (mod2.r + mod1.r) * modstrength;
+		col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0;
+	}
+
+	col *= ambientColor;
+
+	float4 resultColor = float4(col, 1.0 - saturate(exp(-fogDensity  * depth * diff * fadesize)));
+
+	return hdrEncode(resultColor);
+}

+ 39 - 0
Templates/Full/game/shaders/common/VolumetricFog/VFogPreP.hlsl

@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog prepass pixel shader V1.00
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 pos : TEXCOORD0;
+};
+
+float4 main( ConnectData IN ) : COLOR0
+{
+   float OUT;
+   
+   clip( IN.pos.w );
+   OUT = IN.pos.w;
+
+   return float4(OUT,0,0,1);
+}

+ 46 - 0
Templates/Full/game/shaders/common/VolumetricFog/VFogPreV.hlsl

@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog prepass vertex shader V1.00
+
+#include "shaders/common/hlslstructs.h"
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 pos : TEXCOORD0;
+};
+
+uniform float4x4 modelView;
+
+ConnectData main( VertexIn_P IN)    
+{
+	ConnectData OUT;
+	
+	float4 inPos = IN.pos;
+	inPos.w = 1.0;
+ 
+	OUT.hpos = mul( modelView, inPos );
+    OUT.pos = OUT.hpos;
+
+    return OUT;  
+}

+ 37 - 0
Templates/Full/game/shaders/common/VolumetricFog/VFogRefl.hlsl

@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog Reflection pixel shader V1.00
+uniform float4 fogColor;
+uniform float fogDensity;
+uniform float reflStrength;
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 pos : TEXCOORD0;
+};
+
+float4 main( ConnectData IN ) : COLOR0
+{
+   return float4(fogColor.rgb,saturate(fogDensity*reflStrength));
+}

+ 45 - 0
Templates/Full/game/shaders/common/VolumetricFog/VFogV.hlsl

@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog final vertex shader V1.00
+
+#include "shaders/common/hlslstructs.h"
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 htpos : TEXCOORD0;
+   float2 uv0 : TEXCOORD1;
+};
+
+uniform float4x4 modelView;
+
+ConnectData main( VertexIn_PNT IN)    
+{  
+    ConnectData OUT;
+	
+	OUT.hpos = mul(modelView, IN.pos);
+	OUT.htpos = OUT.hpos;
+	OUT.uv0 = IN.uv0;
+	
+    return OUT;  
+}

+ 87 - 0
Templates/Full/game/shaders/common/VolumetricFog/gl/VFogP.glsl

@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+#include "shadergen:/autogenConditioners.h"
+#include "../../gl/torque.glsl"
+
+uniform sampler2D prepassTex;
+uniform sampler2D depthBuffer;
+uniform sampler2D frontBuffer;
+uniform sampler2D density;
+  
+uniform float accumTime;
+uniform vec4 fogColor;
+uniform float fogDensity;
+uniform float preBias;
+uniform float textured;
+uniform float modstrength;
+uniform vec4 modspeed;//xy speed layer 1, zw speed layer 2
+uniform vec2 viewpoint;
+uniform vec2 texscale;
+uniform vec3 ambientColor;
+uniform float numtiles;
+uniform float fadesize;
+uniform vec2 PixelSize;
+
+in vec4 _hpos;
+#define IN_hpos _hpos
+out vec4 OUT_col;
+
+void main()
+{
+	vec2 uvscreen=((IN_hpos.xy/IN_hpos.w) + 1.0 ) / 2.0;
+	uvscreen.y = 1.0 - uvscreen.y;
+	
+	float obj_test = prepassUncondition( prepassTex, uvscreen).w * preBias;
+	float depth = tex2D(depthBuffer,uvscreen).r;
+	float front = tex2D(frontBuffer,uvscreen).r;
+
+	if (depth <= front)
+	{
+		OUT_col = vec4(0,0,0,0);
+		return;
+	}
+	
+	else if ( obj_test < depth )
+		depth = obj_test;
+	if ( front >= 0.0)
+		depth -= front;
+
+	float diff = 1.0;
+	vec3 col = fogColor.rgb;
+	if (textured != 0.0)
+	{
+		vec2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles);
+
+		vec2 mod1 = tex2D(density,(offset + (modspeed.xy*accumTime))).rg;
+		vec2 mod2= tex2D(density,(offset + (modspeed.zw*accumTime))).rg;
+		diff = (mod2.r + mod1.r) * modstrength;
+		col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0;
+	}
+
+   col *= ambientColor;
+
+   vec4 returnColor = vec4(col, 1.0 - saturate(exp(-fogDensity  * depth * diff * fadesize)));
+
+	OUT_col = hdrEncode(returnColor);
+}

+ 37 - 0
Templates/Full/game/shaders/common/VolumetricFog/gl/VFogPreP.glsl

@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+in vec4 _hpos;
+#define IN_hpos _hpos
+
+out vec4 OUT_col;
+
+void main()
+{
+   float OUT;
+   clip( IN_hpos.w );
+   OUT = IN_hpos.w;
+
+   OUT_col = vec4(OUT,0,0,1);
+}

+ 42 - 0
Templates/Full/game/shaders/common/VolumetricFog/gl/VFogPreV.glsl

@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+#define IN_position vPosition
+
+out vec4 _hpos;
+#define OUT_hpos _hpos
+
+uniform mat4 modelView;
+
+void main()
+{
+	vec4 inPos = IN_position;
+	inPos.w = 1.0;
+ 
+	OUT_hpos = tMul( modelView, inPos );
+
+	gl_Position = OUT_hpos;
+	correctSSP(gl_Position);
+}

+ 33 - 0
Templates/Full/game/shaders/common/VolumetricFog/gl/VFogRefl.glsl

@@ -0,0 +1,33 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+uniform vec4 fogColor;
+uniform float fogDensity;
+uniform float reflStrength;
+out vec4 OUT_col;
+
+void main()
+{
+   OUT_col = vec4(fogColor.rgb,saturate(fogDensity*reflStrength));
+}

+ 38 - 0
Templates/Full/game/shaders/common/VolumetricFog/gl/VFogV.glsl

@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+#define IN_position vPosition
+
+out vec4 _hpos;
+#define OUT_hpos _hpos
+
+uniform mat4 modelView;
+
+void main()    
+{  
+	OUT_hpos = tMul(modelView, IN_position);
+	gl_Position = OUT_hpos;
+	correctSSP(gl_Position);
+}

+ 74 - 0
Templates/Full/game/shaders/common/postFx/VolFogGlowP.hlsl

@@ -0,0 +1,74 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 R.G.S. - Richards Game Studio, the Netherlands
+//					  http://www.richardsgamestudio.com/
+//
+// If you find this code useful or you are feeling particularly generous I
+// would ask that you please go to http://www.richardsgamestudio.com/ then
+// choose Donations from the menu on the left side and make a donation to
+// Richards Game Studio. It will be highly appreciated.
+//
+// The MIT License:
+//
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog Glow postFx pixel shader V1.00
+
+#include "./postFx.hlsl"
+
+uniform sampler2D diffuseMap : register(S0);
+uniform float strength;
+
+struct VertToPix
+{
+   float4 hpos       : POSITION;
+
+   float2 uv0        : TEXCOORD0;
+   float2 uv1        : TEXCOORD1;
+   float2 uv2        : TEXCOORD2;
+   float2 uv3        : TEXCOORD3;
+
+   float2 uv4        : TEXCOORD4;
+   float2 uv5        : TEXCOORD5;
+   float2 uv6        : TEXCOORD6;
+   float2 uv7        : TEXCOORD7;
+};
+
+float4 main( VertToPix IN ) : COLOR
+{
+   float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * strength;
+
+   float4 OUT = 0;
+   OUT += tex2D( diffuseMap, IN.uv0 ) * kernel.x;
+   OUT += tex2D( diffuseMap, IN.uv1 ) * kernel.y;
+   OUT += tex2D( diffuseMap, IN.uv2 ) * kernel.z;
+   OUT += tex2D( diffuseMap, IN.uv3 ) * kernel.w;
+
+   OUT += tex2D( diffuseMap, IN.uv4 ) * kernel.x;
+   OUT += tex2D( diffuseMap, IN.uv5 ) * kernel.y;
+   OUT += tex2D( diffuseMap, IN.uv6 ) * kernel.z;
+   OUT += tex2D( diffuseMap, IN.uv7 ) * kernel.w;
+
+   // Calculate a lumenance value in the alpha so we
+   // can use alpha test to save fillrate.
+   float3 rgb2lum = float3( 0.30, 0.59, 0.11 );
+   OUT.a = dot( OUT.rgb, rgb2lum );
+
+   return OUT;
+}

+ 67 - 0
Templates/Full/game/shaders/common/postFx/gl/VolFogGlowP.glsl

@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 R.G.S. - Richards Game Studio, the Netherlands
+//					  http://www.richardsgamestudio.com/
+//
+// If you find this code useful or you are feeling particularly generous I
+// would ask that you please go to http://www.richardsgamestudio.com/ then
+// choose Donations from the menu on the left side and make a donation to
+// Richards Game Studio. It will be highly appreciated.
+//
+// The MIT License:
+//
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog Glow postFx pixel shader V1.00
+
+uniform sampler2D diffuseMap;
+uniform float strength;
+
+out vec4 OUT_col;
+
+in vec2 uv0;
+in vec2 uv1;
+in vec2 uv2;
+in vec2 uv3;
+
+in vec2 uv4;
+in vec2 uv5;
+in vec2 uv6;
+in vec2 uv7;
+
+void main()
+{
+   vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ) * strength;
+
+   OUT_col = vec4(0);
+   OUT_col += texture( diffuseMap, uv0 ) * kernel.x;
+   OUT_col += texture( diffuseMap, uv1 ) * kernel.y;
+   OUT_col += texture( diffuseMap, uv2 ) * kernel.z;
+   OUT_col += texture( diffuseMap, uv3 ) * kernel.w;
+
+   OUT_col += texture( diffuseMap, uv4 ) * kernel.x;
+   OUT_col += texture( diffuseMap, uv5 ) * kernel.y;
+   OUT_col += texture( diffuseMap, uv6 ) * kernel.z;
+   OUT_col += texture( diffuseMap, uv7 ) * kernel.w;
+
+   // Calculate a lumenance value in the alpha so we
+   // can use alpha test to save fillrate.
+   vec3 rgb2lum = vec3( 0.30, 0.59, 0.11 );
+   OUT_col.a = dot( OUT_col.rgb, rgb2lum );
+}

BIN
Templates/Full/game/tools/classIcons/VolumetricFog.png


+ 13 - 1
Templates/Full/game/tools/worldEditor/gui/objectBuilderGui.ed.gui

@@ -980,7 +980,19 @@ function ObjectBuilderGui::buildObserverDropPoint(%this)
 //------------------------------------------------------------------------------
 // System
 //------------------------------------------------------------------------------
-
+function ObjectBuilderGui::buildVolumetricFog(%this)
+{
+	// Change this if you want to default to another Folder
+	// Otherwise every time you want to add a Fog you will go this.
+	%defShape = "/art/environment/Fog_Cube.dts";
+	%this.lastPath=getMainDotCsDir() @ %defShape;
+	OBObjectName.setValue( "" );
+	%this.objectClassName = "VolumetricFog";
+	%this.addField( "shapeName", "TypeFile", "Shape (Fog volume)", "", "*.dts;*.dae");
+	%this.addField("Scale", "TypePoint3", "Scale", "1 1 1");
+	%this.addField("FogColor", "TypeColorI", "FogColor", "200 200 200 255");
+	%this.process();
+}
 function ObjectBuilderGui::buildPhysicsEntity(%this)
 {
    %this.objectClassName = "PhysicsEntity";

+ 1 - 0
Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs

@@ -46,6 +46,7 @@ function EWCreatorWindow::init( %this )
       %this.registerMissionObject( "SFXEmitter",          "Sound Emitter" );
       %this.registerMissionObject( "Precipitation" );
       %this.registerMissionObject( "ParticleEmitterNode", "Particle Emitter" );
+      %this.registerMissionObject( "VolumetricFog", "Volumetric Fog" );
       %this.registerMissionObject( "RibbonNode", "Ribbon" );
       
       // Legacy features. Users should use Ground Cover and the Forest Editor.   

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä