1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-14 21:39:41 +00:00

mono-only version of the shader linking system introduced in the stereo MR

This commit is contained in:
madsbuvi 2022-04-26 19:54:24 +02:00
parent dd4f1e3044
commit dc3045c970
19 changed files with 412 additions and 99 deletions

View file

@ -55,6 +55,7 @@ if (GTEST_FOUND AND GMOCK_FOUND)
shader/parsedefines.cpp
shader/parsefors.cpp
shader/parselinks.cpp
shader/shadermanager.cpp
../openmw/options.cpp

View file

@ -2,6 +2,7 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <vector>
namespace
{
@ -16,6 +17,12 @@ namespace
const std::string mName = "shader";
};
static bool parseFors(std::string& source, const std::string& templateName)
{
std::vector<std::string> dummy;
return parseDirectives(source, dummy, {}, {}, templateName);
}
TEST_F(ShaderParseForsTest, empty_should_succeed)
{
ASSERT_TRUE(parseFors(mSource, mName));

View file

@ -0,0 +1,100 @@
#include <components/shader/shadermanager.hpp>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <vector>
namespace
{
using namespace testing;
using namespace Shader;
using DefineMap = ShaderManager::DefineMap;
struct ShaderParseLinksTest : Test
{
std::string mSource;
std::vector<std::string> mLinkTargets;
ShaderManager::DefineMap mDefines;
const std::string mName = "my_shader.glsl";
bool parseLinks()
{
return parseDirectives(mSource, mLinkTargets, mDefines, {}, mName);
}
};
TEST_F(ShaderParseLinksTest, empty_should_succeed)
{
ASSERT_TRUE(parseLinks());
EXPECT_EQ(mSource, "");
EXPECT_TRUE(mLinkTargets.empty());
}
TEST_F(ShaderParseLinksTest, should_fail_for_single_escape_symbol)
{
mSource = "$";
ASSERT_FALSE(parseLinks());
EXPECT_EQ(mSource, "$");
EXPECT_TRUE(mLinkTargets.empty());
}
TEST_F(ShaderParseLinksTest, should_fail_on_first_found_escaped_not_valid_directive)
{
mSource = "$foo ";
ASSERT_FALSE(parseLinks());
EXPECT_EQ(mSource, "$foo ");
EXPECT_TRUE(mLinkTargets.empty());
}
TEST_F(ShaderParseLinksTest, should_fail_on_absent_link_target)
{
mSource = "$link ";
ASSERT_FALSE(parseLinks());
EXPECT_EQ(mSource, "$link ");
EXPECT_TRUE(mLinkTargets.empty());
}
TEST_F(ShaderParseLinksTest, should_not_require_newline)
{
mSource = "$link \"foo.glsl\"";
ASSERT_TRUE(parseLinks());
EXPECT_EQ(mSource, "");
ASSERT_EQ(mLinkTargets.size(), 1);
EXPECT_EQ(mLinkTargets[0], "foo.glsl");
}
TEST_F(ShaderParseLinksTest, should_require_quotes)
{
mSource = "$link foo.glsl";
ASSERT_FALSE(parseLinks());
EXPECT_EQ(mSource, "$link foo.glsl");
EXPECT_EQ(mLinkTargets.size(), 0);
}
TEST_F(ShaderParseLinksTest, should_be_replaced_with_empty_line)
{
mSource = "$link \"foo.glsl\"\nbar";
ASSERT_TRUE(parseLinks());
EXPECT_EQ(mSource, "\nbar");
ASSERT_EQ(mLinkTargets.size(), 1);
EXPECT_EQ(mLinkTargets[0], "foo.glsl");
}
TEST_F(ShaderParseLinksTest, should_only_accept_on_true_condition)
{
mSource =
R"glsl(
$link "foo.glsl" if 1
$link "bar.glsl" if 0
)glsl";
ASSERT_TRUE(parseLinks());
EXPECT_EQ(mSource,
R"glsl(
)glsl");
ASSERT_EQ(mLinkTargets.size(), 1);
EXPECT_EQ(mLinkTargets[0], "foo.glsl");
}
}

View file

@ -3,6 +3,7 @@
#include <fstream>
#include <algorithm>
#include <sstream>
#include <regex>
#include <osg/Program>
@ -142,11 +143,123 @@ namespace Shader
return true;
}
bool parseFors(std::string& source, const std::string& templateName)
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos)
{
size_t iterNameStart = foundPos + strlen("$foreach") + 1;
size_t iterNameEnd = source.find_first_of(" \n\r()[].;,", iterNameStart);
if (iterNameEnd == std::string::npos)
{
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
return false;
}
std::string iteratorName = "$" + source.substr(iterNameStart, iterNameEnd - iterNameStart);
size_t listStart = iterNameEnd + 1;
size_t listEnd = source.find_first_of("\n\r", listStart);
if (listEnd == std::string::npos)
{
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
return false;
}
std::string list = source.substr(listStart, listEnd - listStart);
std::vector<std::string> listElements;
if (list != "")
Misc::StringUtils::split(list, listElements, ",");
size_t contentStart = source.find_first_not_of("\n\r", listEnd);
size_t contentEnd = source.find("$endforeach", contentStart);
if (contentEnd == std::string::npos)
{
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
return false;
}
std::string content = source.substr(contentStart, contentEnd - contentStart);
size_t overallEnd = contentEnd + std::string("$endforeach").length();
size_t lineDirectivePosition = source.rfind("#line", overallEnd);
int lineNumber;
if (lineDirectivePosition != std::string::npos)
{
size_t lineNumberStart = lineDirectivePosition + std::string("#line ").length();
size_t lineNumberEnd = source.find_first_not_of("0123456789", lineNumberStart);
std::string lineNumberString = source.substr(lineNumberStart, lineNumberEnd - lineNumberStart);
lineNumber = std::stoi(lineNumberString);
}
else
{
lineDirectivePosition = 0;
lineNumber = 2;
}
lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + overallEnd, '\n');
std::string replacement = "";
for (std::vector<std::string>::const_iterator element = listElements.cbegin(); element != listElements.cend(); element++)
{
std::string contentInstance = content;
size_t foundIterator;
while ((foundIterator = contentInstance.find(iteratorName)) != std::string::npos)
contentInstance.replace(foundIterator, iteratorName.length(), *element);
replacement += contentInstance;
}
replacement += "\n#line " + std::to_string(lineNumber);
source.replace(foundPos, overallEnd - foundPos, replacement);
return true;
}
bool parseLinkDirective(std::string& source, std::string& linkTarget, const std::string& templateName, size_t foundPos)
{
size_t endPos = foundPos + 5;
size_t lineEnd = source.find_first_of('\n', endPos);
// If lineEnd = npos, this is the last line, so no need to check
std::string linkStatement = source.substr(endPos, lineEnd - endPos);
std::regex linkRegex(
R"r(\s*"([^"]+)"\s*)r" // Find any quoted string as the link name -> match[1]
R"r((if\s+)r" // Begin optional condition -> match[2]
R"r((!)?\s*)r" // Optional ! -> match[3]
R"r(([_a-zA-Z0-9]+)?)r" // The condition -> match[4]
R"r()?\s*)r" // End optional condition -> match[2]
);
std::smatch linkMatch;
bool hasCondition = false;
std::string linkConditionExpression;
if (std::regex_match(linkStatement, linkMatch, linkRegex))
{
linkTarget = linkMatch[1].str();
hasCondition = !linkMatch[2].str().empty();
linkConditionExpression = linkMatch[4].str();
}
else
{
Log(Debug::Error) << "Shader " << templateName << " error: Expected a shader filename to link";
return false;
}
if (linkTarget.empty())
{
Log(Debug::Error) << "Shader " << templateName << " error: Empty link name";
return false;
}
if (hasCondition)
{
bool condition = !(linkConditionExpression.empty() || linkConditionExpression == "0");
if (linkMatch[3].str() == "!")
condition = !condition;
if (!condition)
linkTarget = "";
}
source.replace(foundPos, lineEnd - foundPos, "");
return true;
}
bool parseDirectives(std::string& source, std::vector<std::string>& linkedShaderTemplateNames, const ShaderManager::DefineMap& defines, const ShaderManager::DefineMap& globalDefines, const std::string& templateName)
{
const char escapeCharacter = '$';
size_t foundPos = 0;
while ((foundPos = source.find(escapeCharacter)) != std::string::npos)
while ((foundPos = source.find(escapeCharacter, foundPos)) != std::string::npos)
{
size_t endPos = source.find_first_of(" \n\r()[].;,", foundPos);
if (endPos == std::string::npos)
@ -154,72 +267,25 @@ namespace Shader
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
return false;
}
std::string command = source.substr(foundPos + 1, endPos - (foundPos + 1));
if (command != "foreach")
std::string directive = source.substr(foundPos + 1, endPos - (foundPos + 1));
if (directive == "foreach")
{
Log(Debug::Error) << "Shader " << templateName << " error: Unknown shader directive: $" << command;
return false;
if (!parseForeachDirective(source, templateName, foundPos))
return false;
}
size_t iterNameStart = endPos + 1;
size_t iterNameEnd = source.find_first_of(" \n\r()[].;,", iterNameStart);
if (iterNameEnd == std::string::npos)
else if (directive == "link")
{
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
return false;
}
std::string iteratorName = "$" + source.substr(iterNameStart, iterNameEnd - iterNameStart);
size_t listStart = iterNameEnd + 1;
size_t listEnd = source.find_first_of("\n\r", listStart);
if (listEnd == std::string::npos)
{
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
return false;
}
std::string list = source.substr(listStart, listEnd - listStart);
std::vector<std::string> listElements;
if (list != "")
Misc::StringUtils::split (list, listElements, ",");
size_t contentStart = source.find_first_not_of("\n\r", listEnd);
size_t contentEnd = source.find("$endforeach", contentStart);
if (contentEnd == std::string::npos)
{
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
return false;
}
std::string content = source.substr(contentStart, contentEnd - contentStart);
size_t overallEnd = contentEnd + std::string("$endforeach").length();
size_t lineDirectivePosition = source.rfind("#line", overallEnd);
int lineNumber;
if (lineDirectivePosition != std::string::npos)
{
size_t lineNumberStart = lineDirectivePosition + std::string("#line ").length();
size_t lineNumberEnd = source.find_first_not_of("0123456789", lineNumberStart);
std::string lineNumberString = source.substr(lineNumberStart, lineNumberEnd - lineNumberStart);
lineNumber = std::stoi(lineNumberString);
std::string linkTarget;
if (!parseLinkDirective(source, linkTarget, templateName, foundPos))
return false;
if (!linkTarget.empty() && linkTarget != templateName)
linkedShaderTemplateNames.push_back(linkTarget);
}
else
{
lineDirectivePosition = 0;
lineNumber = 2;
Log(Debug::Error) << "Shader " << templateName << " error: Unknown shader directive: $" << directive;
return false;
}
lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + overallEnd, '\n');
std::string replacement = "";
for (std::vector<std::string>::const_iterator element = listElements.cbegin(); element != listElements.cend(); element++)
{
std::string contentInstance = content;
size_t foundIterator;
while ((foundIterator = contentInstance.find(iteratorName)) != std::string::npos)
contentInstance.replace(foundIterator, iteratorName.length(), *element);
replacement += contentInstance;
}
replacement += "\n#line " + std::to_string(lineNumber);
source.replace(foundPos, overallEnd - foundPos, replacement);
}
return true;
@ -265,6 +331,10 @@ namespace Shader
else
forIterators.pop_back();
}
else if (define == "link")
{
source.replace(foundPos, 1, "$");
}
else if (std::find(forIterators.begin(), forIterators.end(), define) != forIterators.end())
{
source.replace(foundPos, 1, "$");
@ -288,7 +358,7 @@ namespace Shader
osg::ref_ptr<osg::Shader> ShaderManager::getShader(const std::string &templateName, const ShaderManager::DefineMap &defines, osg::Shader::Type shaderType)
{
std::lock_guard<std::mutex> lock(mMutex);
std::unique_lock<std::mutex> lock(mMutex);
// read the template if we haven't already
TemplateMap::iterator templateIt = mShaderTemplates.find(templateName);
@ -319,7 +389,8 @@ namespace Shader
if (shaderIt == mShaders.end())
{
std::string shaderSource = templateIt->second;
if (!parseDefines(shaderSource, defines, mGlobalDefines, templateName) || !parseFors(shaderSource, templateName))
std::vector<std::string> linkedShaderNames;
if (!createSourceFromTemplate(shaderSource, linkedShaderNames, templateName, defines))
{
// Add to the cache anyway to avoid logging the same error over and over.
mShaders.insert(std::make_pair(std::make_pair(templateName, defines), nullptr));
@ -333,6 +404,10 @@ namespace Shader
static unsigned int counter = 0;
shader->setName(Misc::StringUtils::format("%u %s", counter++, templateName));
lock.unlock();
getLinkedShaders(shader, linkedShaderNames, defines);
lock.lock();
shaderIt = mShaders.insert(std::make_pair(std::make_pair(templateName, defines), shader)).first;
}
return shaderIt->second;
@ -348,6 +423,9 @@ namespace Shader
osg::ref_ptr<osg::Program> program = programTemplate ? cloneProgram(programTemplate) : osg::ref_ptr<osg::Program>(new osg::Program);
program->addShader(vertexShader);
program->addShader(fragmentShader);
addLinkedShaders(vertexShader, program);
addLinkedShaders(fragmentShader, program);
found = mPrograms.insert(std::make_pair(std::make_pair(vertexShader, fragmentShader), program)).first;
}
return found->second;
@ -377,11 +455,14 @@ namespace Shader
// I'm not sure how to handle a shader that was already broken as there's no way to get a potential replacement to the nodes that need it.
continue;
std::string shaderSource = mShaderTemplates[templateId];
if (!parseDefines(shaderSource, defines, mGlobalDefines, templateId) || !parseFors(shaderSource, templateId))
std::vector<std::string> linkedShaderNames;
if (!createSourceFromTemplate(shaderSource, linkedShaderNames, templateId, defines))
// We just broke the shader and there's no way to force existing objects back to fixed-function mode as we would when creating the shader.
// If we put a nullptr in the shader map, we just lose the ability to put a working one in later.
continue;
shader->setShaderSource(shaderSource);
getLinkedShaders(shader, linkedShaderNames, defines);
}
}
@ -397,4 +478,35 @@ namespace Shader
program->releaseGLObjects(state);
}
bool ShaderManager::createSourceFromTemplate(std::string& source, std::vector<std::string>& linkedShaderTemplateNames, const std::string& templateName, const ShaderManager::DefineMap& defines)
{
if (!parseDefines(source, defines, mGlobalDefines, templateName))
return false;
if (!parseDirectives(source, linkedShaderTemplateNames, defines, mGlobalDefines, templateName))
return false;
return true;
}
void ShaderManager::getLinkedShaders(osg::ref_ptr<osg::Shader> shader, const std::vector<std::string>& linkedShaderNames, const DefineMap& defines)
{
mLinkedShaders.erase(shader);
if (linkedShaderNames.empty())
return;
for (auto& linkedShaderName : linkedShaderNames)
{
auto linkedShader = getShader(linkedShaderName, defines, shader->getType());
if (linkedShader)
mLinkedShaders[shader].emplace_back(linkedShader);
}
}
void ShaderManager::addLinkedShaders(osg::ref_ptr<osg::Shader> shader, osg::ref_ptr<osg::Program> program)
{
auto linkedIt = mLinkedShaders.find(shader);
if (linkedIt != mLinkedShaders.end())
for (const auto& linkedShader : linkedIt->second)
program->addShader(linkedShader);
}
}

View file

@ -4,6 +4,7 @@
#include <string>
#include <map>
#include <mutex>
#include <vector>
#include <osg/ref_ptr>
@ -51,7 +52,12 @@ namespace Shader
void releaseGLObjects(osg::State* state);
bool createSourceFromTemplate(std::string& source, std::vector<std::string>& linkedShaderTemplateNames, const std::string& templateName, const ShaderManager::DefineMap& defines);
private:
void getLinkedShaders(osg::ref_ptr<osg::Shader> shader, const std::vector<std::string>& linkedShaderNames, const DefineMap& defines);
void addLinkedShaders(osg::ref_ptr<osg::Shader> shader, osg::ref_ptr<osg::Program> program);
std::string mPath;
DefineMap mGlobalDefines;
@ -67,15 +73,23 @@ namespace Shader
typedef std::map<std::pair<osg::ref_ptr<osg::Shader>, osg::ref_ptr<osg::Shader> >, osg::ref_ptr<osg::Program> > ProgramMap;
ProgramMap mPrograms;
typedef std::vector<osg::ref_ptr<osg::Shader> > ShaderList;
typedef std::map<osg::ref_ptr<osg::Shader>, ShaderList> LinkedShadersMap;
LinkedShadersMap mLinkedShaders;
std::mutex mMutex;
osg::ref_ptr<const osg::Program> mProgramTemplate;
};
bool parseFors(std::string& source, const std::string& templateName);
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos);
bool parseLinkDirective(std::string& source, std::string& linkTarget, const std::string& templateName, size_t foundPos);
bool parseDefines(std::string& source, const ShaderManager::DefineMap& defines,
const ShaderManager::DefineMap& globalDefines, const std::string& templateName);
bool parseDirectives(std::string& source, std::vector<std::string>& linkedShaderTemplateNames, const ShaderManager::DefineMap& defines,
const ShaderManager::DefineMap& globalDefines, const std::string& templateName);
}
#endif

View file

@ -16,6 +16,10 @@ set(SHADER_FILES
depth.glsl
objects_vertex.glsl
objects_fragment.glsl
openmw_fragment.glsl
openmw_fragment.h.glsl
openmw_vertex.glsl
openmw_vertex.h.glsl
terrain_vertex.glsl
terrain_fragment.glsl
lighting.glsl

View file

@ -1,12 +1,12 @@
#version 120
uniform mat4 projectionMatrix;
#include "openmw_vertex.glsl"
centroid varying vec4 passColor;
void main()
{
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
gl_Position = mw_modelToClip(gl_Vertex);
passColor = gl_Color;
}

View file

@ -1,5 +1,7 @@
#version 120
#include "openmw_vertex.h.glsl"
#if @useUBO
#extension GL_ARB_uniform_buffer_object : require
#endif
@ -46,7 +48,6 @@ uniform mat4 osg_ViewMatrixInverse;
uniform mat4 osg_ViewMatrix;
uniform float windSpeed;
uniform vec3 playerPos;
uniform mat4 projectionMatrix;
#if @groundcoverStompMode == 0
#else
@ -143,7 +144,7 @@ void main(void)
if (length(gl_ModelViewMatrix * vec4(position, 1.0)) > @groundcoverFadeEnd)
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
else
gl_Position = projectionMatrix * viewPos;
gl_Position = mw_viewToClip(mw_viewStereoAdjust(viewPos));
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);

View file

@ -1,5 +1,7 @@
#version 120
#include "openmw_vertex.h.glsl"
#if @useUBO
#extension GL_ARB_uniform_buffer_object : require
#endif
@ -8,8 +10,6 @@
#extension GL_EXT_gpu_shader4: require
#endif
uniform mat4 projectionMatrix;
#if @diffuseMap
varying vec2 diffuseMapUV;
#endif
@ -38,9 +38,9 @@ varying vec3 passNormal;
void main(void)
{
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
gl_Position = mw_modelToClip(gl_Vertex);
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
vec4 viewPos = mw_modelToView(gl_Vertex);
gl_ClipVertex = viewPos;
euclideanDepth = length(viewPos.xyz);
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);

View file

@ -1,6 +1,6 @@
#version 120
uniform mat4 projectionMatrix;
#include "openmw_vertex.h.glsl"
#if @diffuseMap
varying vec2 diffuseMapUV;
@ -23,9 +23,9 @@ varying float passFalloff;
void main(void)
{
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
gl_Position = mw_modelToClip(gl_Vertex);
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
vec4 viewPos = mw_modelToView(gl_Vertex);
gl_ClipVertex = viewPos;
#if @radialFog
euclideanDepth = length(viewPos.xyz);

View file

@ -1,5 +1,7 @@
#version 120
#include "openmw_vertex.h.glsl"
#if @useUBO
#extension GL_ARB_uniform_buffer_object : require
#endif
@ -8,8 +10,6 @@
#extension GL_EXT_gpu_shader4: require
#endif
uniform mat4 projectionMatrix;
#if @diffuseMap
varying vec2 diffuseMapUV;
#endif
@ -72,9 +72,9 @@ varying vec3 passNormal;
void main(void)
{
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
gl_Position = mw_modelToClip(gl_Vertex);
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
vec4 viewPos = mw_modelToView(gl_Vertex);
gl_ClipVertex = viewPos;
euclideanDepth = length(viewPos.xyz);

View file

@ -0,0 +1,26 @@
#version 120
#include "openmw_fragment.h.glsl"
uniform sampler2D reflectionMap;
vec4 mw_sampleReflectionMap(vec2 uv)
{
return texture2D(reflectionMap, uv);
}
#if @refraction_enabled
uniform sampler2D refractionMap;
uniform sampler2D refractionDepthMap;
vec4 mw_sampleRefractionMap(vec2 uv)
{
return texture2D(refractionMap, uv);
}
float mw_sampleRefractionDepthMap(vec2 uv)
{
return texture2D(refractionDepthMap, uv).x;
}
#endif

View file

@ -0,0 +1,8 @@
@link "openmw_fragment.glsl"
vec4 mw_sampleReflectionMap(vec2 uv);
#if @refraction_enabled
vec4 mw_sampleRefractionMap(vec2 uv);
float mw_sampleRefractionDepthMap(vec2 uv);
#endif

View file

@ -0,0 +1,35 @@
#version 120
#include "openmw_vertex.h.glsl"
uniform mat4 projectionMatrix;
vec4 mw_modelToClip(vec4 pos)
{
return projectionMatrix * mw_modelToView(pos);
}
vec4 mw_modelToView(vec4 pos)
{
return gl_ModelViewMatrix * pos;
}
vec4 mw_viewToClip(vec4 pos)
{
return projectionMatrix * pos;
}
vec4 mw_viewStereoAdjust(vec4 pos)
{
return pos;
}
mat4 mw_viewMatrix()
{
return gl_ModelViewMatrix;
}
mat4 mw_projectionMatrix()
{
return projectionMatrix;
}

View file

@ -0,0 +1,8 @@
@link "openmw_vertex.glsl"
vec4 mw_modelToClip(vec4 pos);
vec4 mw_modelToView(vec4 pos);
vec4 mw_viewToClip(vec4 pos);
vec4 mw_viewStereoAdjust(vec4 pos);
mat4 mw_viewMatrix();
mat4 mw_projectionMatrix();

View file

@ -1,8 +1,9 @@
#version 120
#include "openmw_vertex.h.glsl"
#include "skypasses.glsl"
uniform mat4 projectionMatrix;
uniform int pass;
varying vec4 passColor;
@ -10,7 +11,7 @@ varying vec2 diffuseMapUV;
void main()
{
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
gl_Position = mw_modelToClip(gl_Vertex);
passColor = gl_Color;
if (pass == PASS_CLOUDS)

View file

@ -1,5 +1,7 @@
#version 120
#include "openmw_vertex.h.glsl"
#if @useUBO
#extension GL_ARB_uniform_buffer_object : require
#endif
@ -8,8 +10,6 @@
#extension GL_EXT_gpu_shader4: require
#endif
uniform mat4 projectionMatrix;
varying vec2 uv;
varying float euclideanDepth;
varying float linearDepth;
@ -31,9 +31,9 @@ varying vec3 passNormal;
void main(void)
{
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
gl_Position = mw_modelToClip(gl_Vertex);
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
vec4 viewPos = mw_modelToView(gl_Vertex);
gl_ClipVertex = viewPos;
euclideanDepth = length(viewPos.xyz);
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);

View file

@ -1,5 +1,7 @@
#version 120
#include "openmw_fragment.h.glsl"
#if @useUBO
#extension GL_ARB_uniform_buffer_object : require
#endif
@ -207,12 +209,6 @@ varying float linearDepth;
uniform sampler2D normalMap;
uniform sampler2D reflectionMap;
#if REFRACTION
uniform sampler2D refractionMap;
uniform sampler2D refractionDepthMap;
#endif
uniform float osg_SimulationTime;
uniform float near;
@ -299,14 +295,14 @@ void main(void)
vec2 screenCoordsOffset = normal.xy * REFL_BUMP;
#if REFRACTION
float depthSample = linearizeDepth(texture2D(refractionDepthMap,screenCoords).x) * radialise;
float depthSampleDistorted = linearizeDepth(texture2D(refractionDepthMap,screenCoords-screenCoordsOffset).x) * radialise;
float depthSample = linearizeDepth(mw_sampleRefractionDepthMap(screenCoords)) * radialise;
float depthSampleDistorted = linearizeDepth(mw_sampleRefractionDepthMap(screenCoords-screenCoordsOffset)) * radialise;
float surfaceDepth = linearizeDepth(gl_FragCoord.z) * radialise;
float realWaterDepth = depthSample - surfaceDepth; // undistorted water depth in view direction, independent of frustum
screenCoordsOffset *= clamp(realWaterDepth / BUMP_SUPPRESS_DEPTH,0,1);
#endif
// reflection
vec3 reflection = texture2D(reflectionMap, screenCoords + screenCoordsOffset).rgb;
vec3 reflection = mw_sampleReflectionMap(screenCoords + screenCoordsOffset).rgb;
// specular
float specular = pow(max(dot(reflect(vVec, normal), lVec), 0.0),SPEC_HARDNESS) * shadow;
@ -324,7 +320,7 @@ void main(void)
rainSpecular *= clamp(fresnel*6.0 + specular * sunSpec.w, 0.0, 1.0);
// refraction
vec3 refraction = texture2D(refractionMap, screenCoords - screenCoordsOffset).rgb;
vec3 refraction = mw_sampleRefractionMap(screenCoords - screenCoordsOffset).rgb;
vec3 rawRefraction = refraction;
// brighten up the refraction underwater

View file

@ -1,6 +1,6 @@
#version 120
uniform mat4 projectionMatrix;
#include "openmw_vertex.h.glsl"
varying vec4 position;
varying float linearDepth;
@ -10,11 +10,11 @@ varying float linearDepth;
void main(void)
{
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
gl_Position = mw_modelToClip(gl_Vertex);
position = gl_Vertex;
vec4 viewPos = gl_ModelViewMatrix * gl_Vertex;
vec4 viewPos = mw_modelToView(gl_Vertex);
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
setupShadowCoords(viewPos, normalize((gl_NormalMatrix * gl_Normal).xyz));