From 532b26bf3cda07fc73f23bdf39f07678f2024389 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 14 Apr 2017 15:32:18 +0200 Subject: [PATCH 1/7] osgShadow experiment --- CMakeLists.txt | 2 +- apps/openmw/CMakeLists.txt | 1 + apps/openmw/mwrender/renderingmanager.cpp | 43 +++++++++++++++++++++-- apps/openmw/mwrender/vismask.hpp | 4 ++- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b4e9ad4b..7c8e8cd16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,8 +206,8 @@ if(NOT HAVE_STDINT_H) message(FATAL_ERROR "stdint.h was not found" ) endif() +find_package(OpenSceneGraph 3.3.4 REQUIRED osgDB osgViewer osgText osgGA osgAnimation osgParticle osgUtil osgFX osgShadow) -find_package(OpenSceneGraph 3.3.4 REQUIRED osgDB osgViewer osgText osgGA osgAnimation osgParticle osgUtil osgFX) include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}) set(USED_OSG_PLUGINS diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index a06678488..6e4a7baab 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -126,6 +126,7 @@ target_link_libraries(openmw ${OSGDB_LIBRARIES} ${OSGVIEWER_LIBRARIES} ${OSGGA_LIBRARIES} + ${OSGSHADOW_LIBRARIES} ${Boost_SYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 6ee9b8ae8..87c13f981 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -13,6 +13,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #include #include @@ -183,6 +190,7 @@ namespace MWRender , mFieldOfViewOverridden(false) { resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem); + resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders"); resourceSystem->getSceneManager()->setForceShaders(Settings::Manager::getBool("force shaders", "Shaders")); resourceSystem->getSceneManager()->setClampLighting(Settings::Manager::getBool("clamp lighting", "Shaders")); @@ -198,7 +206,35 @@ namespace MWRender mSceneRoot = sceneRoot; sceneRoot->setStartLight(1); - mRootNode->addChild(sceneRoot); + osg::ref_ptr shadowedScene (new osgShadow::ShadowedScene); + + osgShadow::ShadowSettings* settings = shadowedScene->getShadowSettings(); + settings->setLightNum(0); + settings->setCastsShadowTraversalMask(Mask_Scene|Mask_Actor|Mask_Player); + settings->setReceivesShadowTraversalMask(~0u); + + settings->setShadowMapProjectionHint(osgShadow::ShadowSettings::PERSPECTIVE_SHADOW_MAP); + settings->setBaseShadowTextureUnit(1); + settings->setMinimumShadowMapNearFarRatio(0); + settings->setNumShadowMapsPerLight(1); + //settings->setShadowMapProjectionHint(osgShadow::ShadowSettings::ORTHOGRAPHIC_SHADOW_MAP); + //settings->setMultipleShadowMapHint(osgShadow::ShadowSettings::PARALLEL_SPLIT); // ignored + //settings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); + //settings->setDebugDraw(true); + + settings->setPerspectiveShadowMapCutOffAngle(0); + settings->setShaderHint(osgShadow::ShadowSettings::PROVIDE_VERTEX_AND_FRAGMENT_SHADER); + + int mapres = 2048; + settings->setTextureSize(osg::Vec2s(mapres,mapres)); + + osgShadow::ShadowTechnique* tech = new osgShadow::ViewDependentShadowMap; + shadowedScene->setShadowTechnique(tech); + + //mRootNode->addChild(sceneRoot); + shadowedScene->addChild(sceneRoot); + mRootNode->addChild(shadowedScene); + mPathgrid.reset(new Pathgrid(mRootNode)); @@ -228,7 +264,7 @@ namespace MWRender mViewer->setLightingMode(osgViewer::View::NO_LIGHT); osg::ref_ptr source = new osg::LightSource; - source->setNodeMask(Mask_Lighting); + //source->setNodeMask(Mask_Lighting); mSunLight = new osg::Light; source->setLight(mSunLight); mSunLight->setDiffuse(osg::Vec4f(0,0,0,1)); @@ -272,7 +308,8 @@ namespace MWRender mViewer->getCamera()->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); mViewer->getCamera()->setCullingMode(cullingMode); - mViewer->getCamera()->setCullMask(~(Mask_UpdateVisitor|Mask_SimpleWater)); + //mViewer->getCamera()->setCullMask(~(Mask_UpdateVisitor|Mask_SimpleWater)); + mViewer->getCamera()->setCullMask(~(Mask_Lighting)); mNearClip = Settings::Manager::getFloat("near clip", "Camera"); mViewDistance = Settings::Manager::getFloat("viewing distance", "Camera"); diff --git a/apps/openmw/mwrender/vismask.hpp b/apps/openmw/mwrender/vismask.hpp index d52c7c232..1f620b7f7 100644 --- a/apps/openmw/mwrender/vismask.hpp +++ b/apps/openmw/mwrender/vismask.hpp @@ -51,7 +51,9 @@ namespace MWRender Mask_PreCompile = (1<<16), // Set on a camera's cull mask to enable the LightManager - Mask_Lighting = (1<<17) + Mask_Lighting = (1<<17), + + Mask_CastsShadows = (1<<18) }; } From 76e8a0b768bc38c56f1711a1aa1051ac7c0a92ec Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Mon, 11 Sep 2017 22:32:45 +0100 Subject: [PATCH 2/7] Add changes I missed in a merge. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0050104cf..5f0c539a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,7 +210,7 @@ if(NOT HAVE_STDINT_H) endif() -find_package(OpenSceneGraph 3.3.4 REQUIRED osgDB osgViewer osgText osgGA osgParticle osgUtil osgFX) +find_package(OpenSceneGraph 3.3.4 REQUIRED osgDB osgViewer osgText osgGA osgAnimation osgParticle osgUtil osgFX osgShadow) include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}) set(USED_OSG_PLUGINS From 99f6a1b8e15b86aa7860b3e3c2890533bb4b8bea Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Tue, 19 Sep 2017 23:44:37 +0100 Subject: [PATCH 3/7] Switch to LispSM --- apps/openmw/mwrender/renderingmanager.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 820fdab49..1b78bef80 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -213,24 +213,31 @@ namespace MWRender settings->setCastsShadowTraversalMask(Mask_Scene|Mask_Actor|Mask_Player); settings->setReceivesShadowTraversalMask(~0u); - settings->setShadowMapProjectionHint(osgShadow::ShadowSettings::PERSPECTIVE_SHADOW_MAP); - settings->setBaseShadowTextureUnit(1); - settings->setMinimumShadowMapNearFarRatio(0); - settings->setNumShadowMapsPerLight(1); + //settings->setShadowMapProjectionHint(osgShadow::ShadowSettings::PERSPECTIVE_SHADOW_MAP); + //settings->setBaseShadowTextureUnit(1); + //settings->setMinimumShadowMapNearFarRatio(0); + //settings->setNumShadowMapsPerLight(1); //settings->setShadowMapProjectionHint(osgShadow::ShadowSettings::ORTHOGRAPHIC_SHADOW_MAP); //settings->setMultipleShadowMapHint(osgShadow::ShadowSettings::PARALLEL_SPLIT); // ignored //settings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); //settings->setDebugDraw(true); - settings->setPerspectiveShadowMapCutOffAngle(0); - settings->setShaderHint(osgShadow::ShadowSettings::PROVIDE_VERTEX_AND_FRAGMENT_SHADER); + //settings->setPerspectiveShadowMapCutOffAngle(0); + //settings->setShaderHint(osgShadow::ShadowSettings::PROVIDE_VERTEX_AND_FRAGMENT_SHADER); int mapres = 2048; settings->setTextureSize(osg::Vec2s(mapres,mapres)); - osgShadow::ShadowTechnique* tech = new osgShadow::ViewDependentShadowMap; + osgShadow::MinimalShadowMap* tech = new osgShadow::LightSpacePerspectiveShadowMapDB(); shadowedScene->setShadowTechnique(tech); + tech->setMaxFarPlane(0); + tech->setTextureSize(osg::Vec2s(mapres, mapres)); + tech->setShadowTextureCoordIndex(1); + tech->setShadowTextureUnit(1); + tech->setBaseTextureCoordIndex(0); + tech->setBaseTextureUnit(0); + //mRootNode->addChild(sceneRoot); shadowedScene->addChild(sceneRoot); mRootNode->addChild(shadowedScene); From f50063402dea5ab8a2e1badd2e7566d1ca100cbf Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 21 Sep 2017 00:25:48 +0100 Subject: [PATCH 4/7] Adjust shaders to support shadows --- CI/before_script.msvc.sh | 2 +- files/shaders/lighting.glsl | 28 +++++++++++++++++++++------- files/shaders/objects_fragment.glsl | 13 ++++++++++--- files/shaders/objects_vertex.glsl | 6 ++++++ files/shaders/terrain_fragment.glsl | 13 ++++++++++--- files/shaders/terrain_vertex.glsl | 6 ++++++ 6 files changed, 54 insertions(+), 14 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 14998a3c6..11317a33f 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -761,7 +761,7 @@ if [ -z $CI ]; then echo " settings-default.cfg" cp settings-default.cfg $BUILD_CONFIG/settings-default.cfg echo " resources/" - cp -r resources $BUILD_CONFIG/resources + cp -r resources $BUILD_CONFIG echo fi diff --git a/files/shaders/lighting.glsl b/files/shaders/lighting.glsl index 7b8486fbe..892ae485a 100644 --- a/files/shaders/lighting.glsl +++ b/files/shaders/lighting.glsl @@ -1,10 +1,23 @@ #define MAX_LIGHTS 8 -vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor) +vec3 perLight(int lightIndex, vec3 viewPos, vec3 viewNormal, vec4 diffuse, vec3 ambient) { vec3 lightDir; float d; + lightDir = gl_LightSource[lightIndex].position.xyz - (viewPos.xyz * gl_LightSource[lightIndex].position.w); + d = length(lightDir); + lightDir = normalize(lightDir); + + return (ambient * gl_LightSource[lightIndex].ambient.xyz + diffuse.xyz * gl_LightSource[lightIndex].diffuse.xyz * max(dot(viewNormal.xyz, lightDir), 0.0)) * clamp(1.0 / (gl_LightSource[lightIndex].constantAttenuation + gl_LightSource[lightIndex].linearAttenuation * d + gl_LightSource[lightIndex].quadraticAttenuation * d * d), 0.0, 1.0); +} + +#ifdef FRAGMENT +vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor, float shadowing) +#else +vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor) +#endif +{ #if @colorMode == 3 vec4 diffuse = gl_FrontMaterial.diffuse; vec3 ambient = vertexColor.xyz; @@ -17,13 +30,14 @@ vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor) #endif vec4 lightResult = vec4(0.0, 0.0, 0.0, diffuse.a); - for (int i=0; i Date: Thu, 21 Sep 2017 00:49:34 +0100 Subject: [PATCH 5/7] Stop shadowing ambient lighting from the light casting a shadow when using per-pixel lighting. --- files/shaders/lighting.glsl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/files/shaders/lighting.glsl b/files/shaders/lighting.glsl index 892ae485a..e50e2f9c2 100644 --- a/files/shaders/lighting.glsl +++ b/files/shaders/lighting.glsl @@ -1,6 +1,6 @@ #define MAX_LIGHTS 8 -vec3 perLight(int lightIndex, vec3 viewPos, vec3 viewNormal, vec4 diffuse, vec3 ambient) +vec3 perLight(int lightIndex, vec3 viewPos, vec3 viewNormal, vec4 diffuse, vec3 ambient, float shadowing) { vec3 lightDir; float d; @@ -9,7 +9,7 @@ vec3 perLight(int lightIndex, vec3 viewPos, vec3 viewNormal, vec4 diffuse, vec3 d = length(lightDir); lightDir = normalize(lightDir); - return (ambient * gl_LightSource[lightIndex].ambient.xyz + diffuse.xyz * gl_LightSource[lightIndex].diffuse.xyz * max(dot(viewNormal.xyz, lightDir), 0.0)) * clamp(1.0 / (gl_LightSource[lightIndex].constantAttenuation + gl_LightSource[lightIndex].linearAttenuation * d + gl_LightSource[lightIndex].quadraticAttenuation * d * d), 0.0, 1.0); + return (ambient * gl_LightSource[lightIndex].ambient.xyz + diffuse.xyz * gl_LightSource[lightIndex].diffuse.xyz * max(dot(viewNormal.xyz, lightDir), 0.0)) * clamp(1.0 / (gl_LightSource[lightIndex].constantAttenuation + gl_LightSource[lightIndex].linearAttenuation * d + gl_LightSource[lightIndex].quadraticAttenuation * d * d), 0.0, 1.0) * shadowing; } #ifdef FRAGMENT @@ -31,13 +31,13 @@ vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor) vec4 lightResult = vec4(0.0, 0.0, 0.0, diffuse.a); #ifdef FRAGMENT - lightResult.xyz += perLight(0, viewPos, viewNormal, diffuse, ambient) * shadowing; + lightResult.xyz += perLight(0, viewPos, viewNormal, diffuse, ambient, shadowing); #else - lightResult.xyz += perLight(0, viewPos, viewNormal, diffuse, ambient); + lightResult.xyz += perLight(0, viewPos, viewNormal, diffuse, ambient, 1.0); #endif for (int i=1; i Date: Thu, 21 Sep 2017 01:59:02 +0100 Subject: [PATCH 6/7] Make shadows play nicely with per-vertex lighting --- files/shaders/lighting.glsl | 34 +++++++++++++++++++++-------- files/shaders/objects_fragment.glsl | 3 ++- files/shaders/objects_vertex.glsl | 3 ++- files/shaders/terrain_fragment.glsl | 3 ++- files/shaders/terrain_vertex.glsl | 3 ++- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/files/shaders/lighting.glsl b/files/shaders/lighting.glsl index e50e2f9c2..fe298e160 100644 --- a/files/shaders/lighting.glsl +++ b/files/shaders/lighting.glsl @@ -1,21 +1,33 @@ #define MAX_LIGHTS 8 -vec3 perLight(int lightIndex, vec3 viewPos, vec3 viewNormal, vec4 diffuse, vec3 ambient, float shadowing) +vec3 lightAmbient(int lightIndex, vec3 ambient) +{ + return ambient * gl_LightSource[lightIndex].ambient.xyz; +} + +vec3 lightDiffuse(int lightIndex, vec4 diffuse, vec3 viewNormal, vec3 lightDir) +{ + return diffuse.xyz * gl_LightSource[lightIndex].diffuse.xyz * max(dot(viewNormal.xyz, lightDir), 0.0); +} + +void perLight(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec3 viewPos, vec3 viewNormal, vec4 diffuse, vec3 ambient) { vec3 lightDir; - float d; + float lightDistance; - lightDir = gl_LightSource[lightIndex].position.xyz - (viewPos.xyz * gl_LightSource[lightIndex].position.w); - d = length(lightDir); + lightDir = gl_LightSource[lightIndex].position.xyz - (viewPos.xyz * gl_LightSource[lightIndex].position.w); + lightDistance = length(lightDir); lightDir = normalize(lightDir); + float illumination = clamp(1.0 / (gl_LightSource[lightIndex].constantAttenuation + gl_LightSource[lightIndex].linearAttenuation * lightDistance + gl_LightSource[lightIndex].quadraticAttenuation * lightDistance * lightDistance), 0.0, 1.0); - return (ambient * gl_LightSource[lightIndex].ambient.xyz + diffuse.xyz * gl_LightSource[lightIndex].diffuse.xyz * max(dot(viewNormal.xyz, lightDir), 0.0)) * clamp(1.0 / (gl_LightSource[lightIndex].constantAttenuation + gl_LightSource[lightIndex].linearAttenuation * d + gl_LightSource[lightIndex].quadraticAttenuation * d * d), 0.0, 1.0) * shadowing; + ambientOut = lightAmbient(lightIndex, ambient) * illumination; + diffuseOut = lightDiffuse(lightIndex, diffuse, viewNormal, lightDir) * illumination; } #ifdef FRAGMENT vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor, float shadowing) #else -vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor) +vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor, out vec3 shadowDiffuse) #endif { #if @colorMode == 3 @@ -30,14 +42,18 @@ vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor) #endif vec4 lightResult = vec4(0.0, 0.0, 0.0, diffuse.a); + vec3 diffuseLight, ambientLight; + perLight(ambientLight, diffuseLight, 0, viewPos, viewNormal, diffuse, ambient); #ifdef FRAGMENT - lightResult.xyz += perLight(0, viewPos, viewNormal, diffuse, ambient, shadowing); + lightResult.xyz += ambientLight + diffuseLight * shadowing; #else - lightResult.xyz += perLight(0, viewPos, viewNormal, diffuse, ambient, 1.0); + shadowDiffuse = diffuseLight; + lightResult.xyz += ambientLight; #endif for (int i=1; i Date: Thu, 21 Sep 2017 02:03:53 +0100 Subject: [PATCH 7/7] Tidy up the mess I made of lighting.glsl a bit by removing two single-line functions that are only ever called in one location. --- files/shaders/lighting.glsl | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/files/shaders/lighting.glsl b/files/shaders/lighting.glsl index fe298e160..afa636e3c 100644 --- a/files/shaders/lighting.glsl +++ b/files/shaders/lighting.glsl @@ -1,15 +1,5 @@ #define MAX_LIGHTS 8 -vec3 lightAmbient(int lightIndex, vec3 ambient) -{ - return ambient * gl_LightSource[lightIndex].ambient.xyz; -} - -vec3 lightDiffuse(int lightIndex, vec4 diffuse, vec3 viewNormal, vec3 lightDir) -{ - return diffuse.xyz * gl_LightSource[lightIndex].diffuse.xyz * max(dot(viewNormal.xyz, lightDir), 0.0); -} - void perLight(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec3 viewPos, vec3 viewNormal, vec4 diffuse, vec3 ambient) { vec3 lightDir; @@ -20,8 +10,8 @@ void perLight(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec3 vie lightDir = normalize(lightDir); float illumination = clamp(1.0 / (gl_LightSource[lightIndex].constantAttenuation + gl_LightSource[lightIndex].linearAttenuation * lightDistance + gl_LightSource[lightIndex].quadraticAttenuation * lightDistance * lightDistance), 0.0, 1.0); - ambientOut = lightAmbient(lightIndex, ambient) * illumination; - diffuseOut = lightDiffuse(lightIndex, diffuse, viewNormal, lightDir) * illumination; + ambientOut = ambient * gl_LightSource[lightIndex].ambient.xyz * illumination; + diffuseOut = diffuse.xyz * gl_LightSource[lightIndex].diffuse.xyz * max(dot(viewNormal.xyz, lightDir), 0.0) * illumination; } #ifdef FRAGMENT