Merge pull request #1751 from wareya/terrainbleeding

Fix #4452
pull/456/head
Bret Curtis 7 years ago committed by GitHub
commit 3ebebdf3c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -39,6 +39,7 @@
Bug #4432: Guards behaviour is incorrect if they do not have AI packages
Bug #4433: Guard behaviour is incorrect with Alarm = 0
Bug #4451: Script fails to compile when using "Begin, [ScriptName]" syntax
Bug #4452: Default terrain texture bleeds through texture transitions
Bug #4453: Quick keys behaviour is invalid for equipment
Bug #4454: AI opens doors too slow
Bug #4457: Item without CanCarry flag prevents shield autoequipping in dark areas

@ -361,6 +361,11 @@ namespace ESMTerrain
std::string Storage::getTextureName(UniqueTextureId id)
{
// Goes under used terrain blend transitions
static const std::string baseTexture = "textures\\tx_black_01.dds";
if (id.first == -1)
return baseTexture;
static const std::string defaultTexture = "textures\\_land_default.dds";
if (id.first == 0)
return defaultTexture; // Not sure if the default texture really is hardcoded?
@ -396,11 +401,9 @@ namespace ESMTerrain
// Save the used texture indices so we know the total number of textures
// and number of required blend maps
std::set<UniqueTextureId> textureIndices;
// Due to the way the blending works, the base layer will always shine through in between
// blend transitions (eg halfway between two texels, both blend values will be 0.5, so 25% of base layer visible).
// To get a consistent look, we need to make sure to use the same base layer in all cells.
// So we're always adding _land_default.dds as the base layer here, even if it's not referenced in this cell.
textureIndices.insert(std::make_pair(0,0));
// Due to the way the blending works, the base layer will bleed between texture transitions so we want it to be a black texture
// The subsequent passes are added instead of blended, so this gives the correct result
textureIndices.insert(std::make_pair(-1,0)); // -1 goes to tx_black_01
LandCache cache;
@ -618,15 +621,6 @@ namespace ESMTerrain
return info;
}
Terrain::LayerInfo Storage::getDefaultLayer()
{
Terrain::LayerInfo info;
info.mDiffuseMap = "textures\\_land_default.dds";
info.mParallax = false;
info.mSpecular = false;
return info;
}
float Storage::getCellWorldSize()
{
return static_cast<float>(ESM::Land::REAL_SIZE);

@ -94,8 +94,6 @@ namespace ESMTerrain
virtual float getHeightAt (const osg::Vec3f& worldPos);
virtual Terrain::LayerInfo getDefaultLayer();
/// Get the transformation factor for mapping cell units to world units.
virtual float getCellWorldSize();

@ -2,11 +2,13 @@
#include <stdexcept>
#include <osg/Fog>
#include <osg/Depth>
#include <osg/TexEnvCombine>
#include <osg/Texture2D>
#include <osg/TexMat>
#include <osg/Material>
#include <osg/BlendFunc>
#include <components/shader/shadermanager.hpp>
@ -59,24 +61,52 @@ namespace Terrain
}
return depth;
}
osg::ref_ptr<osg::Depth> getLequalDepth()
{
static osg::ref_ptr<osg::Depth> depth;
if (!depth)
{
depth = new osg::Depth;
depth->setFunction(osg::Depth::LEQUAL);
}
return depth;
}
std::vector<osg::ref_ptr<osg::StateSet> > createPasses(bool useShaders, bool forcePerPixelLighting, bool clampLighting, Shader::ShaderManager* shaderManager, const std::vector<TextureLayer> &layers,
const std::vector<osg::ref_ptr<osg::Texture2D> > &blendmaps, int blendmapScale, float layerTileSize)
{
std::vector<osg::ref_ptr<osg::StateSet> > passes;
bool firstLayer = true;
unsigned int blendmapIndex = 0;
unsigned int passIndex = 0;
for (std::vector<TextureLayer>::const_iterator it = layers.begin(); it != layers.end(); ++it)
{
bool firstLayer = (it == layers.begin());
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
if (!firstLayer)
{
static osg::ref_ptr<osg::BlendFunc> blendFunc;
if (!blendFunc)
{
blendFunc= new osg::BlendFunc();
blendFunc->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE);
}
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setAttributeAndModes(blendFunc, osg::StateAttribute::ON);
stateset->setAttributeAndModes(getEqualDepth(), osg::StateAttribute::ON);
}
// disable fog if we're the first layer of several - supposed to be completely black
if (firstLayer && blendmaps.size() > 0)
{
osg::ref_ptr<osg::Fog> fog (new osg::Fog);
fog->setStart(10000000);
fog->setEnd(10000000);
stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
stateset->setAttributeAndModes(getLequalDepth(), osg::StateAttribute::ON);
}
int texunit = 0;
@ -158,8 +188,6 @@ namespace Terrain
stateset->setTextureAttributeAndModes(texunit, getLayerTexMat(layerTileSize), osg::StateAttribute::ON);
}
firstLayer = false;
stateset->setRenderBinDetails(passIndex++, "RenderBin");
passes.push_back(stateset);

@ -72,8 +72,6 @@ namespace Terrain
virtual float getHeightAt (const osg::Vec3f& worldPos) = 0;
virtual LayerInfo getDefaultLayer() = 0;
/// Get the transformation factor for mapping cell units to world units.
virtual float getCellWorldSize() = 0;

Loading…
Cancel
Save