From: fredb Date: Thu, 11 Dec 2008 08:24:35 +0000 (+0000) Subject: Stuart : X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=e0a07b7a92392725b266bc0a1f17ab49483df930;p=simgear.git Stuart : - Removes the cloud type re-use code - I think they aren't worth the graphical artefacts that they cause in light of Tim's improvements - Changes the transparency of the clouds. Previously, the clouds were transparent at 0m distance, opaque at 200m, then gradually more transparent to the fog limits. This meant they were generally quite transparent. Now, they are opaque from 200m to 15km, then become transparent at 20km. A side effect of this is that the current textures could probably benefit from being made slightly transparent to improve the blending of the sprites against each other. --- diff --git a/simgear/scene/sky/newcloud.cxx b/simgear/scene/sky/newcloud.cxx index 61dcb8b6..165e1268 100644 --- a/simgear/scene/sky/newcloud.cxx +++ b/simgear/scene/sky/newcloud.cxx @@ -60,13 +60,9 @@ using namespace simgear; using namespace osg; typedef std::map > StateSetMap; -typedef std::vector< osg::ref_ptr > GeodeList; -typedef std::map CloudMap; StateSetMap cloudTextureMap; -static CloudMap cloudMap; double SGNewCloud::sprite_density = 1.0; -unsigned int SGNewCloud::num_flavours = 10; static char vertexShaderSource[] = "#version 120\n" @@ -113,8 +109,8 @@ static char vertexShaderSource[] = " vec4 backlight = 0.9 * gl_LightSource[0].ambient + 0.1 * gl_LightSource[0].diffuse;\n" " gl_FrontColor = mix(backlight, gl_LightSource[0].diffuse, n);\n" " gl_FrontColor += gl_FrontLightModelProduct.sceneColor;\n" -// As we get within 100m of the sprite, it is faded out - " gl_FrontColor.a = smoothstep(10.0, 100.0, fogCoord);\n" +// As we get within 100m of the sprite, it is faded out. Equally at large distances it also fades out. + " gl_FrontColor.a = min(smoothstep(10.0, 100.0, fogCoord), 1 - smoothstep(15000.0, 20000.0, fogCoord));\n" " gl_BackColor = gl_FrontColor;\n" // Fog doesn't affect clouds as much as other objects. " fogFactor = exp( -gl_Fog.density * fogCoord * 0.5);\n" @@ -285,119 +281,86 @@ static float Rnd(float n) { osg::ref_ptr SGNewCloud::genCloud() { - CloudMap::iterator iter = cloudMap.find(name); - osg::ref_ptr geode; + osg::ref_ptr geode = new Geode; + + CloudShaderGeometry* sg = new CloudShaderGeometry(num_textures_x, num_textures_y, max_width, max_height); + + // Determine how big this specific cloud instance is. Note that we subtract + // the sprite size because the width/height is used to define the limits of + // the center of the sprites, not their edges. + float width = min_width + sg_random() * (max_width - min_width) - min_sprite_width; + float height = min_height + sg_random() * (max_height - min_height) - min_sprite_height; + + // Determine the cull distance. This is used to remove sprites that are too close together. + // The value is squared as we use vector calculations. + float cull_distance_squared = min_sprite_height * min_sprite_height * 0.1f; - // We generate up to num_flavours of different versions - // of the same cloud before we start re-using them. This - // allows us to strike a balance between performance and - // visual complexity. + // The number of sprites we actually used is a function of the (user-controlled) density + int n_sprites = num_sprites * sprite_density; - if (iter == cloudMap.end() || (*iter).second->size() < num_flavours) + for (int i = 0; i < n_sprites; i++) { + // Determine the position of the sprite. Rather than being completely random, + // we place them on the surface of a distorted sphere. However, we place + // the first and second sprites on the top and bottom, and the third in the + // center of the sphere (and at maximum size) to ensure good coverage and + // reduce the chance of there being "holes" in our cloud. + float x, y, z; - geode = new Geode; - - CloudShaderGeometry* sg = new CloudShaderGeometry(num_textures_x, num_textures_y, max_width, max_height); - - // Determine how big this specific cloud instance is. Note that we subtract - // the sprite size because the width/height is used to define the limits of - // the center of the sprites, not their edges. - float width = min_width + sg_random() * (max_width - min_width) - min_sprite_width; - float height = min_height + sg_random() * (max_height - min_height) - min_sprite_height; - - // Determine the cull distance. This is used to remove sprites that are too close together. - // The value is squared as we use vector calculations. - float cull_distance_squared = min_sprite_height * min_sprite_height * 0.1f; - - // The number of sprites we actually used is a function of the (user-controlled) density - int n_sprites = num_sprites * sprite_density; - - for (int i = 0; i < n_sprites; i++) - { - // Determine the position of the sprite. Rather than being completely random, - // we place them on the surface of a distorted sphere. However, we place - // the first and second sprites on the top and bottom, and the third in the - // center of the sphere (and at maximum size) to ensure good coverage and - // reduce the chance of there being "holes" in our cloud. - float x, y, z; - - if (i == 0) { - x = 0; - y = 0; - z = height * 0.5f; - } else if (i == 1) { - x = 0; - y = 0; - z = - height * 0.5f; - } else if (i == 2) { - x = 0; - y = 0; - z = 0; - } else { - double theta = sg_random() * SGD_2PI; - double elev = sg_random() * SGD_PI; - x = width * cos(theta) * 0.5f * sin(elev); - y = width * sin(theta) * 0.5f * sin(elev); - z = height * cos(elev) * 0.5f; - } - - SGVec3f *pos = new SGVec3f(x, y, z); - - // Determine the height and width as scaling factors on the minimum size (used to create the quad) - float sprite_width = 1.0f + sg_random() * (max_sprite_width - min_sprite_width) / min_sprite_width; - float sprite_height = 1.0f + sg_random() * (max_sprite_height - min_sprite_height) / min_sprite_height; - - if (i == 2) { - // The center sprite is always maximum size to fill up any holes. - sprite_width = 1.0f + (max_sprite_width - min_sprite_width) / min_sprite_width; - sprite_height = 1.0f + (max_sprite_height - min_sprite_height) / min_sprite_height; - } - - // Determine the sprite texture indexes; - int index_x = (int) floor(sg_random() * num_textures_x); - if (index_x == num_textures_x) { index_x--; } - - int index_y = (int) floor(sg_random() * num_textures_y); - if (index_y == num_textures_y) { index_y--; } - - sg->addSprite(*pos, - index_x, - index_y, - sprite_width, - sprite_height, - bottom_shade, - cull_distance_squared, - height * 0.5f); + if (i == 0) { + x = 0; + y = 0; + z = height * 0.5f; + } else if (i == 1) { + x = 0; + y = 0; + z = - height * 0.5f; + } else if (i == 2) { + x = 0; + y = 0; + z = 0; + } else { + double theta = sg_random() * SGD_2PI; + double elev = sg_random() * SGD_PI; + x = width * cos(theta) * 0.5f * sin(elev); + y = width * sin(theta) * 0.5f * sin(elev); + z = height * cos(elev) * 0.5f; } + SGVec3f *pos = new SGVec3f(x, y, z); + + // Determine the height and width as scaling factors on the minimum size (used to create the quad) + float sprite_width = 1.0f + sg_random() * (max_sprite_width - min_sprite_width) / min_sprite_width; + float sprite_height = 1.0f + sg_random() * (max_sprite_height - min_sprite_height) / min_sprite_height; - sg->setGeometry(quad); - geode->addDrawable(sg); - geode->setName("3D cloud"); - geode->setStateSet(stateSet.get()); - - if (iter == cloudMap.end()) - { - // This is the first of this cloud to be generated. - GeodeList* geodelist = new GeodeList; - geodelist->push_back(geode); - cloudMap.insert(CloudMap::value_type(name, geodelist)); + if (i == 2) { + // The center sprite is always maximum size to fill up any holes. + sprite_width = 1.0f + (max_sprite_width - min_sprite_width) / min_sprite_width; + sprite_height = 1.0f + (max_sprite_height - min_sprite_height) / min_sprite_height; } - else - { - // Add the new cloud to the list of geodes - (*iter).second->push_back(geode); - } - - } else { - int index = sg_random() * num_flavours; - if (index == num_flavours) index--; + // Determine the sprite texture indexes; + int index_x = (int) floor(sg_random() * num_textures_x); + if (index_x == num_textures_x) { index_x--; } - geode = iter->second->at(index); + int index_y = (int) floor(sg_random() * num_textures_y); + if (index_y == num_textures_y) { index_y--; } + + sg->addSprite(*pos, + index_x, + index_y, + sprite_width, + sprite_height, + bottom_shade, + cull_distance_squared, + height * 0.5f); } + sg->setGeometry(quad); + geode->addDrawable(sg); + geode->setName("3D cloud"); + geode->setStateSet(stateSet.get()); + return geode; } diff --git a/simgear/scene/sky/newcloud.hxx b/simgear/scene/sky/newcloud.hxx index fabf073d..be5549ff 100644 --- a/simgear/scene/sky/newcloud.hxx +++ b/simgear/scene/sky/newcloud.hxx @@ -72,19 +72,6 @@ public: sprite_density = d; } - static int getNumFlavours(void) - { - return num_flavours; - } - - // Set the number of flavours of this cloud. - // This is the number of different instances - // to generate. - static void setNumFlavours(int d) - { - num_flavours = d; - } - private: @@ -105,7 +92,6 @@ private: osg::Geometry* quad; osg::ref_ptr stateSet; static double sprite_density; - static unsigned int num_flavours; osg::Geometry* createOrthQuad(float w, float h, int varieties_x, int varieties_y); diff --git a/simgear/scene/sky/sky.cxx b/simgear/scene/sky/sky.cxx index 7ff81da8..ca2c0004 100644 --- a/simgear/scene/sky/sky.cxx +++ b/simgear/scene/sky/sky.cxx @@ -216,15 +216,6 @@ void SGSky::set_3dCloudVisRange(float vis) } } -float SGSky::get_3dCloudNumFlavours() const { - return (float) SGNewCloud::getNumFlavours(); -} - -void SGSky::set_3dCloudNumFlavours(float n) -{ - SGNewCloud::setNumFlavours((int) n); -} - void SGSky::texture_path( const string& path ) { tex_path = SGPath( path ); } diff --git a/simgear/scene/sky/sky.hxx b/simgear/scene/sky/sky.hxx index 9e6a1b1b..4d9199d6 100644 --- a/simgear/scene/sky/sky.hxx +++ b/simgear/scene/sky/sky.hxx @@ -430,14 +430,6 @@ public: */ virtual void set_3dCloudVisRange(float vis); - /** Get 3D cloud number of flavours*/ - virtual float get_3dCloudNumFlavours() const; - - /** Set 3D cloud number of flavours - * @param density 3D cloud number of flavours - */ - virtual void set_3dCloudNumFlavours(float n); - };