shade refactor

This commit is contained in:
Cody Glassman 2023-02-25 11:03:39 -08:00
parent cc5f20d66a
commit ac4787aeec
84 changed files with 737 additions and 658 deletions

View file

@ -13,24 +13,13 @@ namespace MWRender
const float hdrExposureTime
= std::max(Settings::Manager::getFloat("auto exposure speed", "Post Processing"), 0.0001f);
constexpr float minLog = -9.0;
constexpr float maxLog = 4.0;
constexpr float logLumRange = (maxLog - minLog);
constexpr float invLogLumRange = 1.0 / logLumRange;
constexpr float epsilon = 0.004;
Shader::ShaderManager::DefineMap defines = {
{ "minLog", std::to_string(minLog) },
{ "maxLog", std::to_string(maxLog) },
{ "logLumRange", std::to_string(logLumRange) },
{ "invLogLumRange", std::to_string(invLogLumRange) },
{ "hdrExposureTime", std::to_string(hdrExposureTime) },
{ "epsilon", std::to_string(epsilon) },
};
auto vertex = shaderManager.getShader("fullscreen_tri_vertex.glsl", {}, osg::Shader::VERTEX);
auto luminanceFragment = shaderManager.getShader("hdr_luminance_fragment.glsl", defines, osg::Shader::FRAGMENT);
auto resolveFragment = shaderManager.getShader("hdr_resolve_fragment.glsl", defines, osg::Shader::FRAGMENT);
auto vertex = shaderManager.getShader("fullscreen_tri.vert", {});
auto luminanceFragment = shaderManager.getShader("luminance/luminance.frag", defines);
auto resolveFragment = shaderManager.getShader("luminance/resolve.frag", defines);
mResolveProgram = shaderManager.getProgram(vertex, resolveFragment);
mLuminanceProgram = shaderManager.getProgram(vertex, luminanceFragment);

View file

@ -32,20 +32,15 @@ namespace MWRender
Shader::ShaderManager::DefineMap defines;
Stereo::Manager::instance().shaderStereoDefines(defines);
auto fallbackVertex = shaderManager.getShader("fullscreen_tri_vertex.glsl", defines, osg::Shader::VERTEX);
auto fallbackFragment = shaderManager.getShader("fullscreen_tri_fragment.glsl", defines, osg::Shader::FRAGMENT);
mFallbackProgram = shaderManager.getProgram(fallbackVertex, fallbackFragment);
mFallbackProgram = shaderManager.getProgram("fullscreen_tri");
mFallbackStateSet->setAttributeAndModes(mFallbackProgram);
mFallbackStateSet->addUniform(new osg::Uniform("omw_SamplerLastShader", 0));
mFallbackStateSet->addUniform(new osg::Uniform("lastShader", 0));
mFallbackStateSet->addUniform(new osg::Uniform("scaling", osg::Vec2f(1, 1)));
auto multiviewResolveVertex = shaderManager.getShader("multiview_resolve_vertex.glsl", {}, osg::Shader::VERTEX);
auto multiviewResolveFragment
= shaderManager.getShader("multiview_resolve_fragment.glsl", {}, osg::Shader::FRAGMENT);
mMultiviewResolveProgram = shaderManager.getProgram(multiviewResolveVertex, multiviewResolveFragment);
mMultiviewResolveProgram = shaderManager.getProgram("multiview_resolve");
mMultiviewResolveStateSet->setAttributeAndModes(mMultiviewResolveProgram);
mMultiviewResolveStateSet->addUniform(new osg::Uniform("omw_SamplerLastShader", 0));
mMultiviewResolveStateSet->addUniform(new osg::Uniform("lastShader", 0));
}
void PingPongCanvas::setCurrentFrameData(size_t frameId, fx::DispatchArray&& data)

View file

@ -52,11 +52,7 @@ namespace
Shader::ShaderManager& shaderMgr
= MWBase::Environment::get().getResourceSystem()->getSceneManager()->getShaderManager();
osg::ref_ptr<osg::Shader> vertex
= shaderMgr.getShader("precipitation_vertex.glsl", {}, osg::Shader::VERTEX);
osg::ref_ptr<osg::Shader> fragment
= shaderMgr.getShader("precipitation_fragment.glsl", {}, osg::Shader::FRAGMENT);
mProgram = shaderMgr.getProgram(vertex, fragment);
mProgram = shaderMgr.getProgram("depthclipped");
}
private:

View file

@ -156,8 +156,7 @@ namespace MWRender
{
public:
SharedUniformStateUpdater(bool usePlayerUniforms)
: mLinearFac(0.f)
, mNear(0.f)
: mNear(0.f)
, mFar(0.f)
, mWindSpeed(0.f)
, mSkyBlendingStartCoef(Settings::Manager::getFloat("sky blending start", "Fog"))
@ -167,7 +166,6 @@ namespace MWRender
void setDefaults(osg::StateSet* stateset) override
{
stateset->addUniform(new osg::Uniform("linearFac", 0.f));
stateset->addUniform(new osg::Uniform("near", 0.f));
stateset->addUniform(new osg::Uniform("far", 0.f));
stateset->addUniform(new osg::Uniform("skyBlendingStart", 0.f));
@ -183,7 +181,6 @@ namespace MWRender
void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override
{
stateset->getUniform("linearFac")->set(mLinearFac);
stateset->getUniform("near")->set(mNear);
stateset->getUniform("far")->set(mFar);
stateset->getUniform("skyBlendingStart")->set(mFar * mSkyBlendingStartCoef);
@ -196,8 +193,6 @@ namespace MWRender
}
}
void setLinearFac(float linearFac) { mLinearFac = linearFac; }
void setNear(float near) { mNear = near; }
void setFar(float far) { mFar = far; }
@ -209,7 +204,6 @@ namespace MWRender
void setPlayerPos(osg::Vec3f playerPos) { mPlayerPos = playerPos; }
private:
float mLinearFac;
float mNear;
float mFar;
float mWindSpeed;
@ -1293,7 +1287,6 @@ namespace MWRender
if (SceneUtil::AutoDepth::isReversed())
{
mSharedUniformStateUpdater->setLinearFac(-mNearClip / (mViewDistance - mNearClip) - 1.f);
mPerViewUniformStateUpdater->setProjectionMatrix(
SceneUtil::getReversedZProjectionMatrixAsPerspective(fov, aspect, mNearClip, mViewDistance));
}

View file

@ -264,18 +264,10 @@ namespace MWRender
osg::ref_ptr<osg::Camera> screenshotCamera(new osg::Camera);
osg::ref_ptr<osg::ShapeDrawable> quad(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0, 0, 0), 2.0)));
std::map<std::string, std::string> defineMap;
Shader::ShaderManager& shaderMgr = mResourceSystem->getSceneManager()->getShaderManager();
osg::ref_ptr<osg::Shader> fragmentShader(
shaderMgr.getShader("s360_fragment.glsl", defineMap, osg::Shader::FRAGMENT));
osg::ref_ptr<osg::Shader> vertexShader(shaderMgr.getShader("s360_vertex.glsl", defineMap, osg::Shader::VERTEX));
osg::ref_ptr<osg::StateSet> stateset = quad->getOrCreateStateSet();
osg::ref_ptr<osg::Program> program(new osg::Program);
program->addShader(fragmentShader);
program->addShader(vertexShader);
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
Shader::ShaderManager& shaderMgr = mResourceSystem->getSceneManager()->getShaderManager();
stateset->setAttributeAndModes(shaderMgr.getProgram("360"), osg::StateAttribute::ON);
stateset->addUniform(new osg::Uniform("cubeMap", 0));
stateset->addUniform(new osg::Uniform("mapping", screenshotMapping));

View file

@ -366,10 +366,7 @@ namespace MWRender
{
Shader::ShaderManager::DefineMap defines = {};
Stereo::Manager::instance().shaderStereoDefines(defines);
auto vertex = mSceneManager->getShaderManager().getShader("sky_vertex.glsl", defines, osg::Shader::VERTEX);
auto fragment
= mSceneManager->getShaderManager().getShader("sky_fragment.glsl", defines, osg::Shader::FRAGMENT);
auto program = mSceneManager->getShaderManager().getProgram(vertex, fragment);
auto program = mSceneManager->getShaderManager().getProgram("sky", defines);
mEarlyRenderBinRoot->getOrCreateStateSet()->addUniform(new osg::Uniform("pass", -1));
mEarlyRenderBinRoot->getOrCreateStateSet()->setAttributeAndModes(
program, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

View file

@ -34,13 +34,9 @@ namespace MWRender
Shader::ShaderManager::DefineMap defines;
Stereo::Manager::instance().shaderStereoDefines(defines);
osg::ref_ptr<osg::Shader> vertex
= shaderManager.getShader("blended_depth_postpass_vertex.glsl", defines, osg::Shader::VERTEX);
osg::ref_ptr<osg::Shader> fragment
= shaderManager.getShader("blended_depth_postpass_fragment.glsl", defines, osg::Shader::FRAGMENT);
mStateSet->setAttributeAndModes(new osg::BlendFunc, modeOff);
mStateSet->setAttributeAndModes(shaderManager.getProgram(vertex, fragment), modeOn);
mStateSet->setAttributeAndModes(shaderManager.getProgram("depthclipped", defines), modeOn);
mStateSet->setAttributeAndModes(new SceneUtil::AutoDepth, modeOn);
for (unsigned int unit = 1; unit < 8; ++unit)

View file

@ -675,11 +675,7 @@ namespace MWRender
Stereo::Manager::instance().shaderStereoDefines(defineMap);
Shader::ShaderManager& shaderMgr = mResourceSystem->getSceneManager()->getShaderManager();
osg::ref_ptr<osg::Shader> vertexShader(
shaderMgr.getShader("water_vertex.glsl", defineMap, osg::Shader::VERTEX));
osg::ref_ptr<osg::Shader> fragmentShader(
shaderMgr.getShader("water_fragment.glsl", defineMap, osg::Shader::FRAGMENT));
osg::ref_ptr<osg::Program> program = shaderMgr.getProgram(vertexShader, fragmentShader);
osg::ref_ptr<osg::Program> program = shaderMgr.getProgram("water", defineMap);
osg::ref_ptr<osg::Texture2D> normalMap(
new osg::Texture2D(mResourceSystem->getImageManager()->getImage("textures/omw/water_nm.png")));

View file

@ -175,10 +175,10 @@ osg::Group {
struct NifOsgLoaderBSShaderPrefixTest : TestWithParam<ShaderPrefixParams>, BaseNifOsgLoaderTest
{
static constexpr std::array sParams = {
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_Default), "nv_default" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_NoLighting), "nv_nolighting" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_Tile), "nv_default" },
ShaderPrefixParams{ std::numeric_limits<unsigned int>::max(), "nv_default" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_Default), "bs/default" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_NoLighting), "bs/nolighting" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_Tile), "bs/default" },
ShaderPrefixParams{ std::numeric_limits<unsigned int>::max(), "bs/default" },
};
};
@ -204,9 +204,9 @@ osg::Group {
{
static constexpr std::array sParams = {
ShaderPrefixParams{
static_cast<unsigned int>(Nif::BSLightingShaderType::ShaderType_Default), "nv_default" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSLightingShaderType::ShaderType_Cloud), "nv_default" },
ShaderPrefixParams{ std::numeric_limits<unsigned int>::max(), "nv_default" },
static_cast<unsigned int>(Nif::BSLightingShaderType::ShaderType_Default), "bs/default" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSLightingShaderType::ShaderType_Cloud), "bs/default" },
ShaderPrefixParams{ std::numeric_limits<unsigned int>::max(), "bs/default" },
};
};

View file

@ -17,7 +17,7 @@ namespace
ShaderManager mManager;
ShaderManager::DefineMap mDefines;
ShaderManagerTest() { mManager.setShaderPath("."); }
ShaderManagerTest() { mManager.setShaderPath("tests_output"); }
template <class F>
void withShaderFile(const std::string& content, F&& f)
@ -28,16 +28,17 @@ namespace
template <class F>
void withShaderFile(const std::string& suffix, const std::string& content, F&& f)
{
auto path = TestingOpenMW::outputFilePath(
std::string(UnitTest::GetInstance()->current_test_info()->name()) + suffix + ".glsl");
auto subdir = std::filesystem::path("lib")
/ std::filesystem::path(
std::string(UnitTest::GetInstance()->current_test_info()->name()) + suffix + ".vert");
auto path = TestingOpenMW::outputFilePathWithSubDir(subdir);
{
std::ofstream stream(path);
stream << content;
stream.close();
}
f(path);
f(subdir);
}
};
@ -46,7 +47,7 @@ namespace
const std::string content;
withShaderFile(content, [this](const std::filesystem::path& templateName) {
EXPECT_TRUE(mManager.getShader(Files::pathToUnicodeString(templateName), {}, osg::Shader::VERTEX));
EXPECT_TRUE(mManager.getShader(Files::pathToUnicodeString(templateName)));
});
}
@ -57,8 +58,7 @@ namespace
"void main() {}\n";
withShaderFile(content, [&](const std::filesystem::path& templateName) {
const auto shader
= mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX);
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName), mDefines);
ASSERT_TRUE(shader);
EXPECT_EQ(shader->getShaderSource(), content);
});
@ -80,8 +80,7 @@ namespace
"void main() { bar() }\n";
withShaderFile(content2, [&](const std::filesystem::path& templateName2) {
const auto shader
= mManager.getShader(Files::pathToUnicodeString(templateName2), mDefines, osg::Shader::VERTEX);
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName2), mDefines);
ASSERT_TRUE(shader);
const std::string expected
= "#version 120\n"
@ -111,8 +110,7 @@ namespace
withShaderFile(content, [&](const std::filesystem::path& templateName) {
mDefines["flag"] = "1";
const auto shader
= mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX);
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName), mDefines);
ASSERT_TRUE(shader);
const std::string expected
= "#version 120\n"
@ -133,8 +131,7 @@ namespace
withShaderFile(content, [&](const std::filesystem::path& templateName) {
mDefines["list"] = "1,2,3";
const auto shader
= mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX);
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName), mDefines);
ASSERT_TRUE(shader);
const std::string expected
= "#version 120\n"
@ -174,8 +171,7 @@ namespace
withShaderFile(content, [&](const std::filesystem::path& templateName) {
mDefines["list"] = "1,2,3";
const auto shader
= mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX);
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName), mDefines);
ASSERT_TRUE(shader);
const std::string expected
= "#version 120\n"
@ -221,7 +217,7 @@ namespace
"void main() {}\n";
withShaderFile(content, [&](const std::filesystem::path& templateName) {
EXPECT_FALSE(mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX));
EXPECT_FALSE(mManager.getShader(Files::pathToUnicodeString(templateName), mDefines));
});
}
@ -233,7 +229,7 @@ namespace
"void main() {}\n";
withShaderFile(content, [&](const std::filesystem::path& templateName) {
EXPECT_FALSE(mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX));
EXPECT_FALSE(mManager.getShader(Files::pathToUnicodeString(templateName), mDefines));
});
}
}

View file

@ -18,6 +18,14 @@ namespace TestingOpenMW
return dir / Misc::StringUtils::stringToU8String(name);
}
inline std::filesystem::path outputFilePathWithSubDir(const std::filesystem::path& subpath)
{
std::filesystem::path path("tests_output");
path /= subpath;
std::filesystem::create_directories(path.parent_path());
return path;
}
inline std::filesystem::path temporaryFilePath(const std::string name)
{
return std::filesystem::temp_directory_path() / name;