diff --git a/components/shader/shadermanager.cpp b/components/shader/shadermanager.cpp index 7cb49c6cb..02488dd42 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -99,10 +99,39 @@ namespace Shader return true; } - osg::ref_ptr ShaderManager::getShader(const std::string &shaderTemplate, const ShaderManager::DefineMap &defines, osg::Shader::Type shaderType) + osg::ref_ptr ShaderManager::getShader(const std::string &shaderTemplate, const ShaderManager::DefineMap &defines, osg::Shader::Type shaderType, bool disableShadows) { OpenThreads::ScopedLock 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 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; } diff --git a/components/shader/shadermanager.hpp b/components/shader/shadermanager.hpp index bd820a725..17c46f58c 100644 --- a/components/shader/shadermanager.hpp +++ b/components/shader/shadermanager.hpp @@ -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 getShader(const std::string& shaderTemplate, const DefineMap& defines, osg::Shader::Type shaderType); + osg::ref_ptr getShader(const std::string& shaderTemplate, const DefineMap& defines, osg::Shader::Type shaderType, bool disableShadows = false); osg::ref_ptr getProgram(osg::ref_ptr vertexShader, osg::ref_ptr fragmentShader); diff --git a/files/shaders/objects_fragment.glsl b/files/shaders/objects_fragment.glsl index f6355aaa6..7d9372c71 100644 --- a/files/shaders/objects_fragment.glsl +++ b/files/shaders/objects_fragment.glsl @@ -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); diff --git a/files/shaders/objects_vertex.glsl b/files/shaders/objects_vertex.glsl index b90a8722b..fb612afc8 100644 --- a/files/shaders/objects_vertex.glsl +++ b/files/shaders/objects_vertex.glsl @@ -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 } diff --git a/files/shaders/terrain_fragment.glsl b/files/shaders/terrain_fragment.glsl index e79adaafb..e512d7475 100644 --- a/files/shaders/terrain_fragment.glsl +++ b/files/shaders/terrain_fragment.glsl @@ -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); diff --git a/files/shaders/terrain_vertex.glsl b/files/shaders/terrain_vertex.glsl index 015039252..692e76cce 100644 --- a/files/shaders/terrain_vertex.glsl +++ b/files/shaders/terrain_vertex.glsl @@ -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 } diff --git a/files/shaders/water_fragment.glsl b/files/shaders/water_fragment.glsl index 3529b7347..586a247a4 100644 --- a/files/shaders/water_fragment.glsl +++ b/files/shaders/water_fragment.glsl @@ -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); diff --git a/files/shaders/water_vertex.glsl b/files/shaders/water_vertex.glsl index 0c280fb7e..6381155d0 100644 --- a/files/shaders/water_vertex.glsl +++ b/files/shaders/water_vertex.glsl @@ -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 }