From b5b146b81b26ddcb3e73b18af6a3ecd795f5e0ac Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 16 Apr 2015 17:35:37 -0700 Subject: [PATCH] Training Team: improving the sun lighting interface to javascript to enable / disable the earthSkyModel, assign explicitely the SUnDirection and getter, and expose a AmbientINtensity to control the amount of the ambient lighting contribution Expose these to javascript --- examples/example/misc/sunLightExample.js | 6 +++ interface/src/Application.cpp | 2 +- libraries/model/src/model/Light.cpp | 4 ++ libraries/model/src/model/Light.h | 6 ++- libraries/model/src/model/Light.slh | 1 + libraries/model/src/model/Stage.cpp | 27 ++++++++--- libraries/model/src/model/Stage.h | 47 ++++++++++++------- .../render-utils/src/DeferredGlobalLight.slh | 6 +-- .../src/DeferredLightingEffect.cpp | 3 +- .../render-utils/src/DeferredLightingEffect.h | 2 +- .../src/SceneScriptingInterface.cpp | 24 ++++++++++ .../src/SceneScriptingInterface.h | 14 ++++++ 12 files changed, 111 insertions(+), 31 deletions(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index e6c06bb1ae..55c312881f 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -78,6 +78,12 @@ panel.newSlider("Light Intensity", 0.0, 5, function(value) { return (value).toFixed(2); } ); +panel.newSlider("Light Ambient Intensity", 0.0, 1.0, + function(value) { Scene.setSunAmbientIntensity(value); }, + function() { return Scene.getSunAmbientIntensity(); }, + function(value) { return (value).toFixed(2); } +); + Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) { return panel.mouseMoveEvent(event); }); Controller.mousePressEvent.connect( function panelMousePressEvent(event) { return panel.mousePressEvent(event); }); Controller.mouseReleaseEvent.connect(function(event) { return panel.mouseReleaseEvent(event); }); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dc24127054..56b5d931e3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3045,7 +3045,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs { DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); auto skyStage = DependencyManager::get()->getSkyStage(); - DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity()); + DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity()); DependencyManager::get()->setGlobalAtmosphere(skyStage->getAtmosphere()); PROFILE_RANGE("DeferredLighting"); diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index ea77412140..e8c01c68aa 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -64,6 +64,10 @@ void Light::setIntensity(float intensity) { editSchema()._intensity = intensity; } +void Light::setAmbientIntensity(float intensity) { + editSchema()._ambientIntensity = intensity; +} + void Light::setMaximumRadius(float radius) { if (radius <= 0.f) { radius = 1.0f; diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 8f6c663668..6b9371a0ee 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -244,6 +244,10 @@ public: void setShowContour(float show); float getShowContour() const { return getSchema()._control.w; } + // If the light has an ambient (Indirect) component, then the Ambientintensity can be used to control its contribution to the lighting + void setAmbientIntensity(float intensity); + float getAmbientIntensity() const { return getSchema()._ambientIntensity; } + // Spherical Harmonics storing the Ambien lighting approximation used for the Sun typed light void setAmbientSphere(const SphericalHarmonics& sphere) { _ambientSphere = sphere; } const SphericalHarmonics& getAmbientSphere() const { return _ambientSphere; } @@ -254,7 +258,7 @@ public: public: Vec4 _position{0.0f, 0.0f, 0.0f, 1.0f}; Vec3 _direction{0.0f, 0.0f, -1.0f}; - float _spare0{0.0f}; + float _ambientIntensity{0.0f}; Color _color{1.0f}; float _intensity{1.0f}; Vec4 _attenuation{1.0f}; diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index 41c6e075cf..1aaf0e8327 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -27,6 +27,7 @@ vec3 getLightDirection(Light l) { return l._direction.xyz; } // direction is -Z vec3 getLightColor(Light l) { return l._color.rgb; } float getLightIntensity(Light l) { return l._color.w; } +float getLightAmbientIntensity(Light l) { return l._direction.w; } float evalLightAttenuation(Light l, float r) { float d = max(r - l._attenuation.x, 0.0); diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index b72aa16497..68c13e5a7c 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -203,6 +203,7 @@ SunSkyStage::SunSkyStage() : _sunLight->setType(Light::SUN); setSunIntensity(1.0f); + setSunAmbientIntensity(0.5f); setSunColor(Vec3(1.0f, 1.0f, 1.0f)); // Default origin location is a special place in the world... @@ -249,12 +250,26 @@ void SunSkyStage::setOriginLocation(float longitude, float latitude, float altit invalidate(); } +void SunSkyStage::setEarthSunModelEnable(bool isEnabled) { + _earthSunModelEnable = isEnabled; + invalidate(); +} + void SunSkyStage::setSunColor(const Vec3& color) { _sunLight->setColor(color); } void SunSkyStage::setSunIntensity(float intensity) { _sunLight->setIntensity(intensity); } +void SunSkyStage::setSunAmbientIntensity(float intensity) { + _sunLight->setAmbientIntensity(intensity); +} + +void SunSkyStage::setSunDirection(const Vec3& direction) { + if (!isEarthSunModelEnabled()) { + _sunLight->setDirection(direction); + } +} // THe sun declinaison calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun double evalSunDeclinaison(double dayNumber) { @@ -271,19 +286,19 @@ void SunSkyStage::updateGraphicsObject() const { // And update the sunLAtitude as the declinaison depending of the time of the year _earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime)); - Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir(); - _sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z)); + if (isEarthSunModelEnabled()) { + Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir(); + _sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z)); - double originAlt = _earthSunModel.getAltitude(); - _sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f)); + double originAlt = _earthSunModel.getAltitude(); + _sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f)); + } static int firstTime = 0; if (firstTime == 0) { firstTime++; gpu::Shader::makeProgram(*(_skyPipeline->getProgram())); - } - } void SunSkyStage::setSkybox(const SkyboxPointer& skybox) { diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index 30c96259ca..968d50587a 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -177,38 +177,49 @@ typedef QSharedPointer< Skybox > SkyboxPointer; // Sun sky stage generates the rendering primitives to display a scene realistically // at the specified location and time around earth -class SunSkyStage { +class SunSkyStage : public QObject { + Q_OBJECT public: SunSkyStage(); ~SunSkyStage(); // time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0] - void setDayTime(float hour); - float getDayTime() const { return _dayTime; } + Q_INVOKABLE void setDayTime(float hour); + Q_INVOKABLE float getDayTime() const { return _dayTime; } // time of the year expressed in day in the range [0, 365] - void setYearTime(unsigned int day); - unsigned int getYearTime() const { return _yearTime; } + Q_INVOKABLE void setYearTime(unsigned int day); + Q_INVOKABLE unsigned int getYearTime() const { return _yearTime; } // Origin orientation used to modify the cardinal axis alignement used. // THe default is north along +Z axis and west along +X axis. this orientation gets added // to the transform stack producing the sun light direction. - void setOriginOrientation(const Quat& orientation); - const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } + Q_INVOKABLE void setOriginOrientation(const Quat& orientation); + Q_INVOKABLE const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } // Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km] - void setOriginLocation(float longitude, float latitude, float surfaceAltitude); - float getOriginLatitude() const { return _earthSunModel.getLatitude(); } - float getOriginLongitude() const { return _earthSunModel.getLongitude(); } - float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); } + Q_INVOKABLE void setOriginLocation(float longitude, float latitude, float surfaceAltitude); + Q_INVOKABLE float getOriginLatitude() const { return _earthSunModel.getLatitude(); } + Q_INVOKABLE float getOriginLongitude() const { return _earthSunModel.getLongitude(); } + Q_INVOKABLE float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); } + + // Enable / disable the effect of the time and location on the sun direction and color + Q_INVOKABLE void setEarthSunModelEnable(bool isEnabled); + Q_INVOKABLE bool isEarthSunModelEnabled() const { return _earthSunModelEnable; } // Sun properties - void setSunColor(const Vec3& color); - const Vec3& getSunColor() const { return getSunLight()->getColor(); } - void setSunIntensity(float intensity); - float getSunIntensity() const { return getSunLight()->getIntensity(); } + Q_INVOKABLE void setSunColor(const Vec3& color); + Q_INVOKABLE const Vec3& getSunColor() const { return getSunLight()->getColor(); } + Q_INVOKABLE void setSunIntensity(float intensity); + Q_INVOKABLE float getSunIntensity() const { return getSunLight()->getIntensity(); } + Q_INVOKABLE void setSunAmbientIntensity(float intensity); + Q_INVOKABLE float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); } + // The sun direction is expressed in the world space + Q_INVOKABLE void setSunDirection(const Vec3& direction); + Q_INVOKABLE const Vec3& getSunDirection() const { return getSunLight()->getDirection(); } + LightPointer getSunLight() const { valid(); return _sunLight; } AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; } @@ -223,10 +234,10 @@ protected: gpu::PipelinePointer _skyPipeline; - float _dayTime; - int _yearTime; - + float _dayTime = 12.0f; + int _yearTime = 0; mutable EarthSunModel _earthSunModel; + bool _earthSunModelEnable = true; mutable bool _invalid = true; void invalidate() const { _invalid = true; } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index ecb1f503c7..cbf7c31d1f 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -66,7 +66,7 @@ vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec3 color = diffuse.rgb * getLightColor(light) * 0.5; + vec3 color = diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light); vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); @@ -83,7 +83,7 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no vec3 fragEyeDir = normalize(fragEyeVector.xyz); vec3 ambientNormal = fragNormal.xyz; - vec3 color = diffuse.rgb * 0.5 * evalSphericalLight(ambientSphere, ambientNormal).xyz; + vec3 color = diffuse.rgb * evalSphericalLight(ambientSphere, ambientNormal).xyz * getLightAmbientIntensity(light); vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); @@ -112,7 +112,7 @@ vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, ve vec3 diffuseLight = lightAttenuation * lightmap; // ambient is a tiny percentage of the lightmap and only when in the shadow - vec3 ambientLight = (1 - lightAttenuation) * 0.5 * lightmap; + vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light); return diffuse * (ambientLight + diffuseLight); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 440f75e32e..bddb1815bf 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -554,11 +554,12 @@ void DeferredLightingEffect::setAmbientLightMode(int preset) { } } -void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity) { +void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity, float ambientIntensity) { auto light = _allocatedLights.front(); light->setDirection(direction); light->setColor(diffuse); light->setIntensity(intensity); + light->setAmbientIntensity(ambientIntensity); } void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& skybox) { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 6d0d131029..0d3d370fd4 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -73,7 +73,7 @@ public: // update global lighting void setAmbientLightMode(int preset); - void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity); + void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity, float ambientIntensity); void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; } void setGlobalSkybox(const model::SkyboxPointer& skybox); diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index 5a8f591410..0f3818317e 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -62,6 +62,30 @@ float SceneScriptingInterface::getSunIntensity() const { return _skyStage->getSunIntensity(); } +void SceneScriptingInterface::setSunAmbientIntensity(float intensity) { + _skyStage->setSunAmbientIntensity(intensity); +} + +float SceneScriptingInterface::getSunAmbientIntensity() const { + return _skyStage->getSunAmbientIntensity(); +} + +void SceneScriptingInterface::setSunDirection(const glm::vec3& direction) { + _skyStage->setSunDirection(direction); +} + +const glm::vec3& SceneScriptingInterface::getSunDirection() const { + return _skyStage->getSunDirection(); +} + +void SceneScriptingInterface::setStageEarthSunModelEnable(bool isEnabled) { + _skyStage->setEarthSunModelEnable(isEnabled); +} + +bool SceneScriptingInterface::isStageEarthSunModelEnabled() const { + return _skyStage->isEarthSunModelEnabled(); +} + model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { return _skyStage; } diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 352bc1e78f..83f5a44bb7 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -38,10 +38,24 @@ public: Q_INVOKABLE void setStageYearTime(int day); Q_INVOKABLE int getStageYearTime() const; + Q_INVOKABLE void setStageEarthSunModelEnable(bool isEnabled); + Q_INVOKABLE bool isStageEarthSunModelEnabled() const; + + Q_INVOKABLE void setSunColor(const glm::vec3& color); Q_INVOKABLE const glm::vec3& getSunColor() const; Q_INVOKABLE void setSunIntensity(float intensity); Q_INVOKABLE float getSunIntensity() const; + Q_INVOKABLE void setSunAmbientIntensity(float intensity); + Q_INVOKABLE float getSunAmbientIntensity() const; + + // Only valid if stage Earth Sun model is disabled + Q_INVOKABLE void setSunDirection(const glm::vec3& direction); + + Q_INVOKABLE const glm::vec3& getSunDirection() const; + + + model::SunSkyStagePointer getSkyStage() const;