1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-04 06:19:40 +00:00

Dynamically adjust shaders to have the required number of shadow maps.

This commit is contained in:
AnyOldName3 2017-11-07 20:22:45 +00:00
parent 56fa33af66
commit 715f29165b
8 changed files with 105 additions and 50 deletions

View file

@ -99,10 +99,39 @@ namespace Shader
return true; return true;
} }
osg::ref_ptr<osg::Shader> ShaderManager::getShader(const std::string &shaderTemplate, const ShaderManager::DefineMap &defines, osg::Shader::Type shaderType) osg::ref_ptr<osg::Shader> ShaderManager::getShader(const std::string &shaderTemplate, const ShaderManager::DefineMap &defines, osg::Shader::Type shaderType, bool disableShadows)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
// set up shadows in the shader
// get these values from settings manager
bool shadows = true & !disableShadows;
int numShadowMaps = 2;
DefineMap definesWithShadows;
if (shadows)
{
definesWithShadows.insert(std::make_pair(std::string("shadows_enabled"), std::string("1")));
/*definesWithShadows.insert(std::string("shadow_texture_unit_declarations"), std::string(""));
definesWithShadows.insert(std::string("shadow_space_coordinate_declarations"), std::string(""));
definesWithShadows.insert(std::string("shadow_space_coordinate_calculations"), std::string(""));
definesWithShadows.insert(std::string("shadow_texture_sampler_declarations"), std::string(""));
definesWithShadows.insert(std::string("shadow_texture_lookup_calculations"), std::string(""));*/
for (int i = 0; i < numShadowMaps; ++i)
{
definesWithShadows["shadow_texture_unit_declarations"] += "uniform int shadowTextureUnit" + std::to_string(i) + ";\n";
definesWithShadows["shadow_space_coordinate_declarations"] += "varying vec4 shadowSpaceCoords" + std::to_string(i) + ";\n";
definesWithShadows["shadow_space_coordinate_calculations"] += "eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit" + std::to_string(i) + "], gl_EyePlaneT[shadowTextureUnit" + std::to_string(i) + "], gl_EyePlaneR[shadowTextureUnit" + std::to_string(i) + "], gl_EyePlaneQ[shadowTextureUnit" + std::to_string(i) + "]);\n"
+ "shadowSpaceCoords" + std::to_string(i) + " = viewPos * eyePlaneMat;\n";
definesWithShadows["shadow_texture_sampler_declarations"] += "uniform sampler2DShadow shadowTexture" + std::to_string(i) + ";\n";
definesWithShadows["shadow_texture_lookup_calculations"] += "shadowing *= shadow2DProj(shadowTexture" + std::to_string(i) + ", shadowSpaceCoords" + std::to_string(i) + ").r;\n";
}
}
definesWithShadows.insert(defines.begin(), defines.end());
// read the template if we haven't already // read the template if we haven't already
TemplateMap::iterator templateIt = mShaderTemplates.find(shaderTemplate); TemplateMap::iterator templateIt = mShaderTemplates.find(shaderTemplate);
if (templateIt == mShaderTemplates.end()) if (templateIt == mShaderTemplates.end())
@ -126,11 +155,11 @@ namespace Shader
templateIt = mShaderTemplates.insert(std::make_pair(shaderTemplate, source)).first; templateIt = mShaderTemplates.insert(std::make_pair(shaderTemplate, source)).first;
} }
ShaderMap::iterator shaderIt = mShaders.find(std::make_pair(shaderTemplate, defines)); ShaderMap::iterator shaderIt = mShaders.find(std::make_pair(shaderTemplate, definesWithShadows));
if (shaderIt == mShaders.end()) if (shaderIt == mShaders.end())
{ {
std::string shaderSource = templateIt->second; std::string shaderSource = templateIt->second;
if (!parseDefines(shaderSource, defines)) if (!parseDefines(shaderSource, definesWithShadows))
return NULL; return NULL;
osg::ref_ptr<osg::Shader> shader (new osg::Shader(shaderType)); osg::ref_ptr<osg::Shader> shader (new osg::Shader(shaderType));
@ -139,7 +168,7 @@ namespace Shader
static unsigned int counter = 0; static unsigned int counter = 0;
shader->setName(std::to_string(counter++)); shader->setName(std::to_string(counter++));
shaderIt = mShaders.insert(std::make_pair(std::make_pair(shaderTemplate, defines), shader)).first; shaderIt = mShaders.insert(std::make_pair(std::make_pair(shaderTemplate, definesWithShadows), shader)).first;
} }
return shaderIt->second; return shaderIt->second;
} }

View file

@ -26,9 +26,10 @@ namespace Shader
/// @param shaderTemplate The filename of the shader template. /// @param shaderTemplate The filename of the shader template.
/// @param defines Define values that can be retrieved by the shader template. /// @param defines Define values that can be retrieved by the shader template.
/// @param shaderType The type of shader (usually vertex or fragment shader). /// @param shaderType The type of shader (usually vertex or fragment shader).
/// @param disableShadows Whether to disable shadows in the shader regardless of the overall setting. False by default.
/// @note May return NULL on failure. /// @note May return NULL on failure.
/// @note Thread safe. /// @note Thread safe.
osg::ref_ptr<osg::Shader> getShader(const std::string& shaderTemplate, const DefineMap& defines, osg::Shader::Type shaderType); osg::ref_ptr<osg::Shader> getShader(const std::string& shaderTemplate, const DefineMap& defines, osg::Shader::Type shaderType, bool disableShadows = false);
osg::ref_ptr<osg::Program> getProgram(osg::ref_ptr<osg::Shader> vertexShader, osg::ref_ptr<osg::Shader> fragmentShader); osg::ref_ptr<osg::Program> getProgram(osg::ref_ptr<osg::Shader> vertexShader, osg::ref_ptr<osg::Shader> fragmentShader);

View file

@ -1,5 +1,7 @@
#version 120 #version 120
#define SHADOWS @shadows_enabled
#if @diffuseMap #if @diffuseMap
uniform sampler2D diffuseMap; uniform sampler2D diffuseMap;
varying vec2 diffuseMapUV; varying vec2 diffuseMapUV;
@ -55,10 +57,10 @@ varying vec4 passColor;
varying vec3 passViewPos; varying vec3 passViewPos;
varying vec3 passNormal; varying vec3 passNormal;
uniform sampler2DShadow shadowTexture0; #if SHADOWS
uniform sampler2DShadow shadowTexture1; @shadow_texture_sampler_declarations
varying vec4 shadowSpaceCoords0; @shadow_space_coordinate_declarations
varying vec4 shadowSpaceCoords1; #endif // SHADOWS
#include "lighting.glsl" #include "lighting.glsl"
#include "parallax.glsl" #include "parallax.glsl"
@ -118,8 +120,10 @@ void main()
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, decalTex.xyz, decalTex.a); gl_FragData[0].xyz = mix(gl_FragData[0].xyz, decalTex.xyz, decalTex.a);
#endif #endif
float shadowing = shadow2DProj(shadowTexture0, shadowSpaceCoords0).r; float shadowing = 1.0;
shadowing *= shadow2DProj(shadowTexture1, shadowSpaceCoords1).r; #if SHADOWS
@shadow_texture_lookup_calculations
#endif // SHADOWS
#if !PER_PIXEL_LIGHTING #if !PER_PIXEL_LIGHTING
gl_FragData[0] *= lighting + vec4(shadowDiffuseLighting * shadowing, 0); gl_FragData[0] *= lighting + vec4(shadowDiffuseLighting * shadowing, 0);

View file

@ -1,5 +1,7 @@
#version 120 #version 120
#define SHADOWS @shadows_enabled
#if @diffuseMap #if @diffuseMap
varying vec2 diffuseMapUV; varying vec2 diffuseMapUV;
#endif #endif
@ -46,10 +48,10 @@ varying vec4 passColor;
varying vec3 passViewPos; varying vec3 passViewPos;
varying vec3 passNormal; varying vec3 passNormal;
uniform int shadowTextureUnit0; #if SHADOWS
uniform int shadowTextureUnit1; @shadow_texture_unit_declarations
varying vec4 shadowSpaceCoords0; @shadow_space_coordinate_declarations
varying vec4 shadowSpaceCoords1; #endif // SHADOWS
#include "lighting.glsl" #include "lighting.glsl"
@ -106,9 +108,9 @@ void main(void)
passViewPos = viewPos.xyz; passViewPos = viewPos.xyz;
passNormal = gl_Normal.xyz; passNormal = gl_Normal.xyz;
#if SHADOWS
// This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner. // This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner.
mat4 eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit0], gl_EyePlaneT[shadowTextureUnit0], gl_EyePlaneR[shadowTextureUnit0], gl_EyePlaneQ[shadowTextureUnit0]); mat4 eyePlaneMat;
shadowSpaceCoords0 = viewPos * eyePlaneMat; @shadow_space_coordinate_calculations
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit1], gl_EyePlaneT[shadowTextureUnit1], gl_EyePlaneR[shadowTextureUnit1], gl_EyePlaneQ[shadowTextureUnit1]); #endif // SHADOWS
shadowSpaceCoords1 = viewPos * eyePlaneMat;
} }

View file

@ -1,5 +1,7 @@
#version 120 #version 120
#define SHADOWS @shadows_enabled
varying vec2 uv; varying vec2 uv;
uniform sampler2D diffuseMap; uniform sampler2D diffuseMap;
@ -25,10 +27,10 @@ varying vec4 passColor;
varying vec3 passViewPos; varying vec3 passViewPos;
varying vec3 passNormal; varying vec3 passNormal;
uniform sampler2DShadow shadowTexture0; #if SHADOWS
uniform sampler2DShadow shadowTexture1; @shadow_texture_sampler_declarations
varying vec4 shadowSpaceCoords0; @shadow_space_coordinate_declarations
varying vec4 shadowSpaceCoords1; #endif // SHADOWS
#include "lighting.glsl" #include "lighting.glsl"
#include "parallax.glsl" #include "parallax.glsl"
@ -70,8 +72,10 @@ void main()
gl_FragData[0].a *= texture2D(blendMap, blendMapUV).a; gl_FragData[0].a *= texture2D(blendMap, blendMapUV).a;
#endif #endif
float shadowing = shadow2DProj(shadowTexture0, shadowSpaceCoords0).r; float shadowing = 1.0;
shadowing *= shadow2DProj(shadowTexture1, shadowSpaceCoords1).r; #if SHADOWS
@shadow_texture_lookup_calculations
#endif // SHADOWS
#if !PER_PIXEL_LIGHTING #if !PER_PIXEL_LIGHTING
gl_FragData[0] *= lighting + vec4(shadowDiffuseLighting * shadowing, 0); gl_FragData[0] *= lighting + vec4(shadowDiffuseLighting * shadowing, 0);

View file

@ -1,5 +1,7 @@
#version 120 #version 120
#define SHADOWS @shadows_enabled
varying vec2 uv; varying vec2 uv;
varying float depth; varying float depth;
@ -14,10 +16,10 @@ varying vec4 passColor;
varying vec3 passViewPos; varying vec3 passViewPos;
varying vec3 passNormal; varying vec3 passNormal;
uniform int shadowTextureUnit0; #if SHADOWS
uniform int shadowTextureUnit1; @shadow_texture_unit_declarations
varying vec4 shadowSpaceCoords0; @shadow_space_coordinate_declarations
varying vec4 shadowSpaceCoords1; #endif // SHADOWS
#include "lighting.glsl" #include "lighting.glsl"
@ -40,9 +42,9 @@ void main(void)
uv = gl_MultiTexCoord0.xy; uv = gl_MultiTexCoord0.xy;
#if SHADOWS
// This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner. // This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner.
mat4 eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit0], gl_EyePlaneT[shadowTextureUnit0], gl_EyePlaneR[shadowTextureUnit0], gl_EyePlaneQ[shadowTextureUnit0]); mat4 eyePlaneMat;
shadowSpaceCoords0 = viewPos * eyePlaneMat; @shadow_space_coordinate_calculations
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit1], gl_EyePlaneT[shadowTextureUnit1], gl_EyePlaneR[shadowTextureUnit1], gl_EyePlaneQ[shadowTextureUnit1]); #endif // SHADOWS
shadowSpaceCoords1 = viewPos * eyePlaneMat;
} }

View file

@ -1,6 +1,7 @@
#version 120 #version 120
#define REFRACTION @refraction_enabled #define REFRACTION @refraction_enabled
#define SHADOWS @shadows_enabled
// Inspired by Blender GLSL Water by martinsh ( http://devlog-martinsh.blogspot.de/2012/07/waterundewater-shader-wip.html ) // Inspired by Blender GLSL Water by martinsh ( http://devlog-martinsh.blogspot.de/2012/07/waterundewater-shader-wip.html )
@ -142,10 +143,11 @@ uniform vec3 nodePosition;
uniform float rainIntensity; uniform float rainIntensity;
uniform sampler2DShadow shadowTexture0; #if SHADOWS
uniform sampler2DShadow shadowTexture1; @shadow_texture_sampler_declarations
varying vec4 shadowSpaceCoords0;
varying vec4 shadowSpaceCoords1; @shadow_space_coordinate_declarations
#endif // SHADOWS
float frustumDepth; float frustumDepth;
@ -163,8 +165,15 @@ void main(void)
vec2 UV = worldPos.xy / (8192.0*5.0) * 3.0; vec2 UV = worldPos.xy / (8192.0*5.0) * 3.0;
UV.y *= -1.0; UV.y *= -1.0;
float shadow = shadow2DProj(shadowTexture0, shadowSpaceCoords0).r; #if SHADOWS
shadow *= shadow2DProj(shadowTexture1, shadowSpaceCoords1).r; float shadowing = 1.0;
@shadow_texture_lookup_calculations
float shadow = shadowing;
#else // NOT SHADOWS
float shadow = 1.0;
#endif // SHADOWS
vec2 screenCoords = screenCoordsPassthrough.xy / screenCoordsPassthrough.z; vec2 screenCoords = screenCoordsPassthrough.xy / screenCoordsPassthrough.z;
screenCoords.y = (1.0-screenCoords.y); screenCoords.y = (1.0-screenCoords.y);

View file

@ -4,10 +4,13 @@ varying vec3 screenCoordsPassthrough;
varying vec4 position; varying vec4 position;
varying float depthPassthrough; varying float depthPassthrough;
uniform int shadowTextureUnit0; #define SHADOWS @shadows_enabled
uniform int shadowTextureUnit1;
varying vec4 shadowSpaceCoords0; #if SHADOWS
varying vec4 shadowSpaceCoords1; @shadow_texture_unit_declarations
@shadow_space_coordinate_declarations
#endif // SHADOWS
void main(void) void main(void)
{ {
@ -25,10 +28,11 @@ void main(void)
depthPassthrough = gl_Position.z; depthPassthrough = gl_Position.z;
#if SHADOWS
vec4 viewPos = gl_ModelViewMatrix * gl_Vertex; vec4 viewPos = gl_ModelViewMatrix * gl_Vertex;
// This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner. // This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner.
mat4 eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit0], gl_EyePlaneT[shadowTextureUnit0], gl_EyePlaneR[shadowTextureUnit0], gl_EyePlaneQ[shadowTextureUnit0]); mat4 eyePlaneMat;
shadowSpaceCoords0 = viewPos * eyePlaneMat;
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit1], gl_EyePlaneT[shadowTextureUnit1], gl_EyePlaneR[shadowTextureUnit1], gl_EyePlaneQ[shadowTextureUnit1]); @shadow_space_coordinate_calculations
shadowSpaceCoords1 = viewPos * eyePlaneMat; #endif // SHADOWS
} }