Index: SimGear/simgear/scene/sky/CloudShaderGeometry.hxx
===================================================================
--- SimGear/simgear/scene/sky/CloudShaderGeometry.hxx	(.../upstream)	(revision 35)
+++ SimGear/simgear/scene/sky/CloudShaderGeometry.hxx	(.../performance)	(revision 35)
@@ -152,7 +152,7 @@
     
         virtual ~CloudShaderGeometry() {
             delete skip_info;
-            for (int i = 0; i < _cloudsprites.size(); i++)
+            for (unsigned int i = 0; i < _cloudsprites.size(); i++)
             {
                 delete _cloudsprites[i];
             }
Index: SimGear/simgear/scene/sky/cloudfield.hxx
===================================================================
--- SimGear/simgear/scene/sky/cloudfield.hxx	(.../upstream)	(revision 35)
+++ SimGear/simgear/scene/sky/cloudfield.hxx	(.../performance)	(revision 35)
@@ -42,6 +42,8 @@
 
 class SGNewCloud;
 
+#define NEW_FOG_UPDATE_CALLBACK
+
 /**
  * A layer of 3D clouds.
  */
@@ -55,6 +57,7 @@
 		bool		visible;
 	};
 
+
         float Rnd(float);
         
         // We create a quadtree two levels deep
@@ -123,6 +126,12 @@
         
         void applyCoverage(void);
         void applyVisRange(void);
+
+#ifdef NEW_FOG_UPDATE_CALLBACK
+  typedef std::map<std::string, osg::ref_ptr<osg::StateSet> > StateSetMap;
+  static StateSetMap cloudTextureMap;
+#endif
+
 };
 
 #endif // _CLOUDFIELD_HXX
Index: SimGear/simgear/scene/sky/newcloud.cxx
===================================================================
--- SimGear/simgear/scene/sky/newcloud.cxx	(.../upstream)	(revision 35)
+++ SimGear/simgear/scene/sky/newcloud.cxx	(.../performance)	(revision 35)
@@ -61,10 +61,12 @@
 typedef std::vector< osg::ref_ptr<osg::Geode> > GeodeList;
 typedef std::map<std::string, GeodeList*> CloudMap;
 
-static StateSetMap cloudTextureMap;
+#ifndef NEW_FOG_UPDATE_CALLBACK
+StateSetMap cloudTextureMap;
+#endif
 static CloudMap cloudMap;
 double SGNewCloud::sprite_density = 1.0;
-int SGNewCloud::num_flavours = 10;
+unsigned int SGNewCloud::num_flavours = 10;
 
 static char vertexShaderSource[] = 
     "#version 120\n"
@@ -182,9 +184,16 @@
         name(type)
 {
     // Create a new StateSet for the texture, if required.
-    StateSetMap::iterator iter = cloudTextureMap.find(texture);
-
-    if (iter == cloudTextureMap.end()) {
+#ifdef NEW_FOG_UPDATE_CALLBACK        
+        StateSetMap::iterator iter = SGCloudField::cloudTextureMap.find(texture);
+#else
+        StateSetMap::iterator iter = cloudTextureMap.find(texture);
+#endif
+#ifdef NEW_FOG_UPDATE_CALLBACK        
+        if (iter == SGCloudField::cloudTextureMap.end()) {
+#else
+        if (iter == cloudTextureMap.end()) {
+#endif
         stateSet = new osg::StateSet;
                 
         osg::ref_ptr<osgDB::ReaderWriter::Options> options = makeOptionsFromPath(tex_path);
@@ -201,7 +210,9 @@
         
         // Fog handling
         osg::Fog* fog = new osg::Fog;
+#ifndef NEW_FOG_UPDATE_CALLBACK        
         fog->setUpdateCallback(new SGCloudFogUpdateCallback);
+#endif
         stateSet->setAttributeAndModes(fog);
         stateSet->setDataVariance(osg::Object::DYNAMIC);
         
@@ -255,7 +266,11 @@
         stateSet->setAttribute(material.get());
                 
         // Add the newly created texture to the map for use later.
+#ifdef NEW_FOG_UPDATE_CALLBACK        
+        SGCloudField::cloudTextureMap.insert(StateSetMap::value_type(texture,  stateSet));
+#else
         cloudTextureMap.insert(StateSetMap::value_type(texture,  stateSet));
+#endif
     } else {
         stateSet = iter->second.get();
     }
@@ -325,9 +340,9 @@
     // allows us to strike a balance between performance and
     // visual complexity.
     
-    GeodeList* g = (*iter).second;
+    GeodeList* g;// = (*iter).second;
 
-    if (iter == cloudMap.end() || g->size() < num_flavours) 
+    if (iter == cloudMap.end() || (g=(*iter).second)->size() < num_flavours) 
     {
         geode = new Geode;
         
Index: SimGear/simgear/scene/sky/newcloud.hxx
===================================================================
--- SimGear/simgear/scene/sky/newcloud.hxx	(.../upstream)	(revision 35)
+++ SimGear/simgear/scene/sky/newcloud.hxx	(.../performance)	(revision 35)
@@ -105,7 +105,7 @@
         osg::Geometry* quad;
         osg::ref_ptr<osg::StateSet> stateSet;
         static double sprite_density;
-        static int num_flavours; 
+        static unsigned int num_flavours; 
 
         osg::Geometry* createOrthQuad(float w, float h, int varieties_x, int varieties_y);
 
Index: SimGear/simgear/scene/sky/CloudShaderGeometry.cxx
===================================================================
--- SimGear/simgear/scene/sky/CloudShaderGeometry.cxx	(.../upstream)	(revision 35)
+++ SimGear/simgear/scene/sky/CloudShaderGeometry.cxx	(.../performance)	(revision 35)
@@ -59,7 +59,7 @@
         float p = view_dir*_cloudsprites[0]->position.osg();
         // Do a single iteration of a bubble sort, sorting
         // back to front.
-        for(int i = 0; i < _cloudsprites.size() - 1; i++)
+        for(unsigned int i = 0; i < _cloudsprites.size() - 1; i++)
         {
             float q = view_dir*_cloudsprites[i+1]->position.osg();
             if (p > q) {  
Index: SimGear/simgear/scene/sky/cloudfield.cxx
===================================================================
--- SimGear/simgear/scene/sky/cloudfield.cxx	(.../upstream)	(revision 35)
+++ SimGear/simgear/scene/sky/cloudfield.cxx	(.../performance)	(revision 35)
@@ -44,6 +44,9 @@
 #include "sky.hxx"
 #include "newcloud.hxx"
 #include "cloudfield.hxx"
+#ifdef NEW_FOG_UPDATE_CALLBACK
+#include <simgear/scene/util/SGUpdateVisitor.hxx>
+#endif
 
 #if defined(__MINGW32__)
 #define isnan(x) _isnan(x)
@@ -70,7 +73,11 @@
 float SGCloudField::view_distance = 20000.0f;
 sgVec3 SGCloudField::view_vec, SGCloudField::view_X, SGCloudField::view_Y;
 
+#ifdef NEW_FOG_UPDATE_CALLBACK
+SGCloudField::StateSetMap SGCloudField::cloudTextureMap;
+#endif
 
+
 // reposition the cloud layer at the specified origin and orientation
 bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon, double lat,
         		       double dt, int asl )
@@ -136,6 +143,31 @@
     return true;
 }
 
+#ifdef NEW_FOG_UPDATE_CALLBACK
+struct threeDCloudsFogUpdater : public osg::NodeCallback {
+    threeDCloudsFogUpdater() {};
+
+    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
+        SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
+        //running at 5 times frame
+        SGCloudField::StateSetMap::iterator iter;
+        osg::Fog * fog;
+        for( iter = SGCloudField::cloudTextureMap.begin(); iter != SGCloudField::cloudTextureMap.end(); ++iter) {
+            fog = static_cast<osg::Fog*>(iter->second->getAttribute( osg::StateAttribute::FOG, 0 ));
+            fog->setMode(osg::Fog::EXP);
+            osg::Vec4f fogC = updateVisitor->getFogColor().osg();
+            fogC[3] = 0.0;
+            fog->setColor(fogC);
+            fog->setDensity(updateVisitor->getFogExpDensity());
+        }
+
+        if (node->getNumChildrenRequiringUpdateTraversal()>0)
+          traverse(node,nv);
+    }
+};
+#endif
+
+
 SGCloudField::SGCloudField() :
         field_root(new osg::Group),
         field_transform(new osg::MatrixTransform),
@@ -147,6 +179,9 @@
         reposition_count(0)
 {
     cld_pos = SGGeoc();
+#ifdef NEW_FOG_UPDATE_CALLBACK
+    field_root->setUpdateCallback( new threeDCloudsFogUpdater() );
+#endif
     field_root->addChild(field_transform.get());
     field_root->setName("3D Cloud field root");
     osg::StateSet *rootSet = field_root->getOrCreateStateSet();
