mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// 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
|
||||
TemplateMap::iterator templateIt = mShaderTemplates.find(shaderTemplate);
|
||||
if (templateIt == mShaderTemplates.end())
|
||||
|
@ -126,11 +155,11 @@ namespace Shader
|
|||
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())
|
||||
{
|
||||
std::string shaderSource = templateIt->second;
|
||||
if (!parseDefines(shaderSource, defines))
|
||||
if (!parseDefines(shaderSource, definesWithShadows))
|
||||
return NULL;
|
||||
|
||||
osg::ref_ptr<osg::Shader> shader (new osg::Shader(shaderType));
|
||||
|
@ -139,7 +168,7 @@ namespace Shader
|
|||
static unsigned int counter = 0;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -26,9 +26,10 @@ namespace Shader
|
|||
/// @param shaderTemplate The filename of 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 disableShadows Whether to disable shadows in the shader regardless of the overall setting. False by default.
|
||||
/// @note May return NULL on failure.
|
||||
/// @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);
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#version 120
|
||||
|
||||
#define SHADOWS @shadows_enabled
|
||||
|
||||
#if @diffuseMap
|
||||
uniform sampler2D diffuseMap;
|
||||
varying vec2 diffuseMapUV;
|
||||
|
@ -55,10 +57,10 @@ varying vec4 passColor;
|
|||
varying vec3 passViewPos;
|
||||
varying vec3 passNormal;
|
||||
|
||||
uniform sampler2DShadow shadowTexture0;
|
||||
uniform sampler2DShadow shadowTexture1;
|
||||
varying vec4 shadowSpaceCoords0;
|
||||
varying vec4 shadowSpaceCoords1;
|
||||
#if SHADOWS
|
||||
@shadow_texture_sampler_declarations
|
||||
@shadow_space_coordinate_declarations
|
||||
#endif // SHADOWS
|
||||
|
||||
#include "lighting.glsl"
|
||||
#include "parallax.glsl"
|
||||
|
@ -118,8 +120,10 @@ void main()
|
|||
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, decalTex.xyz, decalTex.a);
|
||||
#endif
|
||||
|
||||
float shadowing = shadow2DProj(shadowTexture0, shadowSpaceCoords0).r;
|
||||
shadowing *= shadow2DProj(shadowTexture1, shadowSpaceCoords1).r;
|
||||
float shadowing = 1.0;
|
||||
#if SHADOWS
|
||||
@shadow_texture_lookup_calculations
|
||||
#endif // SHADOWS
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
gl_FragData[0] *= lighting + vec4(shadowDiffuseLighting * shadowing, 0);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#version 120
|
||||
|
||||
#define SHADOWS @shadows_enabled
|
||||
|
||||
#if @diffuseMap
|
||||
varying vec2 diffuseMapUV;
|
||||
#endif
|
||||
|
@ -46,10 +48,10 @@ varying vec4 passColor;
|
|||
varying vec3 passViewPos;
|
||||
varying vec3 passNormal;
|
||||
|
||||
uniform int shadowTextureUnit0;
|
||||
uniform int shadowTextureUnit1;
|
||||
varying vec4 shadowSpaceCoords0;
|
||||
varying vec4 shadowSpaceCoords1;
|
||||
#if SHADOWS
|
||||
@shadow_texture_unit_declarations
|
||||
@shadow_space_coordinate_declarations
|
||||
#endif // SHADOWS
|
||||
|
||||
#include "lighting.glsl"
|
||||
|
||||
|
@ -106,9 +108,9 @@ void main(void)
|
|||
passViewPos = viewPos.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.
|
||||
mat4 eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit0], gl_EyePlaneT[shadowTextureUnit0], gl_EyePlaneR[shadowTextureUnit0], gl_EyePlaneQ[shadowTextureUnit0]);
|
||||
shadowSpaceCoords0 = viewPos * eyePlaneMat;
|
||||
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit1], gl_EyePlaneT[shadowTextureUnit1], gl_EyePlaneR[shadowTextureUnit1], gl_EyePlaneQ[shadowTextureUnit1]);
|
||||
shadowSpaceCoords1 = viewPos * eyePlaneMat;
|
||||
mat4 eyePlaneMat;
|
||||
@shadow_space_coordinate_calculations
|
||||
#endif // SHADOWS
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#version 120
|
||||
|
||||
#define SHADOWS @shadows_enabled
|
||||
|
||||
varying vec2 uv;
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
@ -25,10 +27,10 @@ varying vec4 passColor;
|
|||
varying vec3 passViewPos;
|
||||
varying vec3 passNormal;
|
||||
|
||||
uniform sampler2DShadow shadowTexture0;
|
||||
uniform sampler2DShadow shadowTexture1;
|
||||
varying vec4 shadowSpaceCoords0;
|
||||
varying vec4 shadowSpaceCoords1;
|
||||
#if SHADOWS
|
||||
@shadow_texture_sampler_declarations
|
||||
@shadow_space_coordinate_declarations
|
||||
#endif // SHADOWS
|
||||
|
||||
#include "lighting.glsl"
|
||||
#include "parallax.glsl"
|
||||
|
@ -70,8 +72,10 @@ void main()
|
|||
gl_FragData[0].a *= texture2D(blendMap, blendMapUV).a;
|
||||
#endif
|
||||
|
||||
float shadowing = shadow2DProj(shadowTexture0, shadowSpaceCoords0).r;
|
||||
shadowing *= shadow2DProj(shadowTexture1, shadowSpaceCoords1).r;
|
||||
float shadowing = 1.0;
|
||||
#if SHADOWS
|
||||
@shadow_texture_lookup_calculations
|
||||
#endif // SHADOWS
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
gl_FragData[0] *= lighting + vec4(shadowDiffuseLighting * shadowing, 0);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#version 120
|
||||
|
||||
#define SHADOWS @shadows_enabled
|
||||
|
||||
varying vec2 uv;
|
||||
varying float depth;
|
||||
|
||||
|
@ -14,10 +16,10 @@ varying vec4 passColor;
|
|||
varying vec3 passViewPos;
|
||||
varying vec3 passNormal;
|
||||
|
||||
uniform int shadowTextureUnit0;
|
||||
uniform int shadowTextureUnit1;
|
||||
varying vec4 shadowSpaceCoords0;
|
||||
varying vec4 shadowSpaceCoords1;
|
||||
#if SHADOWS
|
||||
@shadow_texture_unit_declarations
|
||||
@shadow_space_coordinate_declarations
|
||||
#endif // SHADOWS
|
||||
|
||||
#include "lighting.glsl"
|
||||
|
||||
|
@ -40,9 +42,9 @@ void main(void)
|
|||
|
||||
uv = gl_MultiTexCoord0.xy;
|
||||
|
||||
// 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]);
|
||||
shadowSpaceCoords0 = viewPos * eyePlaneMat;
|
||||
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit1], gl_EyePlaneT[shadowTextureUnit1], gl_EyePlaneR[shadowTextureUnit1], gl_EyePlaneQ[shadowTextureUnit1]);
|
||||
shadowSpaceCoords1 = viewPos * eyePlaneMat;
|
||||
#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.
|
||||
mat4 eyePlaneMat;
|
||||
@shadow_space_coordinate_calculations
|
||||
#endif // SHADOWS
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#version 120
|
||||
|
||||
#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 )
|
||||
|
||||
|
@ -142,10 +143,11 @@ uniform vec3 nodePosition;
|
|||
|
||||
uniform float rainIntensity;
|
||||
|
||||
uniform sampler2DShadow shadowTexture0;
|
||||
uniform sampler2DShadow shadowTexture1;
|
||||
varying vec4 shadowSpaceCoords0;
|
||||
varying vec4 shadowSpaceCoords1;
|
||||
#if SHADOWS
|
||||
@shadow_texture_sampler_declarations
|
||||
|
||||
@shadow_space_coordinate_declarations
|
||||
#endif // SHADOWS
|
||||
|
||||
float frustumDepth;
|
||||
|
||||
|
@ -163,8 +165,15 @@ void main(void)
|
|||
vec2 UV = worldPos.xy / (8192.0*5.0) * 3.0;
|
||||
UV.y *= -1.0;
|
||||
|
||||
float shadow = shadow2DProj(shadowTexture0, shadowSpaceCoords0).r;
|
||||
shadow *= shadow2DProj(shadowTexture1, shadowSpaceCoords1).r;
|
||||
#if SHADOWS
|
||||
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;
|
||||
screenCoords.y = (1.0-screenCoords.y);
|
||||
|
|
|
@ -4,10 +4,13 @@ varying vec3 screenCoordsPassthrough;
|
|||
varying vec4 position;
|
||||
varying float depthPassthrough;
|
||||
|
||||
uniform int shadowTextureUnit0;
|
||||
uniform int shadowTextureUnit1;
|
||||
varying vec4 shadowSpaceCoords0;
|
||||
varying vec4 shadowSpaceCoords1;
|
||||
#define SHADOWS @shadows_enabled
|
||||
|
||||
#if SHADOWS
|
||||
@shadow_texture_unit_declarations
|
||||
|
||||
@shadow_space_coordinate_declarations
|
||||
#endif // SHADOWS
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
@ -25,10 +28,11 @@ void main(void)
|
|||
|
||||
depthPassthrough = gl_Position.z;
|
||||
|
||||
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.
|
||||
mat4 eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit0], gl_EyePlaneT[shadowTextureUnit0], gl_EyePlaneR[shadowTextureUnit0], gl_EyePlaneQ[shadowTextureUnit0]);
|
||||
shadowSpaceCoords0 = viewPos * eyePlaneMat;
|
||||
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit1], gl_EyePlaneT[shadowTextureUnit1], gl_EyePlaneR[shadowTextureUnit1], gl_EyePlaneQ[shadowTextureUnit1]);
|
||||
shadowSpaceCoords1 = viewPos * eyePlaneMat;
|
||||
#if SHADOWS
|
||||
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.
|
||||
mat4 eyePlaneMat;
|
||||
|
||||
@shadow_space_coordinate_calculations
|
||||
#endif // SHADOWS
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue