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:
parent
56fa33af66
commit
715f29165b
8 changed files with 105 additions and 50 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue