1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-27 12:40:25 +00:00

Fix red-green normal map handling for terrain

This commit is contained in:
Alexei Kotov 2024-03-28 07:43:33 +03:00
parent cf6b95ae7c
commit 3c0c1717a9
6 changed files with 35 additions and 13 deletions

View file

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

View file

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

View file

@ -286,4 +286,18 @@ namespace SceneUtil
mOperationQueue->add(operation); 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;
}
} }

View file

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

View file

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

View file

@ -10,6 +10,7 @@
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/sceneutil/depth.hpp> #include <components/sceneutil/depth.hpp>
#include <components/sceneutil/util.hpp>
#include <components/shader/shadermanager.hpp> #include <components/shader/shadermanager.hpp>
#include <components/stereo/stereomanager.hpp> #include <components/stereo/stereomanager.hpp>
@ -271,18 +272,30 @@ namespace Terrain
stateset->addUniform(UniformCollection::value().mBlendMap); stateset->addUniform(UniformCollection::value().mBlendMap);
} }
bool parallax = it->mNormalMap && it->mParallax;
bool reconstructNormalZ = false;
if (it->mNormalMap) if (it->mNormalMap)
{ {
stateset->setTextureAttributeAndModes(2, it->mNormalMap); stateset->setTextureAttributeAndModes(2, it->mNormalMap);
stateset->addUniform(UniformCollection::value().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; Shader::ShaderManager::DefineMap defineMap;
defineMap["normalMap"] = (it->mNormalMap) ? "1" : "0"; defineMap["normalMap"] = (it->mNormalMap) ? "1" : "0";
defineMap["blendMap"] = (!blendmaps.empty()) ? "1" : "0"; defineMap["blendMap"] = (!blendmaps.empty()) ? "1" : "0";
defineMap["specularMap"] = it->mSpecular ? "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["writeNormals"] = (it == layers.end() - 1) ? "1" : "0";
defineMap["reconstructNormalZ"] = reconstructNormalZ ? "1" : "0";
Stereo::shaderStereoDefines(defineMap); Stereo::shaderStereoDefines(defineMap);
stateset->setAttributeAndModes(shaderManager.getProgram("terrain", defineMap)); stateset->setAttributeAndModes(shaderManager.getProgram("terrain", defineMap));