diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 123eadfdec..18604e78ca 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -260,7 +260,6 @@ namespace MWRender // turn off sky blending stateset->addUniform(new osg::Uniform("far", 10000000.0f)); stateset->addUniform(new osg::Uniform("skyBlendingStart", 8000000.0f)); - stateset->addUniform(new osg::Uniform("sky", 0)); stateset->addUniform(new osg::Uniform("screenRes", osg::Vec2f{ 1, 1 })); stateset->addUniform(new osg::Uniform("emissiveMult", 1.f)); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 968903f6a3..e582bb76ee 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -736,7 +736,6 @@ namespace MWRender // turn of sky blending stateset->addUniform(new osg::Uniform("far", 10000000.0f)); stateset->addUniform(new osg::Uniform("skyBlendingStart", 8000000.0f)); - stateset->addUniform(new osg::Uniform("sky", 0)); stateset->addUniform(new osg::Uniform("screenRes", osg::Vec2f{ 1, 1 })); osg::ref_ptr lightmodel = new osg::LightModel; diff --git a/components/fx/pass.cpp b/components/fx/pass.cpp index cf50d20fe2..c55bee76e3 100644 --- a/components/fx/pass.cpp +++ b/components/fx/pass.cpp @@ -81,6 +81,7 @@ namespace fx #define omw_Position @position #define omw_Texture1D @texture1D #define omw_Texture2D @texture2D +#define omw_Texture2DArray @texture2DArray #define omw_Texture3D @texture3D #define omw_Vertex @vertex #define omw_FragColor @fragColor @@ -154,7 +155,7 @@ mat4 omw_InvProjectionMatrix() float omw_GetDepth(vec2 uv) { #if OMW_MULTIVIEW - float depth = omw_Texture2D(omw_SamplerDepth, vec3(uv, gl_ViewID_OVR)).r; + float depth = omw_Texture2DArray(omw_SamplerDepth, vec3(uv, gl_ViewID_OVR)).r; #else float depth = omw_Texture2D(omw_SamplerDepth, uv).r; #endif @@ -165,10 +166,19 @@ mat4 omw_InvProjectionMatrix() #endif } + vec4 omw_GetDistortion(vec2 uv) + { +#if OMW_MULTIVIEW + return omw_Texture2DArray(omw_SamplerDistortion, vec3(uv, gl_ViewID_OVR)); +#else + return omw_Texture2D(omw_SamplerDistortion, uv); +#endif + } + vec4 omw_GetLastShader(vec2 uv) { #if OMW_MULTIVIEW - return omw_Texture2D(omw_SamplerLastShader, vec3(uv, gl_ViewID_OVR)); + return omw_Texture2DArray(omw_SamplerLastShader, vec3(uv, gl_ViewID_OVR)); #else return omw_Texture2D(omw_SamplerLastShader, uv); #endif @@ -177,7 +187,7 @@ mat4 omw_InvProjectionMatrix() vec4 omw_GetLastPass(vec2 uv) { #if OMW_MULTIVIEW - return omw_Texture2D(omw_SamplerLastPass, vec3(uv, gl_ViewID_OVR)); + return omw_Texture2DArray(omw_SamplerLastPass, vec3(uv, gl_ViewID_OVR)); #else return omw_Texture2D(omw_SamplerLastPass, uv); #endif @@ -186,7 +196,7 @@ mat4 omw_InvProjectionMatrix() vec3 omw_GetNormals(vec2 uv) { #if OMW_MULTIVIEW - return omw_Texture2D(omw_SamplerNormals, vec3(uv, gl_ViewID_OVR)).rgb * 2.0 - 1.0; + return omw_Texture2DArray(omw_SamplerNormals, vec3(uv, gl_ViewID_OVR)).rgb * 2.0 - 1.0; #else return omw_Texture2D(omw_SamplerNormals, uv).rgb * 2.0 - 1.0; #endif @@ -275,6 +285,9 @@ float omw_EstimateFogCoverageFromUV(vec2 uv) { "@hdr", technique.getHDR() ? "1" : "0" }, { "@in", mLegacyGLSL ? "varying" : "in" }, { "@out", mLegacyGLSL ? "varying" : "out" }, { "@position", "gl_Position" }, { "@texture1D", mLegacyGLSL ? "texture1D" : "texture" }, + // Note, @texture2DArray must be defined before @texture2D since @texture2D is a perfect prefix of + // texture2DArray + { "@texture2DArray", mLegacyGLSL ? "texture2DArray" : "texture" }, { "@texture2D", mLegacyGLSL ? "texture2D" : "texture" }, { "@texture3D", mLegacyGLSL ? "texture3D" : "texture" }, { "@vertex", mLegacyGLSL ? "gl_Vertex" : "_omw_Vertex" }, diff --git a/components/fx/technique.cpp b/components/fx/technique.cpp index f56e0d498e..5963e274ec 100644 --- a/components/fx/technique.cpp +++ b/components/fx/technique.cpp @@ -85,7 +85,7 @@ namespace fx mDescription = {}; mVersion = {}; mGLSLExtensions.clear(); - mGLSLVersion = mUBO ? 330 : 120; + mGLSLVersion = (mUBO || Stereo::getMultiview()) ? 330 : 120; mGLSLProfile.clear(); mDynamic = false; } diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index 9fd435f40d..9fa01385d5 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -986,9 +986,12 @@ void SceneUtil::MWShadowTechnique::copyShadowMap(osgUtil::CullVisitor& cv, ViewD lhs_sd->_camera = rhs_sd->_camera; lhs_sd->_textureUnit = rhs_sd->_textureUnit; lhs_sd->_texture = rhs_sd->_texture; + lhs_sd->_sm_i = rhs_sd->_sm_i; sdl.push_back(lhs_sd); } + copyShadowStateSettings(cv, lhs); + if (lhs->_numValidShadows > 0) { prepareStateSetForRenderingShadow(*lhs, cv.getTraversalNumber()); @@ -1000,6 +1003,14 @@ void SceneUtil::MWShadowTechnique::setCustomFrustumCallback(CustomFrustumCallbac _customFrustumCallback = cfc; } +void SceneUtil::MWShadowTechnique::copyShadowStateSettings(osgUtil::CullVisitor& cv, ViewDependentData* vdd) +{ + for (const auto& sd : vdd->getShadowDataList()) + { + assignValidRegionSettings(cv, sd->_camera, sd->_sm_i, vdd->_uniforms[cv.getTraversalNumber()%2]); + assignShadowStateSettings(cv, sd->_camera, sd->_sm_i, vdd->_uniforms[cv.getTraversalNumber()%2]); + } +} void MWShadowTechnique::update(osg::NodeVisitor& nv) { @@ -1053,6 +1064,8 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) _shadowedScene->osg::Group::traverse(cv); return; } + + Uniforms& vddUniforms = vdd->_uniforms[cv.getTraversalNumber() % 2]; ShadowSettings* settings = getShadowedScene()->getShadowSettings(); @@ -1500,29 +1513,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) if (!orthographicViewFrustum && settings->getShadowMapProjectionHint()==ShadowSettings::PERSPECTIVE_SHADOW_MAP) { - { - osg::Matrix validRegionMatrix = cv.getCurrentCamera()->getInverseViewMatrix() * camera->getViewMatrix() * camera->getProjectionMatrix(); - - std::string validRegionUniformName = "validRegionMatrix" + std::to_string(sm_i); - osg::ref_ptr validRegionUniform; - - for (const auto & uniform : _uniforms[cv.getTraversalNumber() % 2]) - { - if (uniform->getName() == validRegionUniformName) - { - validRegionUniform = uniform; - break; - } - } - - if (!validRegionUniform) - { - validRegionUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, validRegionUniformName); - _uniforms[cv.getTraversalNumber() % 2].push_back(validRegionUniform); - } - - validRegionUniform->set(validRegionMatrix); - } + assignValidRegionSettings(cv, camera, sm_i, vddUniforms); if (settings->getMultipleShadowMapHint() == ShadowSettings::CASCADED) adjustPerspectiveShadowMapCameraSettings(vdsmCallback->getRenderStage(), frustum, pl, camera.get(), cascaseNear, cascadeFar); @@ -1537,31 +1528,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) // 4.4 compute main scene graph TexGen + uniform settings + setup state // { - osg::Matrix shadowSpaceMatrix = cv.getCurrentCamera()->getInverseViewMatrix() * - camera->getViewMatrix() * - camera->getProjectionMatrix() * - osg::Matrix::translate(1.0,1.0,1.0) * - osg::Matrix::scale(0.5,0.5,0.5); - - std::string shadowSpaceUniformName = "shadowSpaceMatrix" + std::to_string(sm_i); - osg::ref_ptr shadowSpaceUniform; - - for (const auto & uniform : _uniforms[cv.getTraversalNumber() % 2]) - { - if (uniform->getName() == shadowSpaceUniformName) - { - shadowSpaceUniform = uniform; - break; - } - } - - if (!shadowSpaceUniform) - { - shadowSpaceUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, shadowSpaceUniformName); - _uniforms[cv.getTraversalNumber() % 2].push_back(shadowSpaceUniform); - } - - shadowSpaceUniform->set(shadowSpaceMatrix); + assignShadowStateSettings(cv, camera, sm_i, vddUniforms); } // mark the light as one that has active shadows and requires shaders @@ -1569,6 +1536,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) // pass on shadow data to ShadowDataList sd->_textureUnit = textureUnit; + sd->_sm_i = sm_i; sdl.push_back(sd); @@ -3080,6 +3048,61 @@ bool MWShadowTechnique::adjustPerspectiveShadowMapCameraSettings(osgUtil::Render return true; } +void MWShadowTechnique::assignShadowStateSettings(osgUtil::CullVisitor& cv, osg::Camera* camera, unsigned int sm_i, Uniforms& uniforms) +{ + osg::Matrix inverseViewMatrix = osg::Matrix::inverse(*cv.getModelViewMatrix()); + osg::Matrix shadowSpaceMatrix = inverseViewMatrix * + camera->getViewMatrix() * + camera->getProjectionMatrix() * + osg::Matrix::translate(1.0,1.0,1.0) * + osg::Matrix::scale(0.5,0.5,0.5); + + std::string shadowSpaceUniformName = "shadowSpaceMatrix" + std::to_string(sm_i); + osg::ref_ptr shadowSpaceUniform; + + for (const auto & uniform : uniforms) + { + if (uniform->getName() == shadowSpaceUniformName) + { + shadowSpaceUniform = uniform; + break; + } + } + + if (!shadowSpaceUniform) + { + shadowSpaceUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, shadowSpaceUniformName); + uniforms.push_back(shadowSpaceUniform); + } + + shadowSpaceUniform->set(shadowSpaceMatrix); +} + +void SceneUtil::MWShadowTechnique::assignValidRegionSettings(osgUtil::CullVisitor & cv, osg::Camera* camera, unsigned int sm_i, Uniforms & uniforms) +{ + osg::Matrix validRegionMatrix = osg::Matrix::inverse(*cv.getModelViewMatrix()) * camera->getViewMatrix() * camera->getProjectionMatrix(); + + std::string validRegionUniformName = "validRegionMatrix" + std::to_string(sm_i); + osg::ref_ptr validRegionUniform; + + for (const auto & uniform : uniforms) + { + if (uniform->getName() == validRegionUniformName) + { + validRegionUniform = uniform; + break; + } + } + + if (!validRegionUniform) + { + validRegionUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, validRegionUniformName); + uniforms.push_back(validRegionUniform); + } + + validRegionUniform->set(validRegionMatrix); +} + void MWShadowTechnique::cullShadowReceivingScene(osgUtil::CullVisitor* cv) const { OSG_INFO<<"cullShadowReceivingScene()"<addUniform(uniform); } + for(const auto& uniform : vdd._uniforms[traversalNumber % 2]) + { + OSG_INFO<<"addUniform("<getName()<<")"<addUniform(uniform); + } + if (_program.valid()) { stateset->setAttribute(_program.get()); diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 8b39818e2e..4b9de9364a 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -157,6 +157,7 @@ namespace SceneUtil { * the resulting shadow map may be invalid. */ virtual void operator()(osgUtil::CullVisitor& cv, osg::BoundingBoxd& customClipSpace, osgUtil::CullVisitor*& sharedFrustumHint) = 0; }; + typedef std::vector< osg::ref_ptr > Uniforms; // forward declare class ViewDependentData; @@ -192,6 +193,7 @@ namespace SceneUtil { ViewDependentData* _viewDependentData; unsigned int _textureUnit; + unsigned int _sm_i; osg::ref_ptr _texture; osg::ref_ptr _camera; }; @@ -228,6 +230,7 @@ namespace SceneUtil { LightDataList _lightDataList; ShadowDataList _shadowDataList; + std::array _uniforms; unsigned int _numValidShadows; }; @@ -240,6 +243,8 @@ namespace SceneUtil { void setCustomFrustumCallback(CustomFrustumCallback* cfc); + void copyShadowStateSettings(osgUtil::CullVisitor& cv, ViewDependentData* vdd); + virtual void createShaders(); virtual bool selectActiveLights(osgUtil::CullVisitor* cv, ViewDependentData* vdd) const; @@ -251,6 +256,10 @@ namespace SceneUtil { virtual bool cropShadowCameraToMainFrustum(Frustum& frustum, osg::Camera* camera, double viewNear, double viewFar, std::vector& planeList); virtual bool adjustPerspectiveShadowMapCameraSettings(osgUtil::RenderStage* renderStage, Frustum& frustum, LightData& positionedLight, osg::Camera* camera, double viewNear, double viewFar); + + virtual void assignShadowStateSettings(osgUtil::CullVisitor& cv, osg::Camera* camera, unsigned int sm_i, Uniforms& uniforms); + + virtual void assignValidRegionSettings(osgUtil::CullVisitor& cv, osg::Camera* camera, unsigned int sm_i, Uniforms& uniforms); virtual void cullShadowReceivingScene(osgUtil::CullVisitor* cv) const; @@ -280,7 +289,6 @@ namespace SceneUtil { osg::ref_ptr _fallbackBaseTexture; osg::ref_ptr _fallbackShadowMapTexture; - typedef std::vector< osg::ref_ptr > Uniforms; std::array _uniforms; osg::ref_ptr _program; diff --git a/files/data/shaders/internal_distortion.omwfx b/files/data/shaders/internal_distortion.omwfx index b641bb6711..b8e62ff229 100644 --- a/files/data/shaders/internal_distortion.omwfx +++ b/files/data/shaders/internal_distortion.omwfx @@ -6,11 +6,11 @@ fragment main { { const float multiplier = 0.14; - vec2 offset = omw_Texture2D(omw_SamplerDistortion, omw_TexCoord).rg; + vec2 offset = omw_GetDistortion(omw_TexCoord).rg; offset *= multiplier; offset = clamp(offset, vec2(-1.0), vec2(1.0)); - float occlusionFactor = omw_Texture2D(omw_SamplerDistortion, omw_TexCoord+offset).b; + float occlusionFactor = omw_GetDistortion(omw_TexCoord+offset).b; omw_FragColor = mix(omw_GetLastShader(omw_TexCoord + offset), omw_GetLastShader(omw_TexCoord), occlusionFactor); } diff --git a/files/shaders/compatibility/bs/default.frag b/files/shaders/compatibility/bs/default.frag index 5068c01d80..6f38c4df5e 100644 --- a/files/shaders/compatibility/bs/default.frag +++ b/files/shaders/compatibility/bs/default.frag @@ -26,8 +26,6 @@ uniform sampler2D normalMap; varying vec2 normalMapUV; #endif -uniform sampler2D opaqueDepthTex; - varying float euclideanDepth; varying float linearDepth; @@ -42,6 +40,7 @@ uniform float specStrength; uniform bool useTreeAnim; uniform float distortionStrength; +#include "lib/core/fragment.h.glsl" #include "lib/light/lighting.glsl" #include "lib/material/alpha.glsl" #include "lib/util/distortion.glsl" @@ -59,7 +58,7 @@ void main() #if defined(DISTORTION) && DISTORTION vec2 screenCoords = gl_FragCoord.xy / (screenRes * @distorionRTRatio); gl_FragData[0].a *= getDiffuseColor().a; - gl_FragData[0] = applyDistortion(gl_FragData[0], distortionStrength, gl_FragCoord.z, texture2D(opaqueDepthTex, screenCoords).x); + gl_FragData[0] = applyDistortion(gl_FragData[0], distortionStrength, gl_FragCoord.z, sampleOpaqueDepthTex(screenCoords).x); return; #endif diff --git a/files/shaders/compatibility/bs/nolighting.frag b/files/shaders/compatibility/bs/nolighting.frag index c9e3ca4e13..a46e99aa82 100644 --- a/files/shaders/compatibility/bs/nolighting.frag +++ b/files/shaders/compatibility/bs/nolighting.frag @@ -26,6 +26,7 @@ uniform float far; uniform float near; uniform float alphaRef; +#include "lib/core/fragment.h.glsl" #include "lib/material/alpha.glsl" #include "compatibility/vertexcolors.glsl" @@ -35,7 +36,6 @@ uniform float alphaRef; #if @softParticles #include "lib/particle/soft.glsl" -uniform sampler2D opaqueDepthTex; uniform float particleSize; uniform bool particleFade; uniform float softFalloffDepth; @@ -70,7 +70,7 @@ void main() viewNormal, near, far, - texture2D(opaqueDepthTex, screenCoords).x, + sampleOpaqueDepthTex(screenCoords).x, particleSize, particleFade, softFalloffDepth diff --git a/files/shaders/compatibility/objects.frag b/files/shaders/compatibility/objects.frag index 8bd9664b41..ad6d262f6d 100644 --- a/files/shaders/compatibility/objects.frag +++ b/files/shaders/compatibility/objects.frag @@ -89,6 +89,7 @@ varying vec4 passTangent; #define ADDITIVE_BLENDING #endif +#include "lib/core/fragment.h.glsl" #include "lib/light/lighting.glsl" #include "lib/material/parallax.glsl" #include "lib/material/alpha.glsl" @@ -113,8 +114,6 @@ uniform sampler2D orthoDepthMap; varying vec3 orthoDepthMapCoord; #endif -uniform sampler2D opaqueDepthTex; - void main() { #if @particleOcclusion @@ -143,7 +142,7 @@ vec2 screenCoords = gl_FragCoord.xy / screenRes; #if defined(DISTORTION) && DISTORTION gl_FragData[0].a *= getDiffuseColor().a; - gl_FragData[0] = applyDistortion(gl_FragData[0], distortionStrength, gl_FragCoord.z, texture2D(opaqueDepthTex, screenCoords / @distorionRTRatio).x); + gl_FragData[0] = applyDistortion(gl_FragData[0], distortionStrength, gl_FragCoord.z, sampleOpaqueDepthTex(screenCoords / @distorionRTRatio).x); return; #endif @@ -258,7 +257,7 @@ vec2 screenCoords = gl_FragCoord.xy / screenRes; viewNormal, near, far, - texture2D(opaqueDepthTex, screenCoords).x, + sampleOpaqueDepthTex(screenCoords).x, particleSize, particleFade, softFalloffDepth diff --git a/files/shaders/lib/core/fragment.glsl b/files/shaders/lib/core/fragment.glsl index 9b983148cb..d58e17feaf 100644 --- a/files/shaders/lib/core/fragment.glsl +++ b/files/shaders/lib/core/fragment.glsl @@ -40,3 +40,10 @@ vec3 sampleSkyColor(vec2 uv) return texture2D(sky, uv).xyz; } #endif + +uniform sampler2D opaqueDepthTex; + +vec4 sampleOpaqueDepthTex(vec2 uv) +{ + return texture2D(opaqueDepthTex, uv); +} diff --git a/files/shaders/lib/core/fragment.h.glsl b/files/shaders/lib/core/fragment.h.glsl index b8c3f9a32b..9b7ef768e6 100644 --- a/files/shaders/lib/core/fragment.h.glsl +++ b/files/shaders/lib/core/fragment.h.glsl @@ -17,4 +17,6 @@ vec4 samplerLastShader(vec2 uv); vec3 sampleSkyColor(vec2 uv); #endif +vec4 sampleOpaqueDepthTex(vec2 uv); + #endif // OPENMW_FRAGMENT_H_GLSL diff --git a/files/shaders/lib/core/fragment_multiview.glsl b/files/shaders/lib/core/fragment_multiview.glsl index 2880087104..e29c5afbc9 100644 --- a/files/shaders/lib/core/fragment_multiview.glsl +++ b/files/shaders/lib/core/fragment_multiview.glsl @@ -2,6 +2,7 @@ #extension GL_OVR_multiview : require #extension GL_OVR_multiview2 : require +#extension GL_EXT_texture_array : require #include "lib/core/fragment.h.glsl" @@ -44,3 +45,10 @@ vec3 sampleSkyColor(vec2 uv) return texture(sky, vec3((uv), gl_ViewID_OVR)).xyz; } #endif + +uniform sampler2DArray opaqueDepthTex; + +vec4 sampleOpaqueDepthTex(vec2 uv) +{ + return texture(opaqueDepthTex, vec3((uv), gl_ViewID_OVR)); +}