WS30: Improved material Uniforms
This commit is contained in:
parent
922ad8d2e7
commit
0e13e48123
@ -403,6 +403,11 @@ public:
|
|||||||
(0 < tex_height) ? 1000.0f/tex_height : 1.0f);
|
(0 < tex_height) ? 1000.0f/tex_height : 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float get_parameter(const std::string& param) const
|
||||||
|
{
|
||||||
|
return parameters->getFloatValue(param);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
@ -355,14 +355,17 @@ SGMaterialCache::Atlas SGMaterialLib::getMaterialTextureAtlas(SGVec2f center, co
|
|||||||
|
|
||||||
atlas.image = new osg::Texture2DArray();
|
atlas.image = new osg::Texture2DArray();
|
||||||
|
|
||||||
if (landclasslib.size() > 128) SG_LOG(SG_TERRAIN, SG_ALERT, "Too many landclass entries for uniform arrays");
|
SG_LOG(SG_TERRAIN, SG_DEBUG, "Generating atlas of size " << landclasslib.size());
|
||||||
|
if (landclasslib.size() > SGMaterialCache::MAX_MATERIALS) SG_LOG(SG_TERRAIN, SG_ALERT, "Too many landclass entries for uniform arrays: " << landclasslib.size() << " > " << SGMaterialCache::MAX_MATERIALS);
|
||||||
|
|
||||||
atlas.textureLookup1 = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_textureLookup1", 128);
|
atlas.textureLookup1 = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_textureLookup1", SGMaterialCache::MAX_MATERIALS);
|
||||||
atlas.textureLookup2 = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_textureLookup2", 128);
|
atlas.textureLookup2 = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_textureLookup2", SGMaterialCache::MAX_MATERIALS);
|
||||||
atlas.dimensions = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_dimensionsArray", 128);
|
atlas.dimensions = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_dimensionsArray", SGMaterialCache::MAX_MATERIALS);
|
||||||
atlas.ambient = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_ambientArray", 128);
|
atlas.ambient = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_ambientArray", SGMaterialCache::MAX_MATERIALS);
|
||||||
atlas.diffuse = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_diffuseArray", 128);
|
atlas.diffuse = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_diffuseArray", SGMaterialCache::MAX_MATERIALS);
|
||||||
atlas.specular = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_specularArray", 128);
|
atlas.specular = new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_specularArray", SGMaterialCache::MAX_MATERIALS);
|
||||||
|
atlas.materialParams1= new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_materialParams1", SGMaterialCache::MAX_MATERIALS);
|
||||||
|
atlas.materialParams2= new osg::Uniform(osg::Uniform::Type::FLOAT_VEC4, "fg_materialParams2", SGMaterialCache::MAX_MATERIALS);
|
||||||
|
|
||||||
atlas.image->setMaxAnisotropy(SGSceneFeatures::instance()->getTextureFilter());
|
atlas.image->setMaxAnisotropy(SGSceneFeatures::instance()->getTextureFilter());
|
||||||
atlas.image->setResizeNonPowerOfTwoHint(false);
|
atlas.image->setResizeNonPowerOfTwoHint(false);
|
||||||
@ -396,10 +399,38 @@ SGMaterialCache::Atlas SGMaterialLib::getMaterialTextureAtlas(SGVec2f center, co
|
|||||||
atlas.diffuse->setElement(materialLookupIndex, mat->get_diffuse());
|
atlas.diffuse->setElement(materialLookupIndex, mat->get_diffuse());
|
||||||
atlas.specular->setElement(materialLookupIndex, mat->get_specular());
|
atlas.specular->setElement(materialLookupIndex, mat->get_specular());
|
||||||
|
|
||||||
// Add any missing textures into the atlas image
|
// The following are material parameters that are normally built into the Effect as Uniforms. In the WS30
|
||||||
for (std::size_t i = 0; i < mat->get_num_textures(0); ++i) {
|
// case we need to pass them as an array, indexed against the material.
|
||||||
const std::string texture = mat->get_one_texture(0,i);
|
atlas.materialParams1->setElement(materialLookupIndex, osg::Vec4f(mat->get_parameter("transition_model"), mat->get_parameter("hires_overlay_bias"), mat->get_parameter("grain_strength"), mat->get_parameter("intrinsic_wetness")));
|
||||||
if (! texture.empty()) {
|
atlas.materialParams2->setElement(materialLookupIndex, osg::Vec4f(mat->get_parameter("dot_density"), mat->get_parameter("dot_size"), mat->get_parameter("dust_resistance"), mat->get_parameter("rock_strata")));
|
||||||
|
|
||||||
|
// Similarly, there are specifically 7 textures that are defined in the materials that need to be passed into
|
||||||
|
// the shader as an array based on the material lookup.
|
||||||
|
//
|
||||||
|
// The mapping from terrain-default.eff / terrain-overlay.eff is as follows
|
||||||
|
//
|
||||||
|
// TEXTURE NAME texture-unit Material texture index Default value
|
||||||
|
// Primary texure 0 0 n/a
|
||||||
|
// gradient_texture 2 13 Textures/Terrain/rock_alt.png
|
||||||
|
// dot_texture 3 15 Textures/Terrain/void.png
|
||||||
|
// grain_texture 4 14 Textures/Terrain/grain_texture.png
|
||||||
|
// mix_texture 5 12 Textures/Terrain/void.png
|
||||||
|
// detail_texture 7 11 Textures/Terrain/void.png
|
||||||
|
// overlayPrimaryTex 7 20 Textures/Terrain/void.png
|
||||||
|
// overlaySecondaryTex 8 21 Textures/Terrain/void.png
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < SGMaterialCache::MAX_TEXTURES; i++) {
|
||||||
|
std::string texture = mat->get_one_texture(0,i);
|
||||||
|
|
||||||
|
if (texture.empty()) {
|
||||||
|
// This is a rather horrible hardcoded mapping of the default textures defined in
|
||||||
|
// terrain-default.eff and terrain-overlay.eff which are in effect defaults to
|
||||||
|
// the material definitions
|
||||||
|
if (i < 13) texture = std::string("Textures/Terrain/void.png");
|
||||||
|
if (i == 13) texture = std::string("Textures/Terrain/rock_alt.png");
|
||||||
|
if (i == 14) texture = std::string("Textures/Terrain/grain_texture.png");
|
||||||
|
if (i > 14) texture = std::string("Textures/Terrain/void.png");
|
||||||
|
}
|
||||||
|
|
||||||
SGPath texturePath = SGPath("Textures");
|
SGPath texturePath = SGPath("Textures");
|
||||||
std::string fullPath = SGModelLib::findDataFile(texture, options, texturePath);
|
std::string fullPath = SGModelLib::findDataFile(texture, options, texturePath);
|
||||||
@ -407,11 +438,12 @@ SGMaterialCache::Atlas SGMaterialLib::getMaterialTextureAtlas(SGVec2f center, co
|
|||||||
if (fullPath.empty()) {
|
if (fullPath.empty()) {
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find texture \""
|
SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find texture \""
|
||||||
<< texture << "\" in Textures folders when creating texture atlas");
|
<< texture << "\" in Textures folders when creating texture atlas");
|
||||||
textureList[i] = -2;
|
texture = std::string("Textures/Terrain/void.png");
|
||||||
continue;
|
fullPath = SGModelLib::findDataFile(texture, options, texturePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atlas.textureMap.find(fullPath) == atlas.textureMap.end()) {
|
if (atlas.textureMap.find(fullPath) == atlas.textureMap.end()) {
|
||||||
|
// Add any missing textures into the atlas image
|
||||||
// Copy the texture into the atlas in the appropriate place
|
// Copy the texture into the atlas in the appropriate place
|
||||||
osg::ref_ptr<osg::Image> subtexture = osgDB::readRefImageFile(fullPath, options);
|
osg::ref_ptr<osg::Image> subtexture = osgDB::readRefImageFile(fullPath, options);
|
||||||
|
|
||||||
@ -430,22 +462,13 @@ SGMaterialCache::Atlas SGMaterialLib::getMaterialTextureAtlas(SGVec2f center, co
|
|||||||
// At this point we know that the texture is present in the
|
// At this point we know that the texture is present in the
|
||||||
// atlas and referenced in the textureMap, so add it to the materialLookup
|
// atlas and referenced in the textureMap, so add it to the materialLookup
|
||||||
textureList[i] = atlas.textureMap[fullPath];
|
textureList[i] = atlas.textureMap[fullPath];
|
||||||
//SG_LOG(SG_TERRAIN, SG_ALERT, "materialLookup Index: " << (materialLookupIndex * SGMaterialCache::MAX_TEXTURES + i) << " " << atlas.textureMap[fullPath] << " " << fullPath);
|
|
||||||
} else {
|
|
||||||
textureList[i] = -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill out the rest of the array
|
|
||||||
for (std::size_t i = mat->get_num_textures(0); i < SGMaterialCache::MAX_TEXTURES; ++i) {
|
|
||||||
textureList[i] = -2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We now have a textureList containing the full set of textures. Pack the relevant ones into the Vec4 of the index Uniform.
|
// We now have a textureList containing the full set of textures. Pack the relevant ones into the Vec4 of the index Uniform.
|
||||||
// This is a bit of a hack to maintain compatibility with the WS2.0 material definitions, as the material definitions use the
|
// This is a bit of a hack to maintain compatibility with the WS2.0 material definitions, as the material definitions use the
|
||||||
// 11-15th textures for the various overlay textures for terrain-default.eff, we do the same for ws30.eff
|
// 11-15th textures for the various overlay textures for terrain-default.eff, we do the same for ws30.eff
|
||||||
atlas.textureLookup1->setElement(materialLookupIndex, osg::Vec4f( (float) (textureList[0] / 255.0), (float) (textureList[11] / 255.0), (float) (textureList[12] / 255.0), (float) (textureList[13] / 255.0)));
|
atlas.textureLookup1->setElement(materialLookupIndex, osg::Vec4f( (float) (textureList[0] / 255.0), (float) (textureList[11] / 255.0), (float) (textureList[12] / 255.0), (float) (textureList[13] / 255.0)));
|
||||||
atlas.textureLookup2->setElement(materialLookupIndex, osg::Vec4f( (float) (textureList[14] / 255.0), (float) (textureList[15] / 255.0), 0.0,0.0));
|
atlas.textureLookup2->setElement(materialLookupIndex, osg::Vec4f( (float) (textureList[14] / 255.0), (float) (textureList[15] / 255.0), (float) (textureList[20] / 255.0), (float) (textureList[21] / 255.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
++materialLookupIndex;
|
++materialLookupIndex;
|
||||||
@ -456,6 +479,17 @@ SGMaterialCache::Atlas SGMaterialLib::getMaterialTextureAtlas(SGVec2f center, co
|
|||||||
return atlas;
|
return atlas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SGMaterialCache::addAtlasUniforms(osg::StateSet* stateset) {
|
||||||
|
stateset->addUniform(_atlas.dimensions);
|
||||||
|
stateset->addUniform(_atlas.ambient);
|
||||||
|
stateset->addUniform(_atlas.diffuse);
|
||||||
|
stateset->addUniform(_atlas.specular);
|
||||||
|
stateset->addUniform(_atlas.textureLookup1);
|
||||||
|
stateset->addUniform(_atlas.textureLookup2);
|
||||||
|
stateset->addUniform(_atlas.materialParams1);
|
||||||
|
stateset->addUniform(_atlas.materialParams2);
|
||||||
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
SGMaterialCache::~SGMaterialCache ( void ) {
|
SGMaterialCache::~SGMaterialCache ( void ) {
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "SGMaterialCache::~SGMaterialCache() size=" << cache.size());
|
SG_LOG( SG_TERRAIN, SG_DEBUG, "SGMaterialCache::~SGMaterialCache() size=" << cache.size());
|
||||||
|
@ -69,7 +69,10 @@ public:
|
|||||||
typedef std::map<int, bool> WaterAtlas;
|
typedef std::map<int, bool> WaterAtlas;
|
||||||
|
|
||||||
// Maximum number of textures per texture-set for the Atlas.
|
// Maximum number of textures per texture-set for the Atlas.
|
||||||
static const unsigned int MAX_TEXTURES = 16;
|
static const unsigned int MAX_TEXTURES = 22;
|
||||||
|
|
||||||
|
// Maximum number of material entries in the atlas
|
||||||
|
static const unsigned int MAX_MATERIALS = 64;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
AtlasIndex index;
|
AtlasIndex index;
|
||||||
@ -80,6 +83,10 @@ public:
|
|||||||
osg::ref_ptr<osg::Uniform> ambient;
|
osg::ref_ptr<osg::Uniform> ambient;
|
||||||
osg::ref_ptr<osg::Uniform> diffuse;
|
osg::ref_ptr<osg::Uniform> diffuse;
|
||||||
osg::ref_ptr<osg::Uniform> specular;
|
osg::ref_ptr<osg::Uniform> specular;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Uniform> materialParams1;
|
||||||
|
osg::ref_ptr<osg::Uniform> materialParams2;
|
||||||
|
|
||||||
WaterAtlas waterAtlas;
|
WaterAtlas waterAtlas;
|
||||||
TextureMap textureMap;
|
TextureMap textureMap;
|
||||||
} Atlas;
|
} Atlas;
|
||||||
@ -97,6 +104,8 @@ public:
|
|||||||
|
|
||||||
Atlas getAtlas() { return _atlas; };
|
Atlas getAtlas() { return _atlas; };
|
||||||
|
|
||||||
|
void addAtlasUniforms(osg::StateSet* stateset);
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~SGMaterialCache ( void );
|
~SGMaterialCache ( void );
|
||||||
|
|
||||||
|
@ -1346,7 +1346,8 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
|||||||
const SGGeod loc = computeCenterGeod(buffer, masterLocator);
|
const SGGeod loc = computeCenterGeod(buffer, masterLocator);
|
||||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Applying VPB material " << loc);
|
SG_LOG(SG_TERRAIN, SG_DEBUG, "Applying VPB material " << loc);
|
||||||
|
|
||||||
SGMaterialCache::Atlas atlas = matlib->generateMatCache(loc, _options)->getAtlas();
|
SGMaterialCache* matCache = matlib->generateMatCache(loc, _options);
|
||||||
|
SGMaterialCache::Atlas atlas = matCache->getAtlas();
|
||||||
SGMaterialCache::AtlasIndex atlasIndex = atlas.index;
|
SGMaterialCache::AtlasIndex atlasIndex = atlas.index;
|
||||||
|
|
||||||
// Set the "g" color channel to an index into the atlas index.
|
// Set the "g" color channel to an index into the atlas index.
|
||||||
@ -1385,14 +1386,9 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
|||||||
stateset->setTextureAttributeAndModes(0, texture2D, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(0, texture2D, osg::StateAttribute::ON);
|
||||||
stateset->setTextureAttributeAndModes(1, atlas.image, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(1, atlas.image, osg::StateAttribute::ON);
|
||||||
stateset->addUniform(new osg::Uniform("fg_photoScenery", false));
|
stateset->addUniform(new osg::Uniform("fg_photoScenery", false));
|
||||||
stateset->addUniform(atlas.dimensions);
|
|
||||||
stateset->addUniform(atlas.ambient);
|
|
||||||
stateset->addUniform(atlas.diffuse);
|
|
||||||
stateset->addUniform(atlas.specular);
|
|
||||||
stateset->addUniform(atlas.textureLookup1);
|
|
||||||
stateset->addUniform(atlas.textureLookup2);
|
|
||||||
stateset->addUniform(new osg::Uniform("fg_zUpTransform", osg::Matrixf(osg::Matrix::inverse(makeZUpFrameRelative(loc)))));
|
stateset->addUniform(new osg::Uniform("fg_zUpTransform", osg::Matrixf(osg::Matrix::inverse(makeZUpFrameRelative(loc)))));
|
||||||
stateset->addUniform(new osg::Uniform("fg_modelOffset", (osg::Vec3f) buffer._transform->getMatrix().getTrans()));
|
stateset->addUniform(new osg::Uniform("fg_modelOffset", (osg::Vec3f) buffer._transform->getMatrix().getTrans()));
|
||||||
|
matCache->addAtlasUniforms(stateset);
|
||||||
//SG_LOG(SG_TERRAIN, SG_ALERT, "modeOffset:" << buffer._transform->getMatrix().getTrans().length() << " " << buffer._transform->getMatrix().getTrans());
|
//SG_LOG(SG_TERRAIN, SG_ALERT, "modeOffset:" << buffer._transform->getMatrix().getTrans().length() << " " << buffer._transform->getMatrix().getTrans());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user