diff --git a/components/sceneutil/lightmanager.cpp b/components/sceneutil/lightmanager.cpp index bc13559b1..3e741ea7e 100644 --- a/components/sceneutil/lightmanager.cpp +++ b/components/sceneutil/lightmanager.cpp @@ -71,6 +71,11 @@ namespace mat(2, 3) = q; mat(3, 3) = r; } + + bool isReflectionCamera(osg::Camera* camera) + { + return (camera->getName() == "ReflectionCamera"); + } } namespace SceneUtil @@ -612,6 +617,7 @@ namespace SceneUtil void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); + bool pop = false; if (mLastFrameNumber != cv->getTraversalNumber()) { @@ -642,15 +648,33 @@ namespace SceneUtil { auto buf = mLightManager->getLightBuffer(mLastFrameNumber); - buf->setDiffuse(0, sun->getDiffuse()); + buf->setPosition(0, sun->getPosition() * (*cv->getCurrentRenderStage()->getInitialViewMatrix())); buf->setAmbient(0, sun->getAmbient()); + buf->setDiffuse(0, sun->getDiffuse()); buf->setSpecular(0, sun->getSpecular()); - buf->setPosition(0, sun->getPosition() * (*cv->getCurrentRenderStage()->getInitialViewMatrix())); } } } + else if (isReflectionCamera(cv->getCurrentCamera())) + { + auto sun = mLightManager->getSunlight(); + if (sun) + { + osg::Vec4 originalPos = sun->getPosition(); + sun->setPosition(originalPos * (*cv->getCurrentRenderStage()->getInitialViewMatrix())); + + osg::ref_ptr stateset = new osg::StateSet; + configureStateSetSunOverride(mLightManager->getLightingMethod(), sun, stateset); + + sun->setPosition(originalPos); + cv->pushStateSet(stateset); + pop = true; + } + } traverse(node, nv); + if (pop) + cv->popStateSet(); } private: @@ -1151,7 +1175,7 @@ namespace SceneUtil const std::vector& LightManager::getLightsInViewSpace(osg::Camera *camera, const osg::RefMatrix* viewMatrix, size_t frameNum) { - bool isReflectionCamera = camera->getName() == "ReflectionCamera"; + bool isReflection = isReflectionCamera(camera); osg::observer_ptr camPtr (camera); auto it = mLightsInViewSpace.find(camPtr); @@ -1168,7 +1192,7 @@ namespace SceneUtil osg::BoundingSphere viewBound = osg::BoundingSphere(osg::Vec3f(0,0,0), radius * mPointLightRadiusMultiplier); transformBoundingSphere(worldViewMat, viewBound); - if (!isReflectionCamera && mPointLightFadeEnd != 0.f) + if (!isReflection && mPointLightFadeEnd != 0.f) { const float fadeDelta = mPointLightFadeEnd - mPointLightFadeStart; float fade = 1 - std::clamp((viewBound.center().length() - mPointLightFadeStart) / fadeDelta, 0.f, 1.f); diff --git a/files/shaders/lighting.glsl b/files/shaders/lighting.glsl index 49e2c3261..0d383e194 100644 --- a/files/shaders/lighting.glsl +++ b/files/shaders/lighting.glsl @@ -2,8 +2,7 @@ void perLightSun(out vec3 diffuseOut, vec3 viewPos, vec3 viewNormal) { - vec3 sunDiffuse = lcalcDiffuse(0).xyz; - vec3 lightDir = normalize(lcalcPosition(0).xyz); + vec3 lightDir = normalize(lcalcPosition(0)); float lambert = dot(viewNormal.xyz, lightDir); #ifndef GROUNDCOVER @@ -18,7 +17,7 @@ void perLightSun(out vec3 diffuseOut, vec3 viewPos, vec3 viewNormal) lambert *= clamp(-8.0 * (1.0 - 0.3) * eyeCosine + 1.0, 0.3, 1.0); #endif - diffuseOut = sunDiffuse * lambert; + diffuseOut = lcalcDiffuse(0).xyz * lambert; } void perLightPoint(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec3 viewPos, vec3 viewNormal) @@ -66,14 +65,14 @@ void doLighting(vec3 viewPos, vec3 viewNormal, out vec3 diffuseLight, out vec3 a #endif { vec3 ambientOut, diffuseOut; - ambientLight = gl_LightModel.ambient.xyz; perLightSun(diffuseOut, viewPos, viewNormal); + ambientLight = gl_LightModel.ambient.xyz; #if PER_PIXEL_LIGHTING diffuseLight = diffuseOut * shadowing; #else shadowDiffuse = diffuseOut; - diffuseLight = diffuseOut; + diffuseLight = vec3(0); #endif for (int i = @startLight; i < @endLight; ++i) @@ -90,14 +89,11 @@ void doLighting(vec3 viewPos, vec3 viewNormal, out vec3 diffuseLight, out vec3 a vec3 getSpecular(vec3 viewNormal, vec3 viewDirection, float shininess, vec3 matSpec) { - vec3 sunDir = lcalcPosition(0); - vec3 sunSpec = lcalcSpecular(0).xyz; - - vec3 lightDir = normalize(sunDir); + vec3 lightDir = normalize(lcalcPosition(0)); float NdotL = dot(viewNormal, lightDir); if (NdotL <= 0.0) return vec3(0.0); vec3 halfVec = normalize(lightDir - viewDirection); float NdotH = dot(viewNormal, halfVec); - return pow(max(NdotH, 0.0), max(1e-4, shininess)) * sunSpec * matSpec; + return pow(max(NdotH, 0.0), max(1e-4, shininess)) * lcalcSpecular(0).xyz * matSpec; }