Fix red-green normal map handling for terrain

pull/3235/head
Alexei Kotov 9 months ago
parent cf6b95ae7c
commit 3c0c1717a9

@ -152,7 +152,6 @@ CSMWorld::Data::Data(ToUTF8::FromType encoding, const Files::PathContainer& data
mResourceSystem
= std::make_unique<Resource::ResourceSystem>(mVFS.get(), expiryDelay, &mEncoder.getStatelessEncoder());
// FIXME: this is severely out of date (see #7595)
Shader::ShaderManager::DefineMap defines
= mResourceSystem->getSceneManager()->getShaderManager().getGlobalDefines();
Shader::ShaderManager::DefineMap shadowDefines = SceneUtil::ShadowManager::getShadowsDisabledDefines();

@ -446,7 +446,6 @@ namespace MWRender
globalDefines["useOVR_multiview"] = "0";
globalDefines["numViews"] = "1";
globalDefines["disableNormals"] = "1";
globalDefines["reconstructNormalZ"] = "0";
for (auto itr = lightDefines.begin(); itr != lightDefines.end(); itr++)
globalDefines[itr->first] = itr->second;

@ -286,4 +286,18 @@ namespace SceneUtil
mOperationQueue->add(operation);
}
bool isRedGreenPixelFormat(GLenum format)
{
switch (format)
{
case GL_RG:
case GL_RG_INTEGER:
case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
return true;
}
return false;
}
}

@ -112,6 +112,8 @@ namespace SceneUtil
protected:
osg::ref_ptr<osg::OperationQueue> mOperationQueue;
};
bool isRedGreenPixelFormat(GLenum format);
}
#endif

@ -26,6 +26,7 @@
#include <components/sceneutil/morphgeometry.hpp>
#include <components/sceneutil/riggeometry.hpp>
#include <components/sceneutil/riggeometryosgaextension.hpp>
#include <components/sceneutil/util.hpp>
#include <components/settings/settings.hpp>
#include <components/stereo/stereomanager.hpp>
#include <components/vfs/manager.hpp>
@ -445,19 +446,13 @@ namespace Shader
if (normalMap != nullptr && normalMap->getImage(0))
{
// Special handling for red-green normal maps (e.g. BC5 or R8G8).
switch (normalMap->getImage(0)->getPixelFormat())
{
case GL_RG:
case GL_RG_INTEGER:
case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
// Special handling for red-green normal maps (e.g. BC5 or R8G8)
if (SceneUtil::isRedGreenPixelFormat(normalMap->getImage(0)->getPixelFormat()))
{
mRequirements.back().mReconstructNormalZ = true;
mRequirements.back().mNormalHeight = false;
}
}
}
if (mAutoUseSpecularMaps && diffuseMap != nullptr && specularMap == nullptr && diffuseMap->getImage(0))
{

@ -10,6 +10,7 @@
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/depth.hpp>
#include <components/sceneutil/util.hpp>
#include <components/shader/shadermanager.hpp>
#include <components/stereo/stereomanager.hpp>
@ -271,18 +272,30 @@ namespace Terrain
stateset->addUniform(UniformCollection::value().mBlendMap);
}
bool parallax = it->mNormalMap && it->mParallax;
bool reconstructNormalZ = false;
if (it->mNormalMap)
{
stateset->setTextureAttributeAndModes(2, it->mNormalMap);
stateset->addUniform(UniformCollection::value().mNormalMap);
// Special handling for red-green normal maps (e.g. BC5 or R8G8).
const osg::Image* image = it->mNormalMap->getImage(0);
if (image && SceneUtil::isRedGreenPixelFormat(image->getPixelFormat()))
{
reconstructNormalZ = true;
parallax = false;
}
}
Shader::ShaderManager::DefineMap defineMap;
defineMap["normalMap"] = (it->mNormalMap) ? "1" : "0";
defineMap["blendMap"] = (!blendmaps.empty()) ? "1" : "0";
defineMap["specularMap"] = it->mSpecular ? "1" : "0";
defineMap["parallax"] = (it->mNormalMap && it->mParallax) ? "1" : "0";
defineMap["parallax"] = parallax ? "1" : "0";
defineMap["writeNormals"] = (it == layers.end() - 1) ? "1" : "0";
defineMap["reconstructNormalZ"] = reconstructNormalZ ? "1" : "0";
Stereo::shaderStereoDefines(defineMap);
stateset->setAttributeAndModes(shaderManager.getProgram("terrain", defineMap));

Loading…
Cancel
Save