From 64317f5fd097996d67781b3b0e162b583b03b01f Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 4 May 2017 16:47:03 -0700 Subject: [PATCH 01/22] Adding a light item per zone --- .../src/RenderableZoneEntityItem.cpp | 84 ++++++++++++++++++- .../src/RenderableZoneEntityItem.h | 9 +- libraries/render-utils/src/LightPayload.cpp | 68 +++++++++++++++ libraries/render-utils/src/LightPayload.h | 30 +++++++ libraries/render-utils/src/LightStage.h | 5 +- .../render-utils/src/RenderDeferredTask.cpp | 1 + .../utilities/render/deferredLighting.qml | 5 ++ 7 files changed, 198 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 66495a7054..de7b943a92 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -21,6 +21,9 @@ #include "EntityTreeRenderer.h" #include "RenderableEntityItem.h" +#include + + // Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1 // is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down. static const float SPHERE_ENTITY_SCALE = 0.5f; @@ -168,6 +171,37 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { _model->removeFromScene(scene, transaction); scene->enqueueTransaction(transaction); } + + /* + { + // Set the keylight + sceneKeyLight->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor())); + sceneKeyLight->setIntensity(this->getKeyLightProperties().getIntensity()); + sceneKeyLight->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity()); + sceneKeyLight->setDirection(this->getKeyLightProperties().getDirection()); + + // Set the stage + bool isSunModelEnabled = this->getStageProperties().getSunModelEnabled(); + sceneStage->setSunModelEnable(isSunModelEnabled); + if (isSunModelEnabled) { + sceneStage->setLocation(this->getStageProperties().getLongitude(), + this->getStageProperties().getLatitude(), + this->getStageProperties().getAltitude()); + + auto sceneTime = sceneStage->getTime(); + sceneTime->setHour(this->getStageProperties().calculateHour()); + sceneTime->setDay(this->getStageProperties().calculateDay()); + } + + // Set the ambient texture + _ambientTextureURL = this->getKeyLightProperties().getAmbientURL(); + if (_ambientTextureURL.isEmpty()) { + _pendingAmbientTexture = false; + _ambientTexture.clear(); + } else { + _pendingAmbientTexture = true; + } + }*/ } bool RenderableZoneEntityItem::contains(const glm::vec3& point) const { @@ -229,11 +263,25 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render:: renderPayload->addStatusGetters(statusGetters); transaction.resetItem(_myMetaItem, renderPayload); + + + _myKeyLightItem = scene->allocateID(); + + auto keyLightPayload = std::make_shared(); + updateKeyLightItemFromEntity((*keyLightPayload)); + + auto keyLightItem = std::make_shared(keyLightPayload); + + transaction.resetItem(_myKeyLightItem, keyLightItem); + + return true; } void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { + transaction.removeItem(_myKeyLightItem); + render::Item::clearID(_myKeyLightItem); transaction.removeItem(_myMetaItem); render::Item::clearID(_myMetaItem); if (_model) { @@ -249,11 +297,43 @@ void RenderableZoneEntityItem::notifyBoundChanged() { render::Transaction transaction; render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); if (scene) { - transaction.updateItem(_myMetaItem, [](RenderableZoneEntityItemMeta& data) { - }); + transaction.updateItem(_myMetaItem, [](RenderableZoneEntityItemMeta& data) {}); + transaction.updateItem(_myKeyLightItem, [](KeyLightPayload& data) {}); scene->enqueueTransaction(transaction); } else { qCWarning(entitiesrenderer) << "RenderableZoneEntityItem::notifyBoundChanged(), Unexpected null scene, possibly during application shutdown"; } } + +void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) { + auto entity = this; + + keylightPayload.setVisible(entity->getVisible()); + + auto light = keylightPayload.editLight(); + light->setPosition(entity->getPosition()); + light->setOrientation(entity->getRotation()); + + bool success; + keylightPayload.editBound() = entity->getAABox(success); + if (!success) { + keylightPayload.editBound() = render::Item::Bound(); + } + + // Set the keylight + light->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor())); + light->setIntensity(this->getKeyLightProperties().getIntensity()); + light->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity()); + light->setDirection(this->getKeyLightProperties().getDirection()); + + + // light->setColor(toGlm(entity->getXColor())); + + // float intensity = entity->getIntensity();//* entity->getFadingRatio(); + // light->setIntensity(intensity); + + + light->setType(model::Light::SUN); + +} diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index c81afdab08..d90993145e 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -16,6 +16,7 @@ #include class NetworkGeometry; +class KeyLightPayload; class RenderableZoneEntityItem : public ZoneEntityItem { public: @@ -42,7 +43,7 @@ public: virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; render::ItemID getRenderItemID() const { return _myMetaItem; } - + private: virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); notifyBoundChanged(); } virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyBoundChanged(); } @@ -54,11 +55,17 @@ private: template void changeProperties(Lambda functor); + + + void updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload); + Model* _model; bool _needsInitialSimulation; render::ItemID _myMetaItem{ render::Item::INVALID_ITEM_ID }; + + render::ItemID _myKeyLightItem { render::Item::INVALID_ITEM_ID }; }; #endif // hifi_RenderableZoneEntityItem_h diff --git a/libraries/render-utils/src/LightPayload.cpp b/libraries/render-utils/src/LightPayload.cpp index a670c9f620..dbdf7129ef 100644 --- a/libraries/render-utils/src/LightPayload.cpp +++ b/libraries/render-utils/src/LightPayload.cpp @@ -81,3 +81,71 @@ void LightPayload::render(RenderArgs* args) { } } + +namespace render { + template <> const ItemKey payloadGetKey(const KeyLightPayload::Pointer& payload) { + ItemKey::Builder builder; + builder.withTypeLight(); + if (!payload || !payload->isVisible()) { + builder.withInvisible(); + } + return builder.build(); + } + + template <> const Item::Bound payloadGetBound(const KeyLightPayload::Pointer& payload) { + if (payload) { + return payload->editBound(); + } + return render::Item::Bound(); + } + template <> void payloadRender(const KeyLightPayload::Pointer& payload, RenderArgs* args) { + if (args) { + if (payload) { + payload->render(args); + } + } + } +} + +KeyLightPayload::KeyLightPayload() : +_light(std::make_shared()) +{ +} + + +KeyLightPayload::~KeyLightPayload() { + if (!LightStage::isIndexInvalid(_index)) { + if (_stage) { + _stage->removeLight(_index); + } + } +} + +void KeyLightPayload::render(RenderArgs* args) { + if (!_stage) { + _stage = DependencyManager::get()->getLightStage(); + } + // Do we need to allocate the light in the stage ? + if (LightStage::isIndexInvalid(_index)) { + _index = _stage->addLight(_light); + _needUpdate = false; + } + // Need an update ? + if (_needUpdate) { + _stage->updateLightArrayBuffer(_index); + _needUpdate = false; + } + + if (isVisible()) { + // FInally, push the light visible in the frame + _stage->_currentFrame.pushLight(_index, _light->getType()); + +#ifdef WANT_DEBUG + Q_ASSERT(args->_batch); + gpu::Batch& batch = *args->_batch; + batch.setModelTransform(getTransformToCenter()); + DependencyManager::get()->renderWireSphere(batch, 0.5f, 15, 15, glm::vec4(color, 1.0f)); +#endif + } +} + diff --git a/libraries/render-utils/src/LightPayload.h b/libraries/render-utils/src/LightPayload.h index 6b5fe83f07..6a1435e12b 100644 --- a/libraries/render-utils/src/LightPayload.h +++ b/libraries/render-utils/src/LightPayload.h @@ -46,4 +46,34 @@ namespace render { template <> void payloadRender(const LightPayload::Pointer& payload, RenderArgs* args); } +class KeyLightPayload { +public: + using Payload = render::Payload; + using Pointer = Payload::DataPointer; + + KeyLightPayload(); + ~KeyLightPayload(); + void render(RenderArgs* args); + + model::LightPointer editLight() { _needUpdate = true; return _light; } + render::Item::Bound& editBound() { _needUpdate = true; return _bound; } + + void setVisible(bool visible) { _isVisible = visible; } + bool isVisible() const { return _isVisible; } + +protected: + model::LightPointer _light; + render::Item::Bound _bound; + LightStagePointer _stage; + LightStage::Index _index { LightStage::INVALID_INDEX }; + bool _needUpdate { true }; + bool _isVisible { true }; +}; + +namespace render { + template <> const ItemKey payloadGetKey(const KeyLightPayload::Pointer& payload); + template <> const Item::Bound payloadGetBound(const KeyLightPayload::Pointer& payload); + template <> void payloadRender(const KeyLightPayload::Pointer& payload, RenderArgs* args); +} + #endif \ No newline at end of file diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index c2293ac099..c38ca404ce 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -123,14 +123,17 @@ public: switch (type) { case model::Light::POINT: { pushPointLight(index); break; } case model::Light::SPOT: { pushSpotLight(index); break; } + case model::Light::SUN: { pushSunLight(index); break; } default: { break; } } } void pushPointLight(LightStage::Index index) { _pointLights.emplace_back(index); } void pushSpotLight(LightStage::Index index) { _spotLights.emplace_back(index); } - + void pushSunLight(LightStage::Index index) { _sunLights.emplace_back(index); } + LightStage::LightIndices _pointLights; LightStage::LightIndices _spotLights; + LightStage::LightIndices _sunLights; }; Frame _currentFrame; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 313b176f19..6367093cb4 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -162,6 +162,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawOpaqueBounds", opaques); task.addJob("DrawTransparentBounds", transparents); + task.addJob("DrawLightBounds", lights); task.addJob("ZoneRenderer", opaques); } diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 229a2d1c3b..c1d8da3db1 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -189,6 +189,11 @@ Column { checked: Render.getConfig("DrawOverlayTransparentBounds")["enabled"] onCheckedChanged: { Render.getConfig("DrawOverlayTransparentBounds")["enabled"] = checked } } + CheckBox { + text: "Lights" + checked: Render.getConfig("DrawLightBounds")["enabled"] + onCheckedChanged: { Render.getConfig("DrawLightBounds")["enabled"] = checked; } + } CheckBox { text: "Zones" checked: Render.getConfig("DrawZones")["enabled"] From df2c5b8c2346623a41aa6fc8345c343c8fb37504 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 4 May 2017 18:28:12 -0700 Subject: [PATCH 02/22] adding the notification for keyLight changes modifying the KeyLIghtPayoad --- interface/src/Application.cpp | 2 +- .../src/RenderableZoneEntityItem.cpp | 31 ++++++++++++++ .../src/RenderableZoneEntityItem.h | 3 +- libraries/entities/src/ZoneEntityItem.cpp | 42 +++++++++++++------ libraries/entities/src/ZoneEntityItem.h | 13 ++++++ .../utilities/render/deferredLighting.qml | 16 ++++--- 6 files changed, 86 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3be55e82cd..8a16b755f5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -337,7 +337,7 @@ public: // Don't actually crash in debug builds, in case this apparent deadlock is simply from // the developer actively debugging code #ifdef NDEBUG - deadlockDetectionCrash(); + // deadlockDetectionCrash(); #endif } } diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index de7b943a92..ad50c9f3cd 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -68,8 +68,17 @@ bool RenderableZoneEntityItem::setProperties(const EntityItemProperties& propert void RenderableZoneEntityItem::somethingChangedNotification() { DependencyManager::get()->updateZone(_id); + + // A new way: + if (_keyLightPropertiesChanged || _backgroundPropertiesChanged) { + notifyChangedRenderItem(); + } + + // Poopagate back to parent + ZoneEntityItem::somethingChangedNotification(); } + int RenderableZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, @@ -290,6 +299,7 @@ void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const ren } + void RenderableZoneEntityItem::notifyBoundChanged() { if (!render::Item::isValidID(_myMetaItem)) { return; @@ -337,3 +347,24 @@ void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& key light->setType(model::Light::SUN); } + +void RenderableZoneEntityItem::sceneUpdateRenderItemFromEntity(render::Transaction& transaction) { + if (!render::Item::isValidID(_myKeyLightItem)) { + return; + } + + transaction.updateItem(_myKeyLightItem, [&](KeyLightPayload& data) { + updateKeyLightItemFromEntity(data); + }); +} + +void RenderableZoneEntityItem::notifyChangedRenderItem() { + if (!render::Item::isValidID(_myKeyLightItem)) { + return; + } + + render::Transaction transaction; + render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); + sceneUpdateRenderItemFromEntity(transaction); + scene->enqueueTransaction(transaction); +} \ No newline at end of file diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index d90993145e..1f3132746c 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -56,7 +56,8 @@ private: template void changeProperties(Lambda functor); - + void notifyChangedRenderItem(); + void sceneUpdateRenderItemFromEntity(render::Transaction& transaction); void updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload); diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 1d73902e8d..364321ddf0 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -71,8 +71,26 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) { bool somethingChanged = false; somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class - bool somethingChangedInKeyLight = _keyLightProperties.setProperties(properties); - + if (somethingChanged) { + bool wantDebug = false; + if (wantDebug) { + uint64_t now = usecTimestampNow(); + int elapsed = now - getLastEdited(); + qCDebug(entities) << "ZoneEntityItem::setProperties() AFTER update... edited AGO=" << elapsed << + "now=" << now << " getLastEdited()=" << getLastEdited(); + } + setLastEdited(properties._lastEdited); + } + + return somethingChanged; +} + +bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& properties) { + bool somethingChanged = EntityItem::setSubClassProperties(properties); // set the properties in our base class + + + _keyLightPropertiesChanged = _keyLightProperties.setProperties(properties); + bool somethingChangedInStage = _stageProperties.setProperties(properties); SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, setShapeType); @@ -85,18 +103,8 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) { bool somethingChangedInSkybox = _skyboxProperties.setProperties(properties); - somethingChanged = somethingChanged || somethingChangedInKeyLight || somethingChangedInStage || somethingChangedInSkybox; + somethingChanged = somethingChanged || _keyLightPropertiesChanged || somethingChangedInStage || somethingChangedInSkybox; - if (somethingChanged) { - bool wantDebug = false; - if (wantDebug) { - uint64_t now = usecTimestampNow(); - int elapsed = now - getLastEdited(); - qCDebug(entities) << "ZoneEntityItem::setProperties() AFTER update... edited AGO=" << elapsed << - "now=" << now << " getLastEdited()=" << getLastEdited(); - } - setLastEdited(properties._lastEdited); - } return somethingChanged; } @@ -185,6 +193,14 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, getFilterURL()); } +void ZoneEntityItem::somethingChangedNotification() { + EntityItem::somethingChangedNotification(); + withWriteLock([&] { + _keyLightPropertiesChanged = false; + _backgroundPropertiesChanged = false; + }); +} + void ZoneEntityItem::debugDump() const { quint64 now = usecTimestampNow(); qCDebug(entities) << " ZoneEntityItem id:" << getEntityItemID() << "---------------------------------------------"; diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index c868da0954..2ef0b33d51 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -29,10 +29,16 @@ public: // methods for getting/setting all properties of an entity virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual bool setProperties(const EntityItemProperties& properties) override; + virtual bool setSubClassProperties(const EntityItemProperties& properties) override; // TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; + /// Override this in your derived class if you'd like to be informed when something about the state of the entity + /// has changed. This will be called with properties change or when new data is loaded from a stream + /// Overriding this function to capture the information that a keylight / Ambient / skybox properties has changed + virtual void somethingChangedNotification() override; + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, @@ -106,6 +112,13 @@ protected: bool _ghostingAllowed { DEFAULT_GHOSTING_ALLOWED }; QString _filterURL { DEFAULT_FILTER_URL }; + // Dirty flags turn true when either keylight properties is changing values. + // This gets back to false in the somethingChangedNotification() call + // Which is called after a setProperties() or a readEntitySubClassFromBUfferCall on the entity. + bool _keyLightPropertiesChanged { false }; + bool _backgroundPropertiesChanged { false }; + + static bool _drawZoneBoundaries; static bool _zonesArePickable; }; diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index c1d8da3db1..730aa547e7 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -162,13 +162,9 @@ Column { } } + Row { Column { - id: metas - CheckBox { - text: "Metas" - checked: Render.getConfig("DrawMetaBounds")["enabled"] - onCheckedChanged: { Render.getConfig("DrawMetaBounds")["enabled"] = checked } - } + CheckBox { text: "Opaques" checked: Render.getConfig("DrawOpaqueBounds")["enabled"] @@ -189,6 +185,13 @@ Column { checked: Render.getConfig("DrawOverlayTransparentBounds")["enabled"] onCheckedChanged: { Render.getConfig("DrawOverlayTransparentBounds")["enabled"] = checked } } + } + Column { + CheckBox { + text: "Metas" + checked: Render.getConfig("DrawMetaBounds")["enabled"] + onCheckedChanged: { Render.getConfig("DrawMetaBounds")["enabled"] = checked } + } CheckBox { text: "Lights" checked: Render.getConfig("DrawLightBounds")["enabled"] @@ -200,5 +203,6 @@ Column { onCheckedChanged: { Render.getConfig("ZoneRenderer")["enabled"] = checked; Render.getConfig("DrawZones")["enabled"] = checked; } } } + } } From db3d634840fa2ba628c5b74757746a58071019a1 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Fri, 5 May 2017 00:11:22 -0700 Subject: [PATCH 03/22] Adding the change notifications --- .../src/RenderableZoneEntityItem.cpp | 14 ++++---------- libraries/entities/src/ZoneEntityItem.cpp | 19 +++++++++++-------- libraries/entities/src/ZoneEntityItem.h | 5 +++-- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index ad50c9f3cd..8ce1a2ef9a 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -13,6 +13,8 @@ #include +#include + #include #include #include @@ -69,8 +71,8 @@ bool RenderableZoneEntityItem::setProperties(const EntityItemProperties& propert void RenderableZoneEntityItem::somethingChangedNotification() { DependencyManager::get()->updateZone(_id); - // A new way: - if (_keyLightPropertiesChanged || _backgroundPropertiesChanged) { + // If graphics elements are changed, we need to update the render items + if (_keyLightPropertiesChanged || _backgroundPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged) { notifyChangedRenderItem(); } @@ -337,15 +339,7 @@ void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& key light->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity()); light->setDirection(this->getKeyLightProperties().getDirection()); - - // light->setColor(toGlm(entity->getXColor())); - - // float intensity = entity->getIntensity();//* entity->getFadingRatio(); - // light->setIntensity(intensity); - - light->setType(model::Light::SUN); - } void RenderableZoneEntityItem::sceneUpdateRenderItemFromEntity(render::Transaction& transaction) { diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 364321ddf0..074437b6b2 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -91,7 +91,7 @@ bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& propertie _keyLightPropertiesChanged = _keyLightProperties.setProperties(properties); - bool somethingChangedInStage = _stageProperties.setProperties(properties); + _stagePropertiesChanged = _stageProperties.setProperties(properties); SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, setShapeType); SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL); @@ -101,9 +101,9 @@ bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& propertie SET_ENTITY_PROPERTY_FROM_PROPERTIES(ghostingAllowed, setGhostingAllowed); SET_ENTITY_PROPERTY_FROM_PROPERTIES(filterURL, setFilterURL); - bool somethingChangedInSkybox = _skyboxProperties.setProperties(properties); + _skyboxPropertiesChanged = _skyboxProperties.setProperties(properties); - somethingChanged = somethingChanged || _keyLightPropertiesChanged || somethingChangedInStage || somethingChangedInSkybox; + somethingChanged = somethingChanged || _keyLightPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged; return somethingChanged; @@ -117,14 +117,14 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, const unsigned char* dataAt = data; int bytesFromKeylight = _keyLightProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData, somethingChanged); - + propertyFlags, overwriteLocalData, _keyLightPropertiesChanged); + somethingChanged = somethingChanged || _keyLightPropertiesChanged; bytesRead += bytesFromKeylight; dataAt += bytesFromKeylight; int bytesFromStage = _stageProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData, somethingChanged); - + propertyFlags, overwriteLocalData, _stagePropertiesChanged); + somethingChanged = somethingChanged || _stagePropertiesChanged; bytesRead += bytesFromStage; dataAt += bytesFromStage; @@ -133,7 +133,8 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode); int bytesFromSkybox = _skyboxProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData, somethingChanged); + propertyFlags, overwriteLocalData, _skyboxPropertiesChanged); + somethingChanged = somethingChanged || _skyboxPropertiesChanged; bytesRead += bytesFromSkybox; dataAt += bytesFromSkybox; @@ -198,6 +199,8 @@ void ZoneEntityItem::somethingChangedNotification() { withWriteLock([&] { _keyLightPropertiesChanged = false; _backgroundPropertiesChanged = false; + _stagePropertiesChanged = false; + _skyboxPropertiesChanged = false; }); } diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index 2ef0b33d51..bcb690f60e 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -70,7 +70,7 @@ public: const KeyLightPropertyGroup& getKeyLightProperties() const { return _keyLightProperties; } - void setBackgroundMode(BackgroundMode value) { _backgroundMode = value; } + void setBackgroundMode(BackgroundMode value) { _backgroundMode = value; _backgroundPropertiesChanged = true; } BackgroundMode getBackgroundMode() const { return _backgroundMode; } const SkyboxPropertyGroup& getSkyboxProperties() const { return _skyboxProperties; } @@ -117,7 +117,8 @@ protected: // Which is called after a setProperties() or a readEntitySubClassFromBUfferCall on the entity. bool _keyLightPropertiesChanged { false }; bool _backgroundPropertiesChanged { false }; - + bool _skyboxPropertiesChanged { false }; + bool _stagePropertiesChanged { false }; static bool _drawZoneBoundaries; static bool _zonesArePickable; From b6c966ef39ded9d0327e831f8d0b9ef4adf9a8d2 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 5 May 2017 18:07:21 -0700 Subject: [PATCH 04/22] Keep iterating on the zones --- .../src/RenderableZoneEntityItem.cpp | 122 ++++++++++++++++-- .../src/RenderableZoneEntityItem.h | 21 ++- .../src/DeferredLightingEffect.cpp | 57 +------- .../render-utils/src/DeferredLightingEffect.h | 15 +-- libraries/render-utils/src/LightPayload.h | 8 ++ libraries/render-utils/src/LightStage.h | 2 +- 6 files changed, 142 insertions(+), 83 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 8ce1a2ef9a..7e78837345 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -24,6 +24,8 @@ #include "RenderableEntityItem.h" #include +#include "DeferredLightingEffect.h" + // Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1 @@ -73,6 +75,7 @@ void RenderableZoneEntityItem::somethingChangedNotification() { // If graphics elements are changed, we need to update the render items if (_keyLightPropertiesChanged || _backgroundPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged) { + notifyChangedRenderItem(); } @@ -120,6 +123,52 @@ void RenderableZoneEntityItem::updateGeometry() { } } +void RenderableZoneEntityItem::updateTextures() { + auto textureCache = DependencyManager::get(); + bool isAmbientSet = false; + if (_pendingAmbientTexture && !_ambientTexture) { + _ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::CUBE_TEXTURE); + } + if (_ambientTexture && _ambientTexture->isLoaded()) { + _pendingAmbientTexture = false; + + auto texture = _ambientTexture->getGPUTexture(); + if (texture) { + isAmbientSet = true; + } else { + qCDebug(entitiesrenderer) << "Failed to load ambient texture:" << _ambientTexture->getURL(); + } + } + + if (_pendingSkyboxTexture && + (!_skyboxTexture || (_skyboxTexture->getURL() != _skyboxTextureURL))) { + _skyboxTexture = textureCache->getTexture(_skyboxTextureURL, image::TextureUsage::CUBE_TEXTURE); + } + if (_skyboxTexture && _skyboxTexture->isLoaded()) { + _pendingSkyboxTexture = false; + + auto texture = _skyboxTexture->getGPUTexture(); + if (texture) { + // skybox->setCubemap(texture); + if (!isAmbientSet) { + // sceneKeyLight->setAmbientSphere(texture->getIrradiance()); + // sceneKeyLight->setAmbientMap(texture); + isAmbientSet = true; + } + } else { + qCDebug(entitiesrenderer) << "Failed to load skybox texture:" << _skyboxTexture->getURL(); + } + } else { + // skybox->setCubemap(nullptr); + } + + if (!isAmbientSet) { + // sceneKeyLight->resetAmbientSphere(); + // sceneKeyLight->setAmbientMap(nullptr); + } + +} + void RenderableZoneEntityItem::render(RenderArgs* args) { Q_ASSERT(getType() == EntityTypes::Zone); @@ -235,6 +284,23 @@ public: typedef Payload::DataPointer Pointer; EntityItemPointer entity; + + void render(RenderArgs* args); + + model::LightPointer editLight() { _needUpdate = true; return _light; } + render::Item::Bound& editBound() { _needUpdate = true; return _bound; } + + void setVisible(bool visible) { _isVisible = visible; } + bool isVisible() const { return _isVisible; } + + + model::LightPointer _light; + render::Item::Bound _bound; + LightStagePointer _stage; + LightStage::Index _index { LightStage::INVALID_INDEX }; + bool _needUpdate { true }; + bool _isVisible { true }; + }; namespace render { @@ -254,11 +320,7 @@ namespace render { return render::Item::Bound(); } template <> void payloadRender(const RenderableZoneEntityItemMeta::Pointer& payload, RenderArgs* args) { - if (args) { - if (payload && payload->entity) { - payload->entity->render(args); - } - } + payload->render(args); } } @@ -318,19 +380,20 @@ void RenderableZoneEntityItem::notifyBoundChanged() { } } -void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) { + +void RenderableZoneEntityItem::updateKeyZoneItemFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) { auto entity = this; - keylightPayload.setVisible(entity->getVisible()); + keyZonePayload.setVisible(entity->getVisible()); - auto light = keylightPayload.editLight(); + auto light = keyZonePayload.editLight(); light->setPosition(entity->getPosition()); light->setOrientation(entity->getRotation()); bool success; - keylightPayload.editBound() = entity->getAABox(success); + keyZonePayload.editBound() = entity->getAABox(success); if (!success) { - keylightPayload.editBound() = render::Item::Bound(); + keyZonePayload.editBound() = render::Item::Bound(); } // Set the keylight @@ -340,8 +403,14 @@ void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& key light->setDirection(this->getKeyLightProperties().getDirection()); light->setType(model::Light::SUN); + + } +void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) { +} + + void RenderableZoneEntityItem::sceneUpdateRenderItemFromEntity(render::Transaction& transaction) { if (!render::Item::isValidID(_myKeyLightItem)) { return; @@ -361,4 +430,35 @@ void RenderableZoneEntityItem::notifyChangedRenderItem() { render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); sceneUpdateRenderItemFromEntity(transaction); scene->enqueueTransaction(transaction); -} \ No newline at end of file +} + +void RenderableZoneEntityItemMeta::render(RenderArgs* args) { + entity->render(args); + + if (!_stage) { + _stage = DependencyManager::get()->getLightStage(); + } + // Do we need to allocate the light in the stage ? + if (LightStage::isIndexInvalid(_index)) { + _index = _stage->addLight(_light); + _needUpdate = false; + } + // Need an update ? + if (_needUpdate) { + _stage->updateLightArrayBuffer(_index); + _needUpdate = false; + } + + if (isVisible()) { + // FInally, push the light visible in the frame + _stage->_currentFrame.pushLight(_index, _light->getType()); + +#ifdef WANT_DEBUG + Q_ASSERT(args->_batch); + gpu::Batch& batch = *args->_batch; + batch.setModelTransform(getTransformToCenter()); + DependencyManager::get()->renderWireSphere(batch, 0.5f, 15, 15, glm::vec4(color, 1.0f)); +#endif + } + +} diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index 1f3132746c..79641682cf 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -18,6 +18,8 @@ class NetworkGeometry; class KeyLightPayload; +class RenderableZoneEntityItemMeta; + class RenderableZoneEntityItem : public ZoneEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); @@ -52,21 +54,34 @@ private: Model* getModel(); void initialSimulation(); void updateGeometry(); + + void updateTextures(); template void changeProperties(Lambda functor); void notifyChangedRenderItem(); void sceneUpdateRenderItemFromEntity(render::Transaction& transaction); - void updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload); + void updateKeyZoneItemFromEntity(RenderableZoneEntityItemMeta& keyZonePayload); + void updateKeyLightItemFromEntity(KeyLightPayload& keyLightPayload); - Model* _model; bool _needsInitialSimulation; - + render::ItemID _myMetaItem{ render::Item::INVALID_ITEM_ID }; render::ItemID _myKeyLightItem { render::Item::INVALID_ITEM_ID }; + + + // More attributes used for rendering: + NetworkTexturePointer _ambientTexture; + NetworkTexturePointer _skyboxTexture; + QString _ambientTextureURL; + QString _skyboxTextureURL; + bool _pendingAmbientTexture { false }; + bool _pendingSkyboxTexture { false }; + bool _validAmbientTextureURL { false }; + bool _validSkyboxTextureURL { false }; }; #endif // hifi_RenderableZoneEntityItem_h diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 93a176f4f3..3dd5ed0352 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -143,53 +143,12 @@ void DeferredLightingEffect::init() { } -void DeferredLightingEffect::addLight(const model::LightPointer& light) { - assert(light); - auto lightID = _lightStage->addLight(light); - if (light->getType() == model::Light::POINT) { - _pointLights.push_back(lightID); - } else { - _spotLights.push_back(lightID); - } -} - - -void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color, - float intensity, float falloffRadius) { - addSpotLight(position, radius, color, intensity, falloffRadius); -} - -void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color, - float intensity, float falloffRadius, const glm::quat& orientation, float exponent, float cutoff) { - - unsigned int lightID = (unsigned int)(_pointLights.size() + _spotLights.size() + _globalLights.size()); - if (lightID >= _allocatedLights.size()) { - _allocatedLights.push_back(std::make_shared()); - } - model::LightPointer lp = _allocatedLights[lightID]; - - lp->setPosition(position); - lp->setMaximumRadius(radius); - lp->setColor(color); - lp->setIntensity(intensity); - lp->setFalloffRadius(falloffRadius); - - if (exponent == 0.0f && cutoff == PI) { - lp->setType(model::Light::POINT); - _pointLights.push_back(lightID); - - } else { - lp->setOrientation(orientation); - lp->setSpotAngle(cutoff); - lp->setSpotExponent(exponent); - lp->setType(model::Light::SPOT); - _spotLights.push_back(lightID); - } -} - void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { PerformanceTimer perfTimer("DLE->setupBatch()"); auto keyLight = _allocatedLights[_globalLights.front()]; + if (_lightStage && _lightStage->_currentFrame._sunLights.size()) { + keyLight = _lightStage->getLight(_lightStage->_currentFrame._sunLights.front()); + } if (lightBufferUnit >= 0) { batch.setUniformBuffer(lightBufferUnit, keyLight->getLightSchemaBuffer()); @@ -772,16 +731,6 @@ void RenderDeferredCleanup::run(const render::RenderContextPointer& renderContex batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, nullptr); } - - auto deferredLightingEffect = DependencyManager::get(); - - // End of the Lighting pass - if (!deferredLightingEffect->_pointLights.empty()) { - deferredLightingEffect->_pointLights.clear(); - } - if (!deferredLightingEffect->_spotLights.empty()) { - deferredLightingEffect->_spotLights.clear(); - } } RenderDeferred::RenderDeferred() { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index dcf0c84622..ad3dcc9061 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -43,18 +43,7 @@ class DeferredLightingEffect : public Dependency { public: void init(); - - void addLight(const model::LightPointer& light); - - /// Adds a point light to render for the current frame. - void addPointLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(0.0f, 0.0f, 0.0f), - float intensity = 0.5f, float falloffRadius = 0.01f); - - /// Adds a spot light to render for the current frame. - void addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), - float intensity = 0.5f, float falloffRadius = 0.01f, - const glm::quat& orientation = glm::quat(), float exponent = 0.0f, float cutoff = PI); - + void setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit); void unsetKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit); @@ -113,8 +102,6 @@ private: Lights _allocatedLights; std::vector _globalLights; - std::vector _pointLights; - std::vector _spotLights; friend class LightClusteringPass; friend class RenderDeferredSetup; diff --git a/libraries/render-utils/src/LightPayload.h b/libraries/render-utils/src/LightPayload.h index 6a1435e12b..0cf8f8e2de 100644 --- a/libraries/render-utils/src/LightPayload.h +++ b/libraries/render-utils/src/LightPayload.h @@ -15,6 +15,7 @@ #include #include #include "LightStage.h" +#include "TextureCache.h" class LightPayload { public: @@ -61,6 +62,13 @@ public: void setVisible(bool visible) { _isVisible = visible; } bool isVisible() const { return _isVisible; } + + // More attributes used for rendering: + NetworkTexturePointer _ambientTexture; + QString _ambientTextureURL; + bool _pendingAmbientTexture { false }; + bool _validAmbientTextureURL { false }; + protected: model::LightPointer _light; render::Item::Bound _bound; diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index c38ca404ce..8da05ec052 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -118,7 +118,7 @@ public: public: Frame() {} - void clear() { _pointLights.clear(); _spotLights.clear(); } + void clear() { _pointLights.clear(); _spotLights.clear(); _sunLights.clear(); } void pushLight(LightStage::Index index, model::Light::Type type) { switch (type) { case model::Light::POINT: { pushPointLight(index); break; } From d3724116d973648066305bda3ec426776683d70f Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Mon, 8 May 2017 00:20:20 -0700 Subject: [PATCH 05/22] Using the items to pick the key light! --- interface/src/Application.cpp | 4 +- .../src/RenderableZoneEntityItem.cpp | 39 ++++++++++--------- libraries/model/src/model/Light.cpp | 2 +- libraries/model/src/model/Light.h | 2 +- .../src/DeferredLightingEffect.cpp | 8 ++-- .../render-utils/src/DeferredLightingEffect.h | 2 +- .../render-utils/src/RenderDeferredTask.cpp | 6 ++- libraries/render-utils/src/ZoneRenderer.cpp | 26 +++++++++++-- libraries/render-utils/src/ZoneRenderer.h | 3 +- 9 files changed, 60 insertions(+), 32 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8a16b755f5..2e0478176b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5126,8 +5126,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // Setup the current Zone Entity lighting { - auto stage = DependencyManager::get()->getSkyStage(); - DependencyManager::get()->setGlobalLight(stage->getSunLight()); + // auto stage = DependencyManager::get()->getSkyStage(); + // DependencyManager::get()->setGlobalLight(stage->getSunLight()); } { diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 7e78837345..fb5f71f6ec 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -279,7 +279,9 @@ bool RenderableZoneEntityItem::contains(const glm::vec3& point) const { class RenderableZoneEntityItemMeta { public: - RenderableZoneEntityItemMeta(EntityItemPointer entity) : entity(entity){ } + RenderableZoneEntityItemMeta(EntityItemPointer entity) : entity(entity), _light(std::make_shared()) { } + ~RenderableZoneEntityItemMeta(); + typedef render::Payload Payload; typedef Payload::DataPointer Pointer; @@ -305,7 +307,7 @@ public: namespace render { template <> const ItemKey payloadGetKey(const RenderableZoneEntityItemMeta::Pointer& payload) { - return ItemKey::Builder::opaqueShape(); + return ItemKey::Builder().withTypeMeta().build(); } template <> const Item::Bound payloadGetBound(const RenderableZoneEntityItemMeta::Pointer& payload) { @@ -330,6 +332,7 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render:: auto renderData = std::make_shared(self); auto renderPayload = std::make_shared(renderData); + updateKeyZoneItemFromEntity((*renderData)); render::Item::Status::Getters statusGetters; makeEntityItemStatusGetters(getThisPointer(), statusGetters); @@ -338,7 +341,7 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render:: transaction.resetItem(_myMetaItem, renderPayload); - _myKeyLightItem = scene->allocateID(); + /* _myKeyLightItem = scene->allocateID(); auto keyLightPayload = std::make_shared(); updateKeyLightItemFromEntity((*keyLightPayload)); @@ -347,14 +350,14 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render:: transaction.resetItem(_myKeyLightItem, keyLightItem); - +*/ return true; } void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { - transaction.removeItem(_myKeyLightItem); - render::Item::clearID(_myKeyLightItem); + // transaction.removeItem(_myKeyLightItem); + // render::Item::clearID(_myKeyLightItem); transaction.removeItem(_myMetaItem); render::Item::clearID(_myMetaItem); if (_model) { @@ -372,7 +375,7 @@ void RenderableZoneEntityItem::notifyBoundChanged() { render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); if (scene) { transaction.updateItem(_myMetaItem, [](RenderableZoneEntityItemMeta& data) {}); - transaction.updateItem(_myKeyLightItem, [](KeyLightPayload& data) {}); + // transaction.updateItem(_myKeyLightItem, [](KeyLightPayload& data) {}); scene->enqueueTransaction(transaction); } else { @@ -412,17 +415,17 @@ void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& key void RenderableZoneEntityItem::sceneUpdateRenderItemFromEntity(render::Transaction& transaction) { - if (!render::Item::isValidID(_myKeyLightItem)) { + if (!render::Item::isValidID(_myMetaItem)) { return; } - transaction.updateItem(_myKeyLightItem, [&](KeyLightPayload& data) { + transaction.updateItem(_myMetaItem, [&](KeyLightPayload& data) { updateKeyLightItemFromEntity(data); }); } void RenderableZoneEntityItem::notifyChangedRenderItem() { - if (!render::Item::isValidID(_myKeyLightItem)) { + if (!render::Item::isValidID(_myMetaItem)) { return; } @@ -432,6 +435,14 @@ void RenderableZoneEntityItem::notifyChangedRenderItem() { scene->enqueueTransaction(transaction); } +RenderableZoneEntityItemMeta::~RenderableZoneEntityItemMeta() { + if (!LightStage::isIndexInvalid(_index)) { + if (_stage) { + _stage->removeLight(_index); + } + } +} + void RenderableZoneEntityItemMeta::render(RenderArgs* args) { entity->render(args); @@ -452,13 +463,5 @@ void RenderableZoneEntityItemMeta::render(RenderArgs* args) { if (isVisible()) { // FInally, push the light visible in the frame _stage->_currentFrame.pushLight(_index, _light->getType()); - -#ifdef WANT_DEBUG - Q_ASSERT(args->_batch); - gpu::Batch& batch = *args->_batch; - batch.setModelTransform(getTransformToCenter()); - DependencyManager::get()->renderWireSphere(batch, 0.5f, 15, 15, glm::vec4(color, 1.0f)); -#endif } - } diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index 11b13606b8..19da084f84 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -145,7 +145,7 @@ void Light::setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) { _ambientSchemaBuffer.edit().ambientSphere.assignPreset(preset); } -void Light::setAmbientMap(gpu::TexturePointer ambientMap) { +void Light::setAmbientMap(const gpu::TexturePointer& ambientMap) { _ambientMap = ambientMap; if (ambientMap) { setAmbientMapNumMips(_ambientMap->getNumMips()); diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 947474bbfd..c772374f42 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -143,7 +143,7 @@ public: const gpu::SphericalHarmonics& getAmbientSphere() const { return _ambientSchemaBuffer->ambientSphere; } void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset); - void setAmbientMap(gpu::TexturePointer ambientMap); + void setAmbientMap(const gpu::TexturePointer& ambientMap); gpu::TexturePointer getAmbientMap() const { return _ambientMap; } void setAmbientMapNumMips(uint16_t numMips); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 3dd5ed0352..b7e4b184c0 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -145,9 +145,11 @@ void DeferredLightingEffect::init() { void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { PerformanceTimer perfTimer("DLE->setupBatch()"); - auto keyLight = _allocatedLights[_globalLights.front()]; + model::LightPointer keyLight; if (_lightStage && _lightStage->_currentFrame._sunLights.size()) { keyLight = _lightStage->getLight(_lightStage->_currentFrame._sunLights.front()); + } else { + keyLight = _allocatedLights[_globalLights.front()]; } if (lightBufferUnit >= 0) { @@ -168,11 +170,11 @@ void DeferredLightingEffect::unsetKeyLightBatch(gpu::Batch& batch, int lightBuff if (lightBufferUnit >= 0) { batch.setUniformBuffer(lightBufferUnit, nullptr); } - if (keyLight->hasAmbient() && (ambientBufferUnit >= 0)) { + if ((ambientBufferUnit >= 0)) { batch.setUniformBuffer(ambientBufferUnit, nullptr); } - if (keyLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) { + if ((skyboxCubemapUnit >= 0)) { batch.setResourceTexture(skyboxCubemapUnit, nullptr); } } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index ad3dcc9061..02f759bab3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -50,7 +50,7 @@ public: // update global lighting void setGlobalLight(const model::LightPointer& light); - const LightStagePointer getLightStage() { return _lightStage; } + const LightStagePointer& getLightStage() { return _lightStage; } void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; }; void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 6367093cb4..693c150004 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -75,7 +75,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto deferredFrameTransform = task.addJob("DeferredFrameTransform"); const auto lightingModel = task.addJob("LightingModel"); - // GPU jobs: Start preparing the primary, deferred and lighting buffer const auto primaryFramebuffer = task.addJob("PreparePrimaryBuffer"); @@ -124,6 +123,9 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now. task.addJob("DrawLight", lights); + // Filter zones + const auto zones = task.addJob("ZoneRenderer", metas); + // Light Clustering // Create the cluster grid of lights, cpu job for now const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, linearDepthTarget).hasVarying(); @@ -163,7 +165,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawTransparentBounds", transparents); task.addJob("DrawLightBounds", lights); - task.addJob("ZoneRenderer", opaques); + task.addJob("DrawZones", zones); } // Overlays diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 2cabe58c33..00b4565edf 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -15,13 +15,33 @@ using namespace render; +class SetupZones { +public: + using Inputs = render::ItemBounds; + using JobModel = render::Job::ModelI; + + SetupZones() {} + + void run(const RenderContextPointer& context, const Inputs& inputs); + +protected: +}; + const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) { - + // Filter out the sorted list of zones const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION.c_str()); - // just draw them... - task.addJob("DrawZones", zoneItems); + // just setup the current zone env + task.addJob("SetupZones", zoneItems); + + ouput = zoneItems; } +void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) { + + // call render in the correct order first... + render::renderItems(context, inputs); + +} diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index 1218608400..cbbfbcb84e 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -19,7 +19,8 @@ class ZoneRendererConfig : public render::Task::Config { Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty) public: - ZoneRendererConfig() : render::Task::Config(false) {} + ZoneRendererConfig() : render::Task::Config( + ) {} int maxDrawn { -1 }; From bbb513220bf32b0e474792fb4299c1e234c86ddc Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 8 May 2017 17:33:24 -0700 Subject: [PATCH 06/22] Moving forward --- .../src/RenderableZoneEntityItem.cpp | 509 +++++++++++------- .../src/RenderableZoneEntityItem.h | 20 +- libraries/model/src/model/Light.h | 5 +- .../src/DeferredLightingEffect.cpp | 25 +- libraries/render-utils/src/LightStage.h | 5 +- 5 files changed, 338 insertions(+), 226 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index fb5f71f6ec..55d47dde98 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -26,7 +26,64 @@ #include #include "DeferredLightingEffect.h" +class RenderableZoneEntityItemMeta { +public: + RenderableZoneEntityItemMeta(EntityItemPointer entity); + ~RenderableZoneEntityItemMeta(); + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + EntityItemPointer entity; + + void render(RenderArgs* args); + + void setVisible(bool visible) { _isVisible = visible; } + bool isVisible() const { return _isVisible; } + + render::Item::Bound& editBound() { _needUpdate = true; return _bound; } + + model::LightPointer editSunLight() { _needSunUpdate = true; return _sunLight; } + model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; } + model::SkyboxPointer editSkybox() { _needSkyboxUpdate = true; return _skybox; } + + void setAmbientURL(const QString& ambientUrl); + + void setSkyboxURL(const QString& skyboxUrl); + +protected: + render::Item::Bound _bound; + + model::LightPointer _sunLight; + model::LightPointer _ambientLight; + model::SkyboxPointer _skybox; + + LightStagePointer _stage; + LightStage::Index _sunIndex { LightStage::INVALID_INDEX }; + LightStage::Index _ambientIndex { LightStage::INVALID_INDEX }; + + bool _needUpdate { true }; + bool _needSunUpdate { true }; + bool _needAmbientUpdate { true }; + bool _needSkyboxUpdate { true }; + bool _isVisible { true }; + + + void updateAmbientMap(); + void updateSkyboxMap(); + + // More attributes used for rendering: + QString _ambientTextureURL; + NetworkTexturePointer _ambientTexture; + bool _pendingAmbientTexture { false }; + bool _validAmbientTexture { false }; + + QString _skyboxTextureURL; + NetworkTexturePointer _skyboxTexture; + bool _pendingSkyboxTexture { false }; + bool _validSkyboxTexture { false }; + +}; // Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1 // is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down. @@ -123,52 +180,6 @@ void RenderableZoneEntityItem::updateGeometry() { } } -void RenderableZoneEntityItem::updateTextures() { - auto textureCache = DependencyManager::get(); - bool isAmbientSet = false; - if (_pendingAmbientTexture && !_ambientTexture) { - _ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::CUBE_TEXTURE); - } - if (_ambientTexture && _ambientTexture->isLoaded()) { - _pendingAmbientTexture = false; - - auto texture = _ambientTexture->getGPUTexture(); - if (texture) { - isAmbientSet = true; - } else { - qCDebug(entitiesrenderer) << "Failed to load ambient texture:" << _ambientTexture->getURL(); - } - } - - if (_pendingSkyboxTexture && - (!_skyboxTexture || (_skyboxTexture->getURL() != _skyboxTextureURL))) { - _skyboxTexture = textureCache->getTexture(_skyboxTextureURL, image::TextureUsage::CUBE_TEXTURE); - } - if (_skyboxTexture && _skyboxTexture->isLoaded()) { - _pendingSkyboxTexture = false; - - auto texture = _skyboxTexture->getGPUTexture(); - if (texture) { - // skybox->setCubemap(texture); - if (!isAmbientSet) { - // sceneKeyLight->setAmbientSphere(texture->getIrradiance()); - // sceneKeyLight->setAmbientMap(texture); - isAmbientSet = true; - } - } else { - qCDebug(entitiesrenderer) << "Failed to load skybox texture:" << _skyboxTexture->getURL(); - } - } else { - // skybox->setCubemap(nullptr); - } - - if (!isAmbientSet) { - // sceneKeyLight->resetAmbientSphere(); - // sceneKeyLight->setAmbientMap(nullptr); - } - -} - void RenderableZoneEntityItem::render(RenderArgs* args) { Q_ASSERT(getType() == EntityTypes::Zone); @@ -252,15 +263,6 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { sceneTime->setHour(this->getStageProperties().calculateHour()); sceneTime->setDay(this->getStageProperties().calculateDay()); } - - // Set the ambient texture - _ambientTextureURL = this->getKeyLightProperties().getAmbientURL(); - if (_ambientTextureURL.isEmpty()) { - _pendingAmbientTexture = false; - _ambientTexture.clear(); - } else { - _pendingAmbientTexture = true; - } }*/ } @@ -277,39 +279,143 @@ bool RenderableZoneEntityItem::contains(const glm::vec3& point) const { return false; } -class RenderableZoneEntityItemMeta { -public: - RenderableZoneEntityItemMeta(EntityItemPointer entity) : entity(entity), _light(std::make_shared()) { } - ~RenderableZoneEntityItemMeta(); - typedef render::Payload Payload; - typedef Payload::DataPointer Pointer; - - EntityItemPointer entity; +bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render::ScenePointer& scene, + render::Transaction& transaction) { + _myMetaItem = scene->allocateID(); + + auto renderData = std::make_shared(self); + auto renderPayload = std::make_shared(renderData); + updateKeyZoneItemFromEntity((*renderData)); + + render::Item::Status::Getters statusGetters; + makeEntityItemStatusGetters(getThisPointer(), statusGetters); + renderPayload->addStatusGetters(statusGetters); + + transaction.resetItem(_myMetaItem, renderPayload); + + return true; +} + +void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, + render::Transaction& transaction) { + transaction.removeItem(_myMetaItem); + render::Item::clearID(_myMetaItem); + if (_model) { + _model->removeFromScene(scene, transaction); + } +} + +void RenderableZoneEntityItem::notifyBoundChanged() { + if (!render::Item::isValidID(_myMetaItem)) { + return; + } + render::Transaction transaction; + render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); + if (scene) { + transaction.updateItem(_myMetaItem, [](RenderableZoneEntityItemMeta& data) {}); + scene->enqueueTransaction(transaction); + } else { + qCWarning(entitiesrenderer) << "RenderableZoneEntityItem::notifyBoundChanged(), Unexpected null scene, possibly during application shutdown"; + } +} + +void RenderableZoneEntityItem::updateKeySunFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) { + auto sunLight = keyZonePayload.editSunLight(); + sunLight->setType(model::Light::SUN); + + sunLight->setPosition(this->getPosition()); + sunLight->setOrientation(this->getRotation()); + + // Set the keylight + sunLight->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor())); + sunLight->setIntensity(this->getKeyLightProperties().getIntensity()); + sunLight->setDirection(this->getKeyLightProperties().getDirection()); +} + +void RenderableZoneEntityItem::updateKeyAmbientFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) { + auto ambientLight = keyZonePayload.editAmbientLight(); + ambientLight->setType(model::Light::AMBIENT); + + ambientLight->setPosition(this->getPosition()); + ambientLight->setOrientation(this->getRotation()); + + + // Set the keylight + ambientLight->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor())); + ambientLight->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity()); + // ambientLight->setIntensity(this->getKeyLightProperties().getIntensity()); + ambientLight->setDirection(this->getKeyLightProperties().getDirection()); + + if (this->getKeyLightProperties().getAmbientURL().isEmpty()) { + keyZonePayload.setAmbientURL(this->getSkyboxProperties().getURL()); + } else { + keyZonePayload.setAmbientURL(this->getKeyLightProperties().getAmbientURL()); + } + +} + +void RenderableZoneEntityItem::updateKeyBackgroundFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) { + auto skybox = keyZonePayload.editSkybox(); + + this->getBackgroundMode(); + + keyZonePayload.setSkyboxURL(this->getSkyboxProperties().getURL()); +} + + +void RenderableZoneEntityItem::updateKeyZoneItemFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) { + + keyZonePayload.setVisible(this->getVisible()); + + bool success; + keyZonePayload.editBound() = this->getAABox(success); + if (!success) { + keyZonePayload.editBound() = render::Item::Bound(); + } + + updateKeySunFromEntity(keyZonePayload); + + updateKeyAmbientFromEntity(keyZonePayload); + + updateKeyBackgroundFromEntity(keyZonePayload); +} + + +void RenderableZoneEntityItem::sceneUpdateRenderItemFromEntity(render::Transaction& transaction) { + if (!render::Item::isValidID(_myMetaItem)) { + return; + } + + transaction.updateItem(_myMetaItem, [&](RenderableZoneEntityItemMeta& data) { + updateKeyZoneItemFromEntity(data); + }); +} + +void RenderableZoneEntityItem::notifyChangedRenderItem() { + if (!render::Item::isValidID(_myMetaItem)) { + return; + } + + render::Transaction transaction; + render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); + sceneUpdateRenderItemFromEntity(transaction); + scene->enqueueTransaction(transaction); +} + + - void render(RenderArgs* args); - model::LightPointer editLight() { _needUpdate = true; return _light; } - render::Item::Bound& editBound() { _needUpdate = true; return _bound; } - void setVisible(bool visible) { _isVisible = visible; } - bool isVisible() const { return _isVisible; } - model::LightPointer _light; - render::Item::Bound _bound; - LightStagePointer _stage; - LightStage::Index _index { LightStage::INVALID_INDEX }; - bool _needUpdate { true }; - bool _isVisible { true }; -}; namespace render { template <> const ItemKey payloadGetKey(const RenderableZoneEntityItemMeta::Pointer& payload) { return ItemKey::Builder().withTypeMeta().build(); } - + template <> const Item::Bound payloadGetBound(const RenderableZoneEntityItemMeta::Pointer& payload) { if (payload && payload->entity) { bool success; @@ -326,142 +432,151 @@ namespace render { } } -bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render::ScenePointer& scene, - render::Transaction& transaction) { - _myMetaItem = scene->allocateID(); - - auto renderData = std::make_shared(self); - auto renderPayload = std::make_shared(renderData); - updateKeyZoneItemFromEntity((*renderData)); +RenderableZoneEntityItemMeta::RenderableZoneEntityItemMeta(EntityItemPointer entity) : + entity(entity), + _sunLight(std::make_shared()), + _ambientLight(std::make_shared()), + _skybox(std::make_shared()) +{} - render::Item::Status::Getters statusGetters; - makeEntityItemStatusGetters(getThisPointer(), statusGetters); - renderPayload->addStatusGetters(statusGetters); - - transaction.resetItem(_myMetaItem, renderPayload); - - - /* _myKeyLightItem = scene->allocateID(); - - auto keyLightPayload = std::make_shared(); - updateKeyLightItemFromEntity((*keyLightPayload)); - - auto keyLightItem = std::make_shared(keyLightPayload); - - transaction.resetItem(_myKeyLightItem, keyLightItem); - -*/ - return true; -} - -void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, - render::Transaction& transaction) { - // transaction.removeItem(_myKeyLightItem); - // render::Item::clearID(_myKeyLightItem); - transaction.removeItem(_myMetaItem); - render::Item::clearID(_myMetaItem); - if (_model) { - _model->removeFromScene(scene, transaction); - } -} - - - -void RenderableZoneEntityItem::notifyBoundChanged() { - if (!render::Item::isValidID(_myMetaItem)) { - return; - } - render::Transaction transaction; - render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); - if (scene) { - transaction.updateItem(_myMetaItem, [](RenderableZoneEntityItemMeta& data) {}); - // transaction.updateItem(_myKeyLightItem, [](KeyLightPayload& data) {}); - - scene->enqueueTransaction(transaction); - } else { - qCWarning(entitiesrenderer) << "RenderableZoneEntityItem::notifyBoundChanged(), Unexpected null scene, possibly during application shutdown"; - } -} - - -void RenderableZoneEntityItem::updateKeyZoneItemFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) { - auto entity = this; - - keyZonePayload.setVisible(entity->getVisible()); - - auto light = keyZonePayload.editLight(); - light->setPosition(entity->getPosition()); - light->setOrientation(entity->getRotation()); - - bool success; - keyZonePayload.editBound() = entity->getAABox(success); - if (!success) { - keyZonePayload.editBound() = render::Item::Bound(); - } - - // Set the keylight - light->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor())); - light->setIntensity(this->getKeyLightProperties().getIntensity()); - light->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity()); - light->setDirection(this->getKeyLightProperties().getDirection()); - - light->setType(model::Light::SUN); - - -} - -void RenderableZoneEntityItem::updateKeyLightItemFromEntity(KeyLightPayload& keylightPayload) { -} - - -void RenderableZoneEntityItem::sceneUpdateRenderItemFromEntity(render::Transaction& transaction) { - if (!render::Item::isValidID(_myMetaItem)) { - return; - } - - transaction.updateItem(_myMetaItem, [&](KeyLightPayload& data) { - updateKeyLightItemFromEntity(data); - }); -} - -void RenderableZoneEntityItem::notifyChangedRenderItem() { - if (!render::Item::isValidID(_myMetaItem)) { - return; - } - - render::Transaction transaction; - render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); - sceneUpdateRenderItemFromEntity(transaction); - scene->enqueueTransaction(transaction); -} RenderableZoneEntityItemMeta::~RenderableZoneEntityItemMeta() { - if (!LightStage::isIndexInvalid(_index)) { - if (_stage) { - _stage->removeLight(_index); + if (_stage) { + if (!LightStage::isIndexInvalid(_sunIndex)) { + _stage->removeLight(_sunIndex); + } + if (!LightStage::isIndexInvalid(_ambientIndex)) { + _stage->removeLight(_ambientIndex); + } } } -void RenderableZoneEntityItemMeta::render(RenderArgs* args) { - entity->render(args); +void RenderableZoneEntityItemMeta::setAmbientURL(const QString& ambientUrl) { + // nothing change if nothing change + if (_ambientTextureURL == ambientUrl) { + return; + } + _ambientTextureURL = ambientUrl; + if (_ambientTextureURL.isEmpty()) { + _validAmbientTexture = false; + _pendingAmbientTexture = false; + _ambientTexture.clear(); + + _ambientLight->setAmbientMap(nullptr); + _ambientLight->setAmbientSpherePreset(gpu::SphericalHarmonics::BREEZEWAY); + } else { + _pendingAmbientTexture = true; + auto textureCache = DependencyManager::get(); + _ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::CUBE_TEXTURE); + + // keep whatever is assigned on the ambient map/sphere until texture is loaded + } +} + +void RenderableZoneEntityItemMeta::updateAmbientMap() { + if (_pendingAmbientTexture) { + if (_ambientTexture && _ambientTexture->isLoaded()) { + _pendingAmbientTexture = false; + + auto texture = _ambientTexture->getGPUTexture(); + if (texture) { + if (texture->getIrradiance()) { + _ambientLight->setAmbientSphere(*texture->getIrradiance()); + } else { + _ambientLight->setAmbientSpherePreset(gpu::SphericalHarmonics::BREEZEWAY); + } + editAmbientLight()->setAmbientMap(texture); + _validAmbientTexture = true; + } else { + qCDebug(entitiesrenderer) << "Failed to load ambient texture:" << _ambientTexture->getURL(); + } + } + } +} + + +void RenderableZoneEntityItemMeta::setSkyboxURL(const QString& skyboxUrl) { + // nothing change if nothing change + if (_skyboxTextureURL == skyboxUrl) { + return; + } + _skyboxTextureURL = skyboxUrl; + + if (_skyboxTextureURL.isEmpty()) { + _validSkyboxTexture = false; + _pendingSkyboxTexture = false; + _skyboxTexture.clear(); + + editSkybox()->setCubemap(nullptr); + } else { + _pendingSkyboxTexture = true; + auto textureCache = DependencyManager::get(); + _skyboxTexture = textureCache->getTexture(_skyboxTextureURL, image::TextureUsage::CUBE_TEXTURE); + } +} + +void RenderableZoneEntityItemMeta::updateSkyboxMap() { + if (_pendingSkyboxTexture) { + if (_skyboxTexture && _skyboxTexture->isLoaded()) { + _pendingSkyboxTexture = false; + + auto texture = _skyboxTexture->getGPUTexture(); + if (texture) { + editSkybox()->setCubemap(texture); + _validSkyboxTexture = true; + } else { + qCDebug(entitiesrenderer) << "Failed to load Skybox texture:" << _skyboxTexture->getURL(); + } + } + } +} + + +void RenderableZoneEntityItemMeta::render(RenderArgs* args) { + // entity->render(args); + if (!_stage) { _stage = DependencyManager::get()->getLightStage(); } - // Do we need to allocate the light in the stage ? - if (LightStage::isIndexInvalid(_index)) { - _index = _stage->addLight(_light); - _needUpdate = false; + + { // Sun + // Need an update ? + if (_needSunUpdate) { + // Do we need to allocate the light in the stage ? + if (LightStage::isIndexInvalid(_sunIndex)) { + _sunIndex = _stage->addLight(_sunLight); + } else { + _stage->updateLightArrayBuffer(_sunIndex); + } + _needSunUpdate = false; + } } - // Need an update ? - if (_needUpdate) { - _stage->updateLightArrayBuffer(_index); - _needUpdate = false; + + { // Ambient + updateAmbientMap(); + + // Need an update ? + if (_needAmbientUpdate) { + // Do we need to allocate the light in the stage ? + if (LightStage::isIndexInvalid(_ambientIndex)) { + _ambientIndex = _stage->addLight(_ambientLight); + } else { + _stage->updateLightArrayBuffer(_ambientIndex); + } + _needAmbientUpdate = false; + } + } + + { // Skybox + updateSkyboxMap(); + } if (isVisible()) { // FInally, push the light visible in the frame - _stage->_currentFrame.pushLight(_index, _light->getType()); + _stage->_currentFrame.pushSunLight(_sunIndex); + _stage->_currentFrame.pushAmbientLight(_ambientIndex); } } diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index 79641682cf..6f19f88bed 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -54,8 +54,6 @@ private: Model* getModel(); void initialSimulation(); void updateGeometry(); - - void updateTextures(); template void changeProperties(Lambda functor); @@ -63,25 +61,15 @@ private: void notifyChangedRenderItem(); void sceneUpdateRenderItemFromEntity(render::Transaction& transaction); void updateKeyZoneItemFromEntity(RenderableZoneEntityItemMeta& keyZonePayload); - void updateKeyLightItemFromEntity(KeyLightPayload& keyLightPayload); + + void updateKeySunFromEntity(RenderableZoneEntityItemMeta& keyZonePayload); + void updateKeyAmbientFromEntity(RenderableZoneEntityItemMeta& keyZonePayload); + void updateKeyBackgroundFromEntity(RenderableZoneEntityItemMeta& keyZonePayload); Model* _model; bool _needsInitialSimulation; render::ItemID _myMetaItem{ render::Item::INVALID_ITEM_ID }; - - render::ItemID _myKeyLightItem { render::Item::INVALID_ITEM_ID }; - - - // More attributes used for rendering: - NetworkTexturePointer _ambientTexture; - NetworkTexturePointer _skyboxTexture; - QString _ambientTextureURL; - QString _skyboxTextureURL; - bool _pendingAmbientTexture { false }; - bool _pendingSkyboxTexture { false }; - bool _validAmbientTextureURL { false }; - bool _validSkyboxTextureURL { false }; }; #endif // hifi_RenderableZoneEntityItem_h diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index c772374f42..ee242bfdf2 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -68,7 +68,8 @@ public: enum Type { - SUN = 0, + AMBIENT = 0, + SUN, POINT, SPOT, @@ -112,7 +113,7 @@ public: void setIntensity(float intensity); bool isRanged() const { return (getType() == POINT) || (getType() == SPOT); } - bool hasAmbient() const { return (getType() == SUN); } + bool hasAmbient() const { return (getType() == AMBIENT); } // FalloffRradius is the physical radius of the light sphere through which energy shines, // expressed in meters. It is used only to calculate the falloff curve of the light. diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index b7e4b184c0..947d0d502c 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -145,28 +145,33 @@ void DeferredLightingEffect::init() { void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { PerformanceTimer perfTimer("DLE->setupBatch()"); - model::LightPointer keyLight; + model::LightPointer keySunLight; if (_lightStage && _lightStage->_currentFrame._sunLights.size()) { - keyLight = _lightStage->getLight(_lightStage->_currentFrame._sunLights.front()); + keySunLight = _lightStage->getLight(_lightStage->_currentFrame._sunLights.front()); } else { - keyLight = _allocatedLights[_globalLights.front()]; + keySunLight = _allocatedLights[_globalLights.front()]; + } + + model::LightPointer keyAmbiLight; + if (_lightStage && _lightStage->_currentFrame._ambientLights.size()) { + keyAmbiLight = _lightStage->getLight(_lightStage->_currentFrame._ambientLights.front()); + } else { + keyAmbiLight = _allocatedLights[_globalLights.front()]; } if (lightBufferUnit >= 0) { - batch.setUniformBuffer(lightBufferUnit, keyLight->getLightSchemaBuffer()); + batch.setUniformBuffer(lightBufferUnit, keySunLight->getLightSchemaBuffer()); } - if (keyLight->hasAmbient() && (ambientBufferUnit >= 0)) { - batch.setUniformBuffer(ambientBufferUnit, keyLight->getAmbientSchemaBuffer()); + if (keyAmbiLight->hasAmbient() && (ambientBufferUnit >= 0)) { + batch.setUniformBuffer(ambientBufferUnit, keyAmbiLight->getAmbientSchemaBuffer()); } - if (keyLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) { - batch.setResourceTexture(skyboxCubemapUnit, keyLight->getAmbientMap()); + if (keyAmbiLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) { + batch.setResourceTexture(skyboxCubemapUnit, keyAmbiLight->getAmbientMap()); } } void DeferredLightingEffect::unsetKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { - auto keyLight = _allocatedLights[_globalLights.front()]; - if (lightBufferUnit >= 0) { batch.setUniformBuffer(lightBufferUnit, nullptr); } diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index 8da05ec052..01131cac73 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -118,22 +118,25 @@ public: public: Frame() {} - void clear() { _pointLights.clear(); _spotLights.clear(); _sunLights.clear(); } + void clear() { _pointLights.clear(); _spotLights.clear(); _sunLights.clear(); _ambientLights.clear(); } void pushLight(LightStage::Index index, model::Light::Type type) { switch (type) { case model::Light::POINT: { pushPointLight(index); break; } case model::Light::SPOT: { pushSpotLight(index); break; } case model::Light::SUN: { pushSunLight(index); break; } + case model::Light::AMBIENT: { pushAmbientLight(index); break; } default: { break; } } } void pushPointLight(LightStage::Index index) { _pointLights.emplace_back(index); } void pushSpotLight(LightStage::Index index) { _spotLights.emplace_back(index); } void pushSunLight(LightStage::Index index) { _sunLights.emplace_back(index); } + void pushAmbientLight(LightStage::Index index) { _ambientLights.emplace_back(index); } LightStage::LightIndices _pointLights; LightStage::LightIndices _spotLights; LightStage::LightIndices _sunLights; + LightStage::LightIndices _ambientLights; }; Frame _currentFrame; From bc41be7ec1eec7a285d4de51a39fcf9e279620a0 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 9 May 2017 17:10:05 -0700 Subject: [PATCH 07/22] Introucing the BackgroundStage to manage the background / skybox in one place --- .../src/RenderableZoneEntityItem.cpp | 39 ++++- libraries/render-utils/CMakeLists.txt | 2 +- .../render-utils/src/BackgroundStage.cpp | 142 ++++++++++++++++++ libraries/render-utils/src/BackgroundStage.h | 80 ++++++++++ .../src/DeferredLightingEffect.cpp | 13 ++ .../render-utils/src/DeferredLightingEffect.h | 14 ++ .../render-utils/src/RenderDeferredTask.cpp | 7 +- plugins/openvr/CMakeLists.txt | 2 +- tests/render-perf/CMakeLists.txt | 2 +- 9 files changed, 289 insertions(+), 12 deletions(-) create mode 100644 libraries/render-utils/src/BackgroundStage.cpp create mode 100644 libraries/render-utils/src/BackgroundStage.h diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 55d47dde98..074f78ef09 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -26,6 +26,8 @@ #include #include "DeferredLightingEffect.h" +#include + class RenderableZoneEntityItemMeta { public: RenderableZoneEntityItemMeta(EntityItemPointer entity); @@ -45,7 +47,8 @@ public: model::LightPointer editSunLight() { _needSunUpdate = true; return _sunLight; } model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; } - model::SkyboxPointer editSkybox() { _needSkyboxUpdate = true; return _skybox; } + model::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; } + model::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); } void setAmbientURL(const QString& ambientUrl); @@ -56,16 +59,19 @@ protected: model::LightPointer _sunLight; model::LightPointer _ambientLight; - model::SkyboxPointer _skybox; + model::SunSkyStagePointer _background; LightStagePointer _stage; LightStage::Index _sunIndex { LightStage::INVALID_INDEX }; LightStage::Index _ambientIndex { LightStage::INVALID_INDEX }; + BackgroundStagePointer _backgroundStage; + BackgroundStage::Index _backgroundIndex { BackgroundStage::INVALID_INDEX }; + bool _needUpdate { true }; bool _needSunUpdate { true }; bool _needAmbientUpdate { true }; - bool _needSkyboxUpdate { true }; + bool _needBackgroundUpdate { true }; bool _isVisible { true }; @@ -356,7 +362,7 @@ void RenderableZoneEntityItem::updateKeyAmbientFromEntity(RenderableZoneEntityIt } void RenderableZoneEntityItem::updateKeyBackgroundFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) { - auto skybox = keyZonePayload.editSkybox(); + auto background = keyZonePayload.editBackground(); this->getBackgroundMode(); @@ -436,8 +442,10 @@ RenderableZoneEntityItemMeta::RenderableZoneEntityItemMeta(EntityItemPointer ent entity(entity), _sunLight(std::make_shared()), _ambientLight(std::make_shared()), - _skybox(std::make_shared()) -{} + _background(std::make_shared()) +{ + _background->setSkybox(std::make_shared()); +} RenderableZoneEntityItemMeta::~RenderableZoneEntityItemMeta() { @@ -450,6 +458,12 @@ RenderableZoneEntityItemMeta::~RenderableZoneEntityItemMeta() { } } + + if (_backgroundStage) { + if (!BackgroundStage::isIndexInvalid(_backgroundIndex)) { + _backgroundStage->removeBackground(_backgroundIndex); + } + } } void RenderableZoneEntityItemMeta::setAmbientURL(const QString& ambientUrl) { @@ -541,6 +555,10 @@ void RenderableZoneEntityItemMeta::render(RenderArgs* args) { _stage = DependencyManager::get()->getLightStage(); } + if (!_backgroundStage) { + _backgroundStage = DependencyManager::get()->getBackgroundStage(); + } + { // Sun // Need an update ? if (_needSunUpdate) { @@ -572,11 +590,20 @@ void RenderableZoneEntityItemMeta::render(RenderArgs* args) { { // Skybox updateSkyboxMap(); + if (_needBackgroundUpdate) { + if (BackgroundStage::isIndexInvalid(_backgroundIndex)) { + _backgroundIndex = _backgroundStage->addBackground(_background); + } else { + + } + _needBackgroundUpdate = false; + } } if (isVisible()) { // FInally, push the light visible in the frame _stage->_currentFrame.pushSunLight(_sunIndex); _stage->_currentFrame.pushAmbientLight(_ambientIndex); + _backgroundStage->_currentFrame.pushBackground(_backgroundIndex); } } diff --git a/libraries/render-utils/CMakeLists.txt b/libraries/render-utils/CMakeLists.txt index 454097233a..c359924e0d 100644 --- a/libraries/render-utils/CMakeLists.txt +++ b/libraries/render-utils/CMakeLists.txt @@ -3,7 +3,7 @@ AUTOSCRIBE_SHADER_LIB(gpu model render) # pull in the resources.qrc file qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc") setup_hifi_library(Widgets OpenGL Network Qml Quick Script) -link_hifi_libraries(shared ktx gpu model model-networking render animation fbx entities image) +link_hifi_libraries(shared ktx gpu model model-networking render animation fbx entities image procedural) if (NOT ANDROID) target_nsight() diff --git a/libraries/render-utils/src/BackgroundStage.cpp b/libraries/render-utils/src/BackgroundStage.cpp new file mode 100644 index 0000000000..b25f5effd8 --- /dev/null +++ b/libraries/render-utils/src/BackgroundStage.cpp @@ -0,0 +1,142 @@ +// +// BackgroundStage.cpp +// +// Created by Sam Gateau on 5/9/2017. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "BackgroundStage.h" + +#include "DeferredLightingEffect.h" + +#include + +BackgroundStage::Index BackgroundStage::findBackground(const BackgroundPointer& background) const { + auto found = _backgroundMap.find(background); + if (found != _backgroundMap.end()) { + return INVALID_INDEX; + } else { + return (*found).second; + } + +} + +BackgroundStage::Index BackgroundStage::addBackground(const BackgroundPointer& background) { + + auto found = _backgroundMap.find(background); + if (found == _backgroundMap.end()) { + auto backgroundId = _backgrounds.newElement(background); + // Avoid failing to allocate a background, just pass + if (backgroundId != INVALID_INDEX) { + + // Insert the background and its index in the reverse map + _backgroundMap.insert(BackgroundMap::value_type(background, backgroundId)); + } + return backgroundId; + } else { + return (*found).second; + } +} + + +BackgroundStage::BackgroundPointer BackgroundStage::removeBackground(Index index) { + BackgroundPointer removed = _backgrounds.freeElement(index); + + if (removed) { + _backgroundMap.erase(removed); + } + return removed; +} + + +void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { + + const auto& lightingModel = inputs; + if (!lightingModel->isBackgroundEnabled()) { + return; + } + + + // Background rendering decision + auto backgroundStage = DependencyManager::get()->getBackgroundStage(); + model::SunSkyStagePointer background; + model::SkyboxPointer skybox; + if (backgroundStage->_currentFrame._backgrounds.size()) { + auto backgroundId = backgroundStage->_currentFrame._backgrounds.front(); + auto background = backgroundStage->getBackground(backgroundId); + if (background) { + skybox = background->getSkybox(); + } + } else { + skybox = DependencyManager::get()->getDefaultSkybox(); + } + + /* auto backgroundMode = skyStage->getBackgroundMode(); + + switch (backgroundMode) { + case model::SunSkyStage::SKY_DEFAULT: { + auto scene = DependencyManager::get()->getStage(); + auto sceneKeyLight = scene->getKeyLight(); + + scene->setSunModelEnable(false); + sceneKeyLight->setColor(ColorUtils::toVec3(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR)); + sceneKeyLight->setIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY); + sceneKeyLight->setAmbientIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY); + sceneKeyLight->setDirection(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION); + // fall through: render a skybox (if available), or the defaults (if requested) + } + + case model::SunSkyStage::SKY_BOX: {*/ + if (skybox && !skybox->empty()) { + PerformanceTimer perfTimer("skybox"); + auto args = renderContext->args; + + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + + batch.enableSkybox(true); + + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + glm::mat4 projMat; + Transform viewMat; + args->getViewFrustum().evalProjectionMatrix(projMat); + args->getViewFrustum().evalViewTransform(viewMat); + + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + + skybox->render(batch, args->getViewFrustum()); + }); + args->_batch = nullptr; + gpu::Batch& batch = *args->_batch; + + // break; + } + // fall through: render defaults (if requested) +// } +/* + case model::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: { + if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { + auto scene = DependencyManager::get()->getStage(); + auto sceneKeyLight = scene->getKeyLight(); + auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture(); + if (defaultSkyboxAmbientTexture) { + sceneKeyLight->setAmbientSphere(defaultSkyboxAmbientTexture->getIrradiance()); + sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture); + } else { + static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex( + "Failed to get a valid Default Skybox Ambient Texture ? probably because it couldn't be find during initialization step"); + } + // fall through: render defaults skybox + } else { + break; + } + } + + + backgroundStage->_currentFrame.clear(); +} \ No newline at end of file diff --git a/libraries/render-utils/src/BackgroundStage.h b/libraries/render-utils/src/BackgroundStage.h new file mode 100644 index 0000000000..1dd1651c98 --- /dev/null +++ b/libraries/render-utils/src/BackgroundStage.h @@ -0,0 +1,80 @@ +// +// BackgroundStage.h + +// Created by Sam Gateau on 5/9/2017. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_render_utils_BackgroundStage_h +#define hifi_render_utils_BackgroundStage_h + +#include +#include +#include +#include + +#include "LightingModel.h" + + +// Background stage to set up background-related rendering tasks +class BackgroundStage { +public: + using Index = render::indexed_container::Index; + static const Index INVALID_INDEX { render::indexed_container::INVALID_INDEX }; + static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; } + + using BackgroundPointer = model::SunSkyStagePointer; + using Backgrounds = render::indexed_container::IndexedPointerVector; + using BackgroundMap = std::unordered_map; + + using BackgroundIndices = std::vector; + + + Index findBackground(const BackgroundPointer& background) const; + Index addBackground(const BackgroundPointer& background); + + BackgroundPointer removeBackground(Index index); + + bool checkBackgroundId(Index index) const { return _backgrounds.checkIndex(index); } + + Index getNumBackgrounds() const { return _backgrounds.getNumElements(); } + Index getNumFreeBackgrounds() const { return _backgrounds.getNumFreeIndices(); } + Index getNumAllocatedBackgrounds() const { return _backgrounds.getNumAllocatedIndices(); } + + BackgroundPointer getBackground(Index backgroundId) const { + return _backgrounds.get(backgroundId); + } + + Backgrounds _backgrounds; + BackgroundMap _backgroundMap; + + class Frame { + public: + Frame() {} + + void clear() { _backgrounds.clear(); } + + void pushBackground(BackgroundStage::Index index) { _backgrounds.emplace_back(index); } + + BackgroundStage::BackgroundIndices _backgrounds; + }; + + Frame _currentFrame; +}; +using BackgroundStagePointer = std::shared_ptr; + + +class DrawBackgroundStage { +public: + using Inputs = LightingModelPointer; + using JobModel = render::Job::ModelI; + + void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); + +protected: +}; + +#endif diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 947d0d502c..96f92758ea 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -141,6 +141,19 @@ void DeferredLightingEffect::init() { _globalLights.push_back(_lightStage->addLight(lp)); _lightStage->addShadow(_globalLights[0]); + + _backgroundStage = std::make_shared(); + + auto textureCache = DependencyManager::get(); + + QString skyboxUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-cubemap.jpg" }; + QString skyboxAmbientUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-ambient.jpg" }; + + _defaultSkyboxTexture = textureCache->getImageTexture(skyboxUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", false } }); + _defaultSkyboxAmbientTexture = textureCache->getImageTexture(skyboxAmbientUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", true } }); + + _defaultSkybox->setCubemap(_defaultSkyboxTexture); + } void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 02f759bab3..63895c2ec9 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -20,6 +20,8 @@ #include "model/Light.h" #include "model/Geometry.h" +#include + #include #include "DeferredFrameTransform.h" @@ -28,11 +30,13 @@ #include "LightStage.h" #include "LightClusters.h" +#include "BackgroundEffect.h" #include "SurfaceGeometryPass.h" #include "SubsurfaceScattering.h" #include "AmbientOcclusionEffect.h" + class RenderArgs; struct LightLocations; using LightLocationsPtr = std::shared_ptr; @@ -51,15 +55,21 @@ public: void setGlobalLight(const model::LightPointer& light); const LightStagePointer& getLightStage() { return _lightStage; } + const BackgroundStagePointer& getBackgroundStage() { return _backgroundStage; } void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; }; void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; } bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; } + model::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; } + gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; } + gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; } + private: DeferredLightingEffect() = default; LightStagePointer _lightStage; + BackgroundStagePointer _backgroundStage; bool _shadowMapEnabled{ false }; bool _ambientOcclusionEnabled{ false }; @@ -103,6 +113,10 @@ private: Lights _allocatedLights; std::vector _globalLights; + model::SkyboxPointer _defaultSkybox { new ProceduralSkybox() }; + gpu::TexturePointer _defaultSkyboxTexture; + gpu::TexturePointer _defaultSkyboxAmbientTexture; + friend class LightClusteringPass; friend class RenderDeferredSetup; friend class RenderDeferredLocals; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 693c150004..4264cfb424 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -139,9 +139,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("RenderDeferred", deferredLightingInputs); // Use Stencil and draw background in Lighting buffer to complete filling in the opaque - const auto backgroundInputs = DrawBackgroundDeferred::Inputs(background, lightingModel).hasVarying(); - task.addJob("DrawBackgroundDeferred", backgroundInputs); - + //const auto backgroundInputs = DrawBackgroundDeferred::Inputs(background, lightingModel).hasVarying(); + //task.addJob("DrawBackgroundDeferred", backgroundInputs); + + task.addJob("DrawBackgroundDeferred", lightingModel); // Render transparent objects forward in LightingBuffer const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).hasVarying(); diff --git a/plugins/openvr/CMakeLists.txt b/plugins/openvr/CMakeLists.txt index bc62117e70..af65f3dbf7 100644 --- a/plugins/openvr/CMakeLists.txt +++ b/plugins/openvr/CMakeLists.txt @@ -13,7 +13,7 @@ if (WIN32) setup_hifi_plugin(OpenGL Script Qml Widgets) link_hifi_libraries(shared gl networking controllers ui plugins display-plugins ui-plugins input-plugins script-engine - render-utils model gpu gpu-gl render model-networking fbx ktx image) + render-utils model gpu gpu-gl render model-networking fbx ktx image procedural) include_hifi_library_headers(octree) diff --git a/tests/render-perf/CMakeLists.txt b/tests/render-perf/CMakeLists.txt index 1e85dd3ea8..553e7c06e7 100644 --- a/tests/render-perf/CMakeLists.txt +++ b/tests/render-perf/CMakeLists.txt @@ -10,7 +10,7 @@ setup_hifi_project(Quick Gui OpenGL) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries -link_hifi_libraries(shared octree ktx gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics image) +link_hifi_libraries(shared octree ktx gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics image procedural) package_libraries_for_deployment() From 75facdfa88a1a8f3631929160bf3c99baa4eb8a9 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 9 May 2017 17:31:18 -0700 Subject: [PATCH 08/22] Testing the new behavior with the BackgroundStage, --- libraries/render-utils/src/BackgroundStage.cpp | 2 +- libraries/render-utils/src/DeferredLightingEffect.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/BackgroundStage.cpp b/libraries/render-utils/src/BackgroundStage.cpp index b25f5effd8..f3ccfa6485 100644 --- a/libraries/render-utils/src/BackgroundStage.cpp +++ b/libraries/render-utils/src/BackgroundStage.cpp @@ -136,7 +136,7 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, break; } } - + */ backgroundStage->_currentFrame.clear(); } \ No newline at end of file diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 63895c2ec9..3a1e7d2b4b 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -30,7 +30,7 @@ #include "LightStage.h" #include "LightClusters.h" -#include "BackgroundEffect.h" +#include "BackgroundStage.h" #include "SurfaceGeometryPass.h" #include "SubsurfaceScattering.h" From 8626e1f3d15d0e32881e25460f52ef2532d43b17 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 15 May 2017 17:19:46 -0700 Subject: [PATCH 09/22] Keep fixing the cascading behavior to the zone render item --- .../src/RenderableZoneEntityItem.cpp | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 074f78ef09..681a047e6c 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -54,12 +54,17 @@ public: void setSkyboxURL(const QString& skyboxUrl); + void setBackgroundMode(BackgroundMode mode); + void setSkyboxColor(const glm::vec3& color); + void setProceduralUserData(QString userData); + protected: render::Item::Bound _bound; model::LightPointer _sunLight; model::LightPointer _ambientLight; model::SunSkyStagePointer _background; + BackgroundMode _backgroundMode { BACKGROUND_MODE_INHERIT }; LightStagePointer _stage; LightStage::Index _sunIndex { LightStage::INVALID_INDEX }; @@ -89,6 +94,7 @@ protected: bool _pendingSkyboxTexture { false }; bool _validSkyboxTexture { false }; + QString _proceduralUserData; }; // Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1 @@ -364,8 +370,9 @@ void RenderableZoneEntityItem::updateKeyAmbientFromEntity(RenderableZoneEntityIt void RenderableZoneEntityItem::updateKeyBackgroundFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) { auto background = keyZonePayload.editBackground(); - this->getBackgroundMode(); - + keyZonePayload.setBackgroundMode(this->getBackgroundMode()); + keyZonePayload.setSkyboxColor(this->getSkyboxProperties().getColorVec3()); + keyZonePayload.setProceduralUserData(this->getUserData()); keyZonePayload.setSkyboxURL(this->getSkyboxProperties().getURL()); } @@ -547,6 +554,22 @@ void RenderableZoneEntityItemMeta::updateSkyboxMap() { } } +void RenderableZoneEntityItemMeta::setBackgroundMode(BackgroundMode mode) { + _backgroundMode = mode; +} + +void RenderableZoneEntityItemMeta::setSkyboxColor(const glm::vec3& color) { + editSkybox()->setColor(color); +} + +void RenderableZoneEntityItemMeta::setProceduralUserData(QString userData) { + if (_proceduralUserData != userData) { + _proceduralUserData = userData; + std::dynamic_pointer_cast(editSkybox())->parse(_proceduralUserData); + } +} + + void RenderableZoneEntityItemMeta::render(RenderArgs* args) { // entity->render(args); @@ -602,8 +625,17 @@ void RenderableZoneEntityItemMeta::render(RenderArgs* args) { if (isVisible()) { // FInally, push the light visible in the frame + // THe directional key light for sure _stage->_currentFrame.pushSunLight(_sunIndex); - _stage->_currentFrame.pushAmbientLight(_ambientIndex); - _backgroundStage->_currentFrame.pushBackground(_backgroundIndex); + + // The ambient light only if it has a valid texture to render with + if (_validAmbientTexture || _validSkyboxTexture) { + _stage->_currentFrame.pushAmbientLight(_ambientIndex); + } + + // The background only if the mode is not inherit + if (_backgroundMode != BACKGROUND_MODE_INHERIT) { + _backgroundStage->_currentFrame.pushBackground(_backgroundIndex); + } } } From db4387e55dca030642cb8c11cca82be7e703be2a Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 15 May 2017 17:31:29 -0700 Subject: [PATCH 10/22] Trying to mess with the defautl texture for skybox --- .../entities-renderer/src/RenderableZoneEntityItem.cpp | 2 -- libraries/render-utils/src/DeferredLightingEffect.cpp | 10 ++++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 681a047e6c..92682d46df 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -572,8 +572,6 @@ void RenderableZoneEntityItemMeta::setProceduralUserData(QString userData) { void RenderableZoneEntityItemMeta::render(RenderArgs* args) { - // entity->render(args); - if (!_stage) { _stage = DependencyManager::get()->getLightStage(); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 96f92758ea..71d60df2ae 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -146,14 +146,16 @@ void DeferredLightingEffect::init() { auto textureCache = DependencyManager::get(); - QString skyboxUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-cubemap.jpg" }; - QString skyboxAmbientUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-ambient.jpg" }; + QString skyboxUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-cubemap.ktx" }; +// QString skyboxAmbientUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-cubemap.ktx" }; - _defaultSkyboxTexture = textureCache->getImageTexture(skyboxUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", false } }); - _defaultSkyboxAmbientTexture = textureCache->getImageTexture(skyboxAmbientUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", true } }); + _defaultSkyboxTexture = _defaultSkyboxAmbientTexture = textureCache->getImageTexture(skyboxUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", false } }); + // _defaultSkyboxAmbientTexture = textureCache->getImageTexture(skyboxAmbientUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", true } }); _defaultSkybox->setCubemap(_defaultSkyboxTexture); + lp->setAmbientMap(_defaultSkyboxTexture); + } void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { From 4c3ddfbff9e9b7a9efd75498b4555424746579a5 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Tue, 16 May 2017 01:01:19 -0700 Subject: [PATCH 11/22] Adding debuging of the ambient lighting --- .../render-utils/src/RenderDeferredTask.cpp | 2 + libraries/render-utils/src/ZoneRenderer.cpp | 81 +++++++++++++++++++ libraries/render-utils/src/ZoneRenderer.h | 20 +++++ .../render-utils/src/zone_drawAmbient.slf | 39 +++++++++ 4 files changed, 142 insertions(+) create mode 100644 libraries/render-utils/src/zone_drawAmbient.slf diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 4264cfb424..492875a4ac 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -206,6 +206,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren auto statusIconMap = DependencyManager::get()->getImageTexture(iconMapPath, image::TextureUsage::STRICT_TEXTURE); task.addJob("DrawStatus", opaques, DrawStatus(statusIconMap)); } + + task.addJob("DebugZoneLighting"); } diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 00b4565edf..e7bcda2036 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -10,9 +10,18 @@ // #include "ZoneRenderer.h" + +#include +#include + #include #include +#include "DeferredLightingEffect.h" + +#include "zone_drawAmbient_frag.h" + + using namespace render; class SetupZones { @@ -45,3 +54,75 @@ void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) render::renderItems(context, inputs); } + +const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { + if (!_keyLightPipeline) { + } + return _keyLightPipeline; +} + +const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() { + if (!_ambientPipeline) { + auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); + auto ps = gpu::Shader::createPixel(std::string(zone_drawAmbient_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + //slotBindings.insert(gpu::Shader::Binding(std::string("blurParamsBuffer"), BlurTask_ParamsSlot)); + //slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), BlurTask_SourceSlot)); + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + _ambientPipeline = gpu::Pipeline::create(program, state); + } + return _ambientPipeline; +} +const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { + if (!_backgroundPipeline) { + } + return _backgroundPipeline; +} + +void DebugZoneLighting::run(const render::RenderContextPointer& context) { + RenderArgs* args = context->args; + + auto lightStage = DependencyManager::get()->getLightStage(); + + const auto light = lightStage->getLight(0); + model::LightPointer keyAmbiLight; + if (lightStage && lightStage->_currentFrame._ambientLights.size()) { + keyAmbiLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front()); + } else { + // keyAmbiLight = _allocatedLights[_globalLights.front()]; + } + +/* if (lightBufferUnit >= 0) { + batch.setUniformBuffer(lightBufferUnit, keySunLight->getLightSchemaBuffer()); + }*/ + + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { + + batch.setViewportTransform(args->_viewport); + auto viewFrustum = args->getViewFrustum(); + batch.setProjectionTransform(viewFrustum.getProjection()); + batch.resetViewTransform(); + + Transform model; + model.setTranslation(glm::vec3(0.0, 0.0, -10.0)); + batch.setModelTransform(model); + + batch.setPipeline(getAmbientPipeline()); + if (keyAmbiLight) { + if (keyAmbiLight->hasAmbient()) { + batch.setUniformBuffer(0, keyAmbiLight->getAmbientSchemaBuffer()); + } + + if (keyAmbiLight->getAmbientMap()) { + batch.setResourceTexture(0, keyAmbiLight->getAmbientMap()); + } + } + + batch.draw(gpu::TRIANGLE_STRIP, 4); + + }); +} diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index cbbfbcb84e..1ca34892c9 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -50,4 +50,24 @@ protected: int _maxDrawn; // initialized by Config }; +class DebugZoneLighting { +public: + using JobModel = render::Job::Model; + + DebugZoneLighting() {} + + void run(const render::RenderContextPointer& context); + +protected: + + gpu::PipelinePointer _keyLightPipeline; + gpu::PipelinePointer _ambientPipeline; + gpu::PipelinePointer _backgroundPipeline; + + const gpu::PipelinePointer& getKeyLightPipeline(); + const gpu::PipelinePointer& getAmbientPipeline(); + const gpu::PipelinePointer& getBackgroundPipeline(); +}; + + #endif \ No newline at end of file diff --git a/libraries/render-utils/src/zone_drawAmbient.slf b/libraries/render-utils/src/zone_drawAmbient.slf new file mode 100644 index 0000000000..aff4bcb47f --- /dev/null +++ b/libraries/render-utils/src/zone_drawAmbient.slf @@ -0,0 +1,39 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gateau on 5/16/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include model/Light.slh@> + +<@include LightingModel.slh@> + !> +<$declareLightAmbientBuffer()$> + +<@include LightAmbient.slh@> + !> + +<$declareLightingAmbient(_SCRIBE_NULL, 1, _SCRIBE_NULL, _SCRIBE_NULL)$> + +in vec2 varTexCoord0; +out vec4 _fragColor; + +void main(void) { + + LightAmbient lightAmbient = getLightAmbient(); + + // _fragColor = vec4(varTexCoord0, 0.0, 1.0); + + float z = sqrt( dot(varTexCoord0.xy, varTexCoord0.xy)); + vec3 dir = vec3(varTexCoord0.xy, z); + + vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), dir).xyz; + _fragColor = vec4(ambient, 1.0); +} + + From 2cd2c959407932ee57335856a863027cba15445d Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 16 May 2017 16:12:31 -0700 Subject: [PATCH 12/22] Adding more debugging tool --- .../src/RenderableZoneEntityItem.cpp | 5 +- libraries/model/src/model/Light.h | 1 - .../render-utils/src/BackgroundStage.cpp | 1 - .../src/DeferredLightingEffect.cpp | 29 +++++--- .../render-utils/src/DeferredLightingEffect.h | 1 + libraries/render-utils/src/LightStage.h | 1 - .../render-utils/src/RenderDeferredTask.cpp | 2 +- libraries/render-utils/src/ZoneRenderer.cpp | 68 +++++++++++++++---- libraries/render-utils/src/ZoneRenderer.h | 14 +++- .../render-utils/src/zone_drawAmbient.slf | 44 +++++++++--- .../render-utils/src/zone_drawSkybox.slf | 54 +++++++++++++++ 11 files changed, 178 insertions(+), 42 deletions(-) create mode 100644 libraries/render-utils/src/zone_drawSkybox.slf diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 92682d46df..6758134a7e 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -354,11 +354,8 @@ void RenderableZoneEntityItem::updateKeyAmbientFromEntity(RenderableZoneEntityIt // Set the keylight - ambientLight->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor())); ambientLight->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity()); - // ambientLight->setIntensity(this->getKeyLightProperties().getIntensity()); - ambientLight->setDirection(this->getKeyLightProperties().getDirection()); - + if (this->getKeyLightProperties().getAmbientURL().isEmpty()) { keyZonePayload.setAmbientURL(this->getSkyboxProperties().getURL()); } else { diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index ee242bfdf2..4c82eb5d77 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -113,7 +113,6 @@ public: void setIntensity(float intensity); bool isRanged() const { return (getType() == POINT) || (getType() == SPOT); } - bool hasAmbient() const { return (getType() == AMBIENT); } // FalloffRradius is the physical radius of the light sphere through which energy shines, // expressed in meters. It is used only to calculate the falloff curve of the light. diff --git a/libraries/render-utils/src/BackgroundStage.cpp b/libraries/render-utils/src/BackgroundStage.cpp index f3ccfa6485..1a85a70863 100644 --- a/libraries/render-utils/src/BackgroundStage.cpp +++ b/libraries/render-utils/src/BackgroundStage.cpp @@ -138,5 +138,4 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, } */ - backgroundStage->_currentFrame.clear(); } \ No newline at end of file diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 71d60df2ae..b799a7c49e 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -146,15 +146,21 @@ void DeferredLightingEffect::init() { auto textureCache = DependencyManager::get(); - QString skyboxUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-cubemap.ktx" }; -// QString skyboxAmbientUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-cubemap.ktx" }; + { + PROFILE_RANGE(render, "Process Default Skybox"); + auto textureCache = DependencyManager::get(); - _defaultSkyboxTexture = _defaultSkyboxAmbientTexture = textureCache->getImageTexture(skyboxUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", false } }); - // _defaultSkyboxAmbientTexture = textureCache->getImageTexture(skyboxAmbientUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", true } }); + auto skyboxUrl = PathUtils::resourcesPath().toStdString() + "images/Default-Sky-9-cubemap.ktx"; - _defaultSkybox->setCubemap(_defaultSkyboxTexture); + _defaultSkyboxTexture = gpu::Texture::unserialize(skyboxUrl); + _defaultSkyboxAmbientTexture = _defaultSkyboxTexture; - lp->setAmbientMap(_defaultSkyboxTexture); + _defaultSkybox->setCubemap(_defaultSkyboxTexture); + } + + + lp->setAmbientIntensity(0.5f); + lp->setAmbientMap(_defaultSkyboxAmbientTexture); } @@ -177,7 +183,7 @@ void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBuff if (lightBufferUnit >= 0) { batch.setUniformBuffer(lightBufferUnit, keySunLight->getLightSchemaBuffer()); } - if (keyAmbiLight->hasAmbient() && (ambientBufferUnit >= 0)) { + if (ambientBufferUnit >= 0) { batch.setUniformBuffer(ambientBufferUnit, keyAmbiLight->getAmbientSchemaBuffer()); } @@ -315,15 +321,20 @@ static void loadLightVolumeProgram(const char* vertSource, const char* fragSourc } void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) { - auto globalLight = _allocatedLights.front(); + /* auto globalLight = _allocatedLights.front(); globalLight->setDirection(light->getDirection()); globalLight->setColor(light->getColor()); globalLight->setIntensity(light->getIntensity()); globalLight->setAmbientIntensity(light->getAmbientIntensity()); globalLight->setAmbientSphere(light->getAmbientSphere()); - globalLight->setAmbientMap(light->getAmbientMap()); + globalLight->setAmbientMap(light->getAmbientMap());*/ } +const model::LightPointer& DeferredLightingEffect::getGlobalLight() const { + return _allocatedLights.front(); +} + + #include model::MeshPointer DeferredLightingEffect::getPointLightMesh() { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 3a1e7d2b4b..2f4f9901c3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -53,6 +53,7 @@ public: // update global lighting void setGlobalLight(const model::LightPointer& light); + const model::LightPointer& getGlobalLight() const; const LightStagePointer& getLightStage() { return _lightStage; } const BackgroundStagePointer& getBackgroundStage() { return _backgroundStage; } diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index 01131cac73..edbdff28fd 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -77,7 +77,6 @@ public: }; using Descs = std::vector; - Index findLight(const LightPointer& light) const; Index addLight(const LightPointer& light); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 492875a4ac..21df88d4c4 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -207,7 +207,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawStatus", opaques, DrawStatus(statusIconMap)); } - task.addJob("DebugZoneLighting"); + task.addJob("DebugZoneLighting", deferredFrameTransform); } diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index e7bcda2036..c838954b72 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -20,6 +20,7 @@ #include "DeferredLightingEffect.h" #include "zone_drawAmbient_frag.h" +#include "zone_drawSkybox_frag.h" using namespace render; @@ -50,6 +51,9 @@ void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& oupu void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) { + auto backgroundStage = DependencyManager::get()->getBackgroundStage(); + backgroundStage->_currentFrame.clear(); + // call render in the correct order first... render::renderItems(context, inputs); @@ -68,37 +72,63 @@ const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() { gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); gpu::Shader::BindingSet slotBindings; - //slotBindings.insert(gpu::Shader::Binding(std::string("blurParamsBuffer"), BlurTask_ParamsSlot)); - //slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), BlurTask_SourceSlot)); + slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), ZONE_AMBIENT_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), ZONE_AMBIENT_MAP)); + gpu::Shader::makeProgram(*program, slotBindings); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _ambientPipeline = gpu::Pipeline::create(program, state); } return _ambientPipeline; } const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { if (!_backgroundPipeline) { + auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); + auto ps = gpu::Shader::createPixel(std::string(zone_drawSkybox_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), ZONE_SKYBOX_MAP)); + + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + _backgroundPipeline = gpu::Pipeline::create(program, state); } return _backgroundPipeline; } -void DebugZoneLighting::run(const render::RenderContextPointer& context) { +void DebugZoneLighting::run(const render::RenderContextPointer& context, const Inputs& inputs) { RenderArgs* args = context->args; + auto deferredTransform = inputs; + auto lightStage = DependencyManager::get()->getLightStage(); - const auto light = lightStage->getLight(0); model::LightPointer keyAmbiLight; if (lightStage && lightStage->_currentFrame._ambientLights.size()) { keyAmbiLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front()); } else { - // keyAmbiLight = _allocatedLights[_globalLights.front()]; + keyAmbiLight = DependencyManager::get()->getGlobalLight(); } -/* if (lightBufferUnit >= 0) { - batch.setUniformBuffer(lightBufferUnit, keySunLight->getLightSchemaBuffer()); - }*/ + auto backgroundStage = DependencyManager::get()->getBackgroundStage(); + model::SkyboxPointer skybox; + if (backgroundStage && backgroundStage->_currentFrame._backgrounds.size()) { + auto background = backgroundStage->getBackground(backgroundStage->_currentFrame._backgrounds.front()); + if (background) { + skybox = background->getSkybox(); + } + } else { + skybox = DependencyManager::get()->getDefaultSkybox(); + } gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { @@ -108,21 +138,29 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context) { batch.resetViewTransform(); Transform model; - model.setTranslation(glm::vec3(0.0, 0.0, -10.0)); - batch.setModelTransform(model); + model.setTranslation(glm::vec3(-4.0, 0.0, -10.0)); + + batch.setUniformBuffer(ZONE_DEFERRED_TRANSFORM_BUFFER, deferredTransform->getFrameTransformBuffer()); batch.setPipeline(getAmbientPipeline()); + batch.setModelTransform(model); if (keyAmbiLight) { - if (keyAmbiLight->hasAmbient()) { - batch.setUniformBuffer(0, keyAmbiLight->getAmbientSchemaBuffer()); - } + batch.setUniformBuffer(ZONE_AMBIENT_BUFFER, keyAmbiLight->getAmbientSchemaBuffer()); if (keyAmbiLight->getAmbientMap()) { - batch.setResourceTexture(0, keyAmbiLight->getAmbientMap()); + batch.setResourceTexture(ZONE_AMBIENT_MAP, keyAmbiLight->getAmbientMap()); } } - batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setPipeline(getBackgroundPipeline()); + model.setTranslation(glm::vec3(-4.0, 3.0, -10.0)); + batch.setModelTransform(model); + if (skybox) { + batch.setResourceTexture(ZONE_SKYBOX_MAP, skybox->getCubemap()); + } + batch.draw(gpu::TRIANGLE_STRIP, 4); + + }); } diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index 1ca34892c9..ee3754b7eb 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -14,6 +14,8 @@ #include "render/Engine.h" +#include "DeferredFrameTransform.h" + class ZoneRendererConfig : public render::Task::Config { Q_OBJECT Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty) @@ -52,14 +54,22 @@ protected: class DebugZoneLighting { public: - using JobModel = render::Job::Model; + using Inputs = DeferredFrameTransformPointer; + using JobModel = render::Job::ModelI; DebugZoneLighting() {} - void run(const render::RenderContextPointer& context); + void run(const render::RenderContextPointer& context, const Inputs& inputs); protected: + enum Slots { + ZONE_DEFERRED_TRANSFORM_BUFFER = 0, + ZONE_AMBIENT_BUFFER, + ZONE_AMBIENT_MAP, + ZONE_SKYBOX_MAP, + }; + gpu::PipelinePointer _keyLightPipeline; gpu::PipelinePointer _ambientPipeline; gpu::PipelinePointer _backgroundPipeline; diff --git a/libraries/render-utils/src/zone_drawAmbient.slf b/libraries/render-utils/src/zone_drawAmbient.slf index aff4bcb47f..f14bed5c03 100644 --- a/libraries/render-utils/src/zone_drawAmbient.slf +++ b/libraries/render-utils/src/zone_drawAmbient.slf @@ -9,14 +9,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredTransform.slh@> +<$declareDeferredFrameTransform()$> + <@include model/Light.slh@> <@include LightingModel.slh@> - !> <$declareLightAmbientBuffer()$> <@include LightAmbient.slh@> - !> <$declareLightingAmbient(_SCRIBE_NULL, 1, _SCRIBE_NULL, _SCRIBE_NULL)$> @@ -25,15 +26,42 @@ out vec4 _fragColor; void main(void) { + const float INNER_RADIUS = 1.0; + const float INNER_RADIUS2 = INNER_RADIUS * INNER_RADIUS; + const float OUTER_RADIUS = 1.05; + const float OUTER_RADIUS2 = OUTER_RADIUS * OUTER_RADIUS; + vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUTER_RADIUS; + float sphereR2 = dot(sphereUV.xy, sphereUV.xy); + if (sphereR2 > OUTER_RADIUS * OUTER_RADIUS) { + discard; + } + if (sphereR2 > INNER_RADIUS2) { + float falloff = (sphereR2 - OUTER_RADIUS2) / (OUTER_RADIUS2 - INNER_RADIUS2); + _fragColor = vec4(0.0, 0.0, 0.0, falloff * falloff); + return; + } + vec3 spherePos = normalize(vec3(sphereUV, sqrt(1.0 - sphereR2))); + + + vec3 fragNormal = vec3(getViewInverse() * vec4(spherePos, 0.0)); + + LightAmbient lightAmbient = getLightAmbient(); - - // _fragColor = vec4(varTexCoord0, 0.0, 1.0); - float z = sqrt( dot(varTexCoord0.xy, varTexCoord0.xy)); - vec3 dir = vec3(varTexCoord0.xy, z); - vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), dir).xyz; - _fragColor = vec4(ambient, 1.0); + float roughness = 0.1; + float levels = getLightAmbientMapNumMips(lightAmbient); + float lod = min(((roughness)* levels), levels); + vec3 ambientMap = evalSkyboxLight(fragNormal, lod).xyz; + vec3 ambientSH = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; + + // vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; + // _fragColor = vec4( 0.5 * (fragNormal + vec3(1.0)), 1.0); + + vec3 ambient = (sphereUV.x > 0 ? ambientMap : ambientSH); + + const float INV_GAMMA_22 = 1.0 / 2.2; + _fragColor = vec4(pow(ambient, vec3(INV_GAMMA_22)), 1.0); } diff --git a/libraries/render-utils/src/zone_drawSkybox.slf b/libraries/render-utils/src/zone_drawSkybox.slf new file mode 100644 index 0000000000..77b144379b --- /dev/null +++ b/libraries/render-utils/src/zone_drawSkybox.slf @@ -0,0 +1,54 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gateau on 5/16/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include DeferredTransform.slh@> +<$declareDeferredFrameTransform()$> + +// declareSkyboxMap +uniform samplerCube skyboxMap; + +vec4 evalSkyboxLight(vec3 direction, float lod) { + // textureQueryLevels is not available until #430, so we require explicit lod + // float mipmapLevel = lod * textureQueryLevels(skyboxMap); + return textureLod(skyboxMap, direction, lod); +} + +in vec2 varTexCoord0; +out vec4 _fragColor; + +void main(void) { + + const float INNER_RADIUS = 1.0; + const float INNER_RADIUS2 = INNER_RADIUS * INNER_RADIUS; + const float OUTER_RADIUS = 1.05; + const float OUTER_RADIUS2 = OUTER_RADIUS * OUTER_RADIUS; + vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUTER_RADIUS; + float sphereR2 = dot(sphereUV.xy, sphereUV.xy); + if (sphereR2 > OUTER_RADIUS * OUTER_RADIUS) { + discard; + } + if (sphereR2 > INNER_RADIUS2) { + float falloff = (sphereR2 - OUTER_RADIUS2) / (OUTER_RADIUS2 - INNER_RADIUS2); + _fragColor = vec4(0.0, 0.0, 0.0, falloff * falloff); + return; + } + vec3 spherePos = normalize(vec3(sphereUV, -sqrt(1.0 - sphereR2))); + + vec3 fragNormal = vec3(getViewInverse() * vec4(spherePos, 0.0)); + + float lod = 0; + vec3 ambient = evalSkyboxLight(fragNormal, lod).xyz; + + const float INV_GAMMA_22 = 1.0 / 2.2; + _fragColor = vec4(pow(ambient, vec3(INV_GAMMA_22)), 1.0); +} + + From 79f700e8ce3f5f5a2f9efa7e9916948ab990f489 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 17 May 2017 18:12:48 -0700 Subject: [PATCH 13/22] Adding the drawKeyLight shader --- libraries/render-utils/src/ZoneRenderer.cpp | 38 +++++++++-- libraries/render-utils/src/ZoneRenderer.h | 3 +- .../render-utils/src/zone_drawKeyLight.slf | 66 +++++++++++++++++++ 3 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 libraries/render-utils/src/zone_drawKeyLight.slf diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index c838954b72..620597e76a 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -19,6 +19,7 @@ #include "DeferredLightingEffect.h" +#include "zone_drawKeyLight_frag.h" #include "zone_drawAmbient_frag.h" #include "zone_drawSkybox_frag.h" @@ -61,7 +62,21 @@ void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { if (!_keyLightPipeline) { - } + auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); + auto ps = gpu::Shader::createPixel(std::string(zone_drawSkybox_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("keylightBuffer"), ZONE_KEYLIGHT_BUFFER)); + + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + _keyLightPipeline = gpu::Pipeline::create(program, state); + } return _keyLightPipeline; } @@ -111,7 +126,14 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I auto deferredTransform = inputs; auto lightStage = DependencyManager::get()->getLightStage(); - const auto light = lightStage->getLight(0); + model::LightPointer keyLight; + if (lightStage && lightStage->_currentFrame._sunLights.size()) { + keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front()); + } + else { + keyLight = DependencyManager::get()->getGlobalLight(); + } + model::LightPointer keyAmbiLight; if (lightStage && lightStage->_currentFrame._ambientLights.size()) { keyAmbiLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front()); @@ -138,12 +160,20 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I batch.resetViewTransform(); Transform model; - model.setTranslation(glm::vec3(-4.0, 0.0, -10.0)); batch.setUniformBuffer(ZONE_DEFERRED_TRANSFORM_BUFFER, deferredTransform->getFrameTransformBuffer()); + batch.setPipeline(getKeyLightPipeline()); + model.setTranslation(glm::vec3(-4.0, -3.0, -10.0)); + batch.setModelTransform(model); + if (keyLight) { + batch.setUniformBuffer(ZONE_KEYLIGHT_BUFFER, keyLight->getLightSchemaBuffer()); + } + batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setPipeline(getAmbientPipeline()); - batch.setModelTransform(model); + model.setTranslation(glm::vec3(-4.0, 0.0, -10.0)); + batch.setModelTransform(model); if (keyAmbiLight) { batch.setUniformBuffer(ZONE_AMBIENT_BUFFER, keyAmbiLight->getAmbientSchemaBuffer()); diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index ee3754b7eb..10eaa67d31 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -65,7 +65,8 @@ protected: enum Slots { ZONE_DEFERRED_TRANSFORM_BUFFER = 0, - ZONE_AMBIENT_BUFFER, + ZONE_KEYLIGHT_BUFFER, + ZONE_AMBIENT_BUFFER, ZONE_AMBIENT_MAP, ZONE_SKYBOX_MAP, }; diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf new file mode 100644 index 0000000000..f4bb147635 --- /dev/null +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -0,0 +1,66 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gateau on 5/16/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include DeferredTransform.slh@> +<$declareDeferredFrameTransform()$> + +<@include model/Light.slh@> + +<@include LightingModel.slh@> +<$declareLightBuffer()$> + +<@include LightDirectional.slh@> +<$declareLightingDirectional(_SCRIBE_NULL)$> + +in vec2 varTexCoord0; +out vec4 _fragColor; + +void main(void) { + + const float INNER_RADIUS = 1.0; + const float INNER_RADIUS2 = INNER_RADIUS * INNER_RADIUS; + const float OUTER_RADIUS = 1.05; + const float OUTER_RADIUS2 = OUTER_RADIUS * OUTER_RADIUS; + vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUTER_RADIUS; + float sphereR2 = dot(sphereUV.xy, sphereUV.xy); + if (sphereR2 > OUTER_RADIUS * OUTER_RADIUS) { + discard; + } + if (sphereR2 > INNER_RADIUS2) { + float falloff = (sphereR2 - OUTER_RADIUS2) / (OUTER_RADIUS2 - INNER_RADIUS2); + _fragColor = vec4(0.0, 0.0, 0.0, falloff * falloff); + return; + } + vec3 spherePos = normalize(vec3(sphereUV, sqrt(1.0 - sphereR2))); + + + vec3 fragNormal = vec3(getViewInverse() * vec4(spherePos, 0.0)); + + + LightAmbient lightAmbient = getLightAmbient(); + + + float roughness = 0.1; + float levels = getLightAmbientMapNumMips(lightAmbient); + float lod = min(((roughness)* levels), levels); + vec3 ambientMap = evalSkyboxLight(fragNormal, lod).xyz; + vec3 ambientSH = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; + + // vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; + // _fragColor = vec4( 0.5 * (fragNormal + vec3(1.0)), 1.0); + + vec3 ambient = (sphereUV.x > 0 ? ambientMap : ambientSH); + + const float INV_GAMMA_22 = 1.0 / 2.2; + _fragColor = vec4(pow(ambient, vec3(INV_GAMMA_22)), 1.0); +} + + From 3e7795ec11714043a7df75d538c294b595d3f424 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 17 May 2017 18:23:47 -0700 Subject: [PATCH 14/22] Adding the drawKeyLight shader --- libraries/render-utils/src/ZoneRenderer.cpp | 2 +- .../render-utils/src/zone_drawKeyLight.slf | 17 +++++------------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 620597e76a..290e3ce6a7 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -68,7 +68,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); - slotBindings.insert(gpu::Shader::Binding(std::string("keylightBuffer"), ZONE_KEYLIGHT_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ZONE_KEYLIGHT_BUFFER)); gpu::Shader::makeProgram(*program, slotBindings); diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf index f4bb147635..5165d5139d 100644 --- a/libraries/render-utils/src/zone_drawKeyLight.slf +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -45,22 +45,15 @@ void main(void) { vec3 fragNormal = vec3(getViewInverse() * vec4(spherePos, 0.0)); - LightAmbient lightAmbient = getLightAmbient(); + Light light = getLight(); + vec3 lightDirection = getLightDirection(light); + vec3 lightIrradiance = getLightIrradiance(light); - float roughness = 0.1; - float levels = getLightAmbientMapNumMips(lightAmbient); - float lod = min(((roughness)* levels), levels); - vec3 ambientMap = evalSkyboxLight(fragNormal, lod).xyz; - vec3 ambientSH = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; - - // vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; - // _fragColor = vec4( 0.5 * (fragNormal + vec3(1.0)), 1.0); - - vec3 ambient = (sphereUV.x > 0 ? ambientMap : ambientSH); + vec3 color = lightIrradiance; const float INV_GAMMA_22 = 1.0 / 2.2; - _fragColor = vec4(pow(ambient, vec3(INV_GAMMA_22)), 1.0); + _fragColor = vec4(pow(color, vec3(INV_GAMMA_22)), 1.0); } From 966afa1e4aa5ac3d3ccd277d1c3fc21c47e71f6f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 17 May 2017 18:26:49 -0700 Subject: [PATCH 15/22] Adding the drawKeyLight shader --- libraries/render-utils/src/ZoneRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 290e3ce6a7..2ae18ffb1f 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -63,7 +63,7 @@ void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { if (!_keyLightPipeline) { auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); - auto ps = gpu::Shader::createPixel(std::string(zone_drawSkybox_frag)); + auto ps = gpu::Shader::createPixel(std::string(zone_drawKeyLight_frag)); gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); gpu::Shader::BindingSet slotBindings; From 5edcc38eba32ae82d16be429b4de1fb374ed3552 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Thu, 18 May 2017 01:06:59 -0700 Subject: [PATCH 16/22] Polishing the scope shaders --- libraries/model/src/model/Skybox.h | 4 ++ libraries/render-utils/src/ZoneRenderer.cpp | 58 ++++++++++--------- libraries/render-utils/src/ZoneRenderer.h | 5 +- libraries/render-utils/src/zone_draw.slh | 37 ++++++++++++ .../render-utils/src/zone_drawAmbient.slf | 25 ++------ .../render-utils/src/zone_drawKeyLight.slf | 46 +++++++-------- .../render-utils/src/zone_drawSkybox.slf | 48 +++++++-------- 7 files changed, 122 insertions(+), 101 deletions(-) create mode 100644 libraries/render-utils/src/zone_draw.slh diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h index d7d95fbe9e..90896fd8c6 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/model/src/model/Skybox.h @@ -25,6 +25,8 @@ typedef glm::vec3 Color; class Skybox { public: + typedef gpu::BufferView UniformBufferView; + Skybox(); Skybox& operator= (const Skybox& skybox); virtual ~Skybox() {}; @@ -43,6 +45,8 @@ public: static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox); + const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; } + protected: static const int SKYBOX_SKYMAP_SLOT { 0 }; static const int SKYBOX_CONSTANTS_SLOT { 0 }; diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 2ae18ffb1f..57cb4ecdaa 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -62,21 +62,21 @@ void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { if (!_keyLightPipeline) { - auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); - auto ps = gpu::Shader::createPixel(std::string(zone_drawKeyLight_frag)); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); + auto ps = gpu::Shader::createPixel(std::string(zone_drawKeyLight_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); - slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ZONE_KEYLIGHT_BUFFER)); + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ZONE_KEYLIGHT_BUFFER)); - gpu::Shader::makeProgram(*program, slotBindings); + gpu::Shader::makeProgram(*program, slotBindings); - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); - _keyLightPipeline = gpu::Pipeline::create(program, state); - } + state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + _keyLightPipeline = gpu::Pipeline::create(program, state); + } return _keyLightPipeline; } @@ -109,7 +109,8 @@ const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), ZONE_SKYBOX_MAP)); - + slotBindings.insert(gpu::Shader::Binding(std::string("skyboxBuffer"), ZONE_SKYBOX_BUFFER)); + gpu::Shader::makeProgram(*program, slotBindings); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); @@ -126,13 +127,13 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I auto deferredTransform = inputs; auto lightStage = DependencyManager::get()->getLightStage(); - model::LightPointer keyLight; - if (lightStage && lightStage->_currentFrame._sunLights.size()) { - keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front()); - } - else { - keyLight = DependencyManager::get()->getGlobalLight(); - } + model::LightPointer keyLight; + if (lightStage && lightStage->_currentFrame._sunLights.size()) { + keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front()); + } + else { + keyLight = DependencyManager::get()->getGlobalLight(); + } model::LightPointer keyAmbiLight; if (lightStage && lightStage->_currentFrame._ambientLights.size()) { @@ -163,17 +164,17 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I batch.setUniformBuffer(ZONE_DEFERRED_TRANSFORM_BUFFER, deferredTransform->getFrameTransformBuffer()); - batch.setPipeline(getKeyLightPipeline()); - model.setTranslation(glm::vec3(-4.0, -3.0, -10.0)); - batch.setModelTransform(model); - if (keyLight) { - batch.setUniformBuffer(ZONE_KEYLIGHT_BUFFER, keyLight->getLightSchemaBuffer()); - } - batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setPipeline(getKeyLightPipeline()); + model.setTranslation(glm::vec3(-4.0, -3.0, -10.0)); + batch.setModelTransform(model); + if (keyLight) { + batch.setUniformBuffer(ZONE_KEYLIGHT_BUFFER, keyLight->getLightSchemaBuffer()); + } + batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setPipeline(getAmbientPipeline()); - model.setTranslation(glm::vec3(-4.0, 0.0, -10.0)); - batch.setModelTransform(model); + model.setTranslation(glm::vec3(-4.0, 0.0, -10.0)); + batch.setModelTransform(model); if (keyAmbiLight) { batch.setUniformBuffer(ZONE_AMBIENT_BUFFER, keyAmbiLight->getAmbientSchemaBuffer()); @@ -188,6 +189,7 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I batch.setModelTransform(model); if (skybox) { batch.setResourceTexture(ZONE_SKYBOX_MAP, skybox->getCubemap()); + batch.setUniformBuffer(ZONE_SKYBOX_BUFFER, skybox->getSchemaBuffer()); } batch.draw(gpu::TRIANGLE_STRIP, 4); diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index 10eaa67d31..40f9db2995 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -65,9 +65,10 @@ protected: enum Slots { ZONE_DEFERRED_TRANSFORM_BUFFER = 0, - ZONE_KEYLIGHT_BUFFER, - ZONE_AMBIENT_BUFFER, + ZONE_KEYLIGHT_BUFFER, + ZONE_AMBIENT_BUFFER, ZONE_AMBIENT_MAP, + ZONE_SKYBOX_BUFFER, ZONE_SKYBOX_MAP, }; diff --git a/libraries/render-utils/src/zone_draw.slh b/libraries/render-utils/src/zone_draw.slh new file mode 100644 index 0000000000..2cc8fc99f2 --- /dev/null +++ b/libraries/render-utils/src/zone_draw.slh @@ -0,0 +1,37 @@ + +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gateau on 5/17/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include DeferredTransform.slh@> +<$declareDeferredFrameTransform()$> + +<@func evalGlobeWidget()@> + const float SCOPE_RADIUS = 1.0; + const float SCOPE_RADIUS2 = SCOPE_RADIUS * SCOPE_RADIUS; + const float EDGE_HALFWIDTH = 0.025; + const float EDGE_HALFWIDTH2 = EDGE_HALFWIDTH * EDGE_HALFWIDTH; + const float OUT_RADIUS = SCOPE_RADIUS + EDGE_HALFWIDTH; + + vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUT_RADIUS; + float sphereR2 = dot(sphereUV.xy, sphereUV.xy); + if (sphereR2 > OUT_RADIUS * OUT_RADIUS) { + discard; + } + float sphereR = sqrt(sphereR2); + + float edgeFalloff = (SCOPE_RADIUS - sphereR) / (EDGE_HALFWIDTH); + float edgeFalloff2 = min(1.0, edgeFalloff * edgeFalloff); + + vec4 base = vec4(0.0, 0.0, 0.0, 1.0 - edgeFalloff2); + if (sphereR2 > SCOPE_RADIUS2) { + _fragColor = base; + return; + } +<@endfunc@> + diff --git a/libraries/render-utils/src/zone_drawAmbient.slf b/libraries/render-utils/src/zone_drawAmbient.slf index f14bed5c03..f104e5be44 100644 --- a/libraries/render-utils/src/zone_drawAmbient.slf +++ b/libraries/render-utils/src/zone_drawAmbient.slf @@ -8,9 +8,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -<@include DeferredTransform.slh@> -<$declareDeferredFrameTransform()$> +<@include zone_draw.slh@> <@include model/Light.slh@> @@ -26,20 +24,8 @@ out vec4 _fragColor; void main(void) { - const float INNER_RADIUS = 1.0; - const float INNER_RADIUS2 = INNER_RADIUS * INNER_RADIUS; - const float OUTER_RADIUS = 1.05; - const float OUTER_RADIUS2 = OUTER_RADIUS * OUTER_RADIUS; - vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUTER_RADIUS; - float sphereR2 = dot(sphereUV.xy, sphereUV.xy); - if (sphereR2 > OUTER_RADIUS * OUTER_RADIUS) { - discard; - } - if (sphereR2 > INNER_RADIUS2) { - float falloff = (sphereR2 - OUTER_RADIUS2) / (OUTER_RADIUS2 - INNER_RADIUS2); - _fragColor = vec4(0.0, 0.0, 0.0, falloff * falloff); - return; - } + <$evalGlobeWidget()$> + vec3 spherePos = normalize(vec3(sphereUV, sqrt(1.0 - sphereR2))); @@ -58,10 +44,11 @@ void main(void) { // vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; // _fragColor = vec4( 0.5 * (fragNormal + vec3(1.0)), 1.0); - vec3 ambient = (sphereUV.x > 0 ? ambientMap : ambientSH); + vec3 color = (sphereUV.x > 0 ? ambientMap : ambientSH); + color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; - _fragColor = vec4(pow(ambient, vec3(INV_GAMMA_22)), 1.0); + _fragColor = vec4(pow(color, vec3(INV_GAMMA_22)), 1.0); } diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf index 5165d5139d..dcfdd20c6a 100644 --- a/libraries/render-utils/src/zone_drawKeyLight.slf +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -8,9 +8,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -<@include DeferredTransform.slh@> -<$declareDeferredFrameTransform()$> +<@include zone_draw.slh@> <@include model/Light.slh@> @@ -25,33 +23,31 @@ out vec4 _fragColor; void main(void) { - const float INNER_RADIUS = 1.0; - const float INNER_RADIUS2 = INNER_RADIUS * INNER_RADIUS; - const float OUTER_RADIUS = 1.05; - const float OUTER_RADIUS2 = OUTER_RADIUS * OUTER_RADIUS; - vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUTER_RADIUS; - float sphereR2 = dot(sphereUV.xy, sphereUV.xy); - if (sphereR2 > OUTER_RADIUS * OUTER_RADIUS) { - discard; - } - if (sphereR2 > INNER_RADIUS2) { - float falloff = (sphereR2 - OUTER_RADIUS2) / (OUTER_RADIUS2 - INNER_RADIUS2); - _fragColor = vec4(0.0, 0.0, 0.0, falloff * falloff); - return; - } - vec3 spherePos = normalize(vec3(sphereUV, sqrt(1.0 - sphereR2))); - - - vec3 fragNormal = vec3(getViewInverse() * vec4(spherePos, 0.0)); - + <$evalGlobeWidget()$> Light light = getLight(); - - vec3 lightDirection = getLightDirection(light); + vec3 lightDirection = getLightDirection(light); vec3 lightIrradiance = getLightIrradiance(light); + vec3 color = vec3(0.0); + + const float INOUT_RATIO = 0.4; + const float SUN_THRESHOLD = 0.99; - vec3 color = lightIrradiance; + vec3 outSpherePos = normalize(vec3(sphereUV, -sqrt(1.0 - sphereR2))); + vec3 outNormal = vec3(getViewInverse() * vec4(outSpherePos, 0.0)); + float val = step(SUN_THRESHOLD, dot(-lightDirection, outNormal)); + color = lightIrradiance * vec3(val); + + if (sphereR2 < INOUT_RATIO * INOUT_RATIO * SCOPE_RADIUS2) { + vec2 inSphereUV = sphereUV / INOUT_RATIO; + vec3 inSpherePos = normalize(vec3(inSphereUV, sqrt(1.0 - dot(inSphereUV.xy, inSphereUV.xy)))); + vec3 inNormal = vec3(getViewInverse() * vec4(inSpherePos, 0.0)); + + color += lightIrradiance * vec3(dot(-lightDirection, inNormal)); + } + + color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; _fragColor = vec4(pow(color, vec3(INV_GAMMA_22)), 1.0); } diff --git a/libraries/render-utils/src/zone_drawSkybox.slf b/libraries/render-utils/src/zone_drawSkybox.slf index 77b144379b..fd6976365e 100644 --- a/libraries/render-utils/src/zone_drawSkybox.slf +++ b/libraries/render-utils/src/zone_drawSkybox.slf @@ -8,47 +8,41 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include zone_draw.slh@> -<@include DeferredTransform.slh@> -<$declareDeferredFrameTransform()$> - -// declareSkyboxMap uniform samplerCube skyboxMap; -vec4 evalSkyboxLight(vec3 direction, float lod) { - // textureQueryLevels is not available until #430, so we require explicit lod - // float mipmapLevel = lod * textureQueryLevels(skyboxMap); - return textureLod(skyboxMap, direction, lod); -} +struct Skybox { + vec4 color; +}; + +uniform skyboxBuffer { + Skybox skybox; +}; in vec2 varTexCoord0; out vec4 _fragColor; void main(void) { + <$evalGlobeWidget()$> - const float INNER_RADIUS = 1.0; - const float INNER_RADIUS2 = INNER_RADIUS * INNER_RADIUS; - const float OUTER_RADIUS = 1.05; - const float OUTER_RADIUS2 = OUTER_RADIUS * OUTER_RADIUS; - vec2 sphereUV = (varTexCoord0.xy * 2.0 - vec2(1.0)) * OUTER_RADIUS; - float sphereR2 = dot(sphereUV.xy, sphereUV.xy); - if (sphereR2 > OUTER_RADIUS * OUTER_RADIUS) { - discard; - } - if (sphereR2 > INNER_RADIUS2) { - float falloff = (sphereR2 - OUTER_RADIUS2) / (OUTER_RADIUS2 - INNER_RADIUS2); - _fragColor = vec4(0.0, 0.0, 0.0, falloff * falloff); - return; - } vec3 spherePos = normalize(vec3(sphereUV, -sqrt(1.0 - sphereR2))); - vec3 fragNormal = vec3(getViewInverse() * vec4(spherePos, 0.0)); + vec3 direction = vec3(getViewInverse() * vec4(spherePos, 0.0)); - float lod = 0; - vec3 ambient = evalSkyboxLight(fragNormal, lod).xyz; + vec3 color = skybox.color.rgb; + // blend is only set if there is a cubemap + if (skybox.color.a > 0.0) { + color = texture(skyboxMap, direction).rgb; + if (skybox.color.a < 1.0) { + color *= skybox.color.rgb; + } + } + + color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; - _fragColor = vec4(pow(ambient, vec3(INV_GAMMA_22)), 1.0); + _fragColor = vec4(pow(color, vec3(INV_GAMMA_22)), 1.0); } From b8a2b38fd5a41a03867b9d86b6bc070089d0ecfb Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 18 May 2017 12:54:25 -0700 Subject: [PATCH 17/22] Displaying the stack of zone components --- libraries/render-utils/src/ZoneRenderer.cpp | 98 ++++++++++--------- .../render-utils/src/zone_drawKeyLight.slf | 5 +- 2 files changed, 57 insertions(+), 46 deletions(-) diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 57cb4ecdaa..c51e8205cd 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -127,31 +127,35 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I auto deferredTransform = inputs; auto lightStage = DependencyManager::get()->getLightStage(); - model::LightPointer keyLight; + std::vector keyLightStack; if (lightStage && lightStage->_currentFrame._sunLights.size()) { - keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front()); - } - else { - keyLight = DependencyManager::get()->getGlobalLight(); + for (auto index : lightStage->_currentFrame._sunLights) { + keyLightStack.push_back(lightStage->getLight(index)); + } } + keyLightStack.push_back(DependencyManager::get()->getGlobalLight()); + + std::vector ambientLightStack; + if (lightStage && lightStage->_currentFrame._ambientLights.size()) { + for (auto index : lightStage->_currentFrame._ambientLights) { + ambientLightStack.push_back(lightStage->getLight(index)); + } + } + ambientLightStack.push_back(DependencyManager::get()->getGlobalLight()); - model::LightPointer keyAmbiLight; - if (lightStage && lightStage->_currentFrame._ambientLights.size()) { - keyAmbiLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front()); - } else { - keyAmbiLight = DependencyManager::get()->getGlobalLight(); - } auto backgroundStage = DependencyManager::get()->getBackgroundStage(); - model::SkyboxPointer skybox; + std::vector skyboxStack; if (backgroundStage && backgroundStage->_currentFrame._backgrounds.size()) { - auto background = backgroundStage->getBackground(backgroundStage->_currentFrame._backgrounds.front()); - if (background) { - skybox = background->getSkybox(); - } - } else { - skybox = DependencyManager::get()->getDefaultSkybox(); - } + for (auto index : backgroundStage->_currentFrame._backgrounds) { + auto background = backgroundStage->getBackground(index); + if (background) { + skyboxStack.push_back(background->getSkybox()); + } + } + } + skyboxStack.push_back(DependencyManager::get()->getDefaultSkybox()); + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { @@ -165,34 +169,40 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I batch.setUniformBuffer(ZONE_DEFERRED_TRANSFORM_BUFFER, deferredTransform->getFrameTransformBuffer()); batch.setPipeline(getKeyLightPipeline()); - model.setTranslation(glm::vec3(-4.0, -3.0, -10.0)); - batch.setModelTransform(model); - if (keyLight) { - batch.setUniformBuffer(ZONE_KEYLIGHT_BUFFER, keyLight->getLightSchemaBuffer()); - } - batch.draw(gpu::TRIANGLE_STRIP, 4); + auto numKeys = keyLightStack.size(); + for (int i = numKeys - 1; i >= 0; i--) { + model.setTranslation(glm::vec3(-4.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0))); + batch.setModelTransform(model); + if (keyLightStack[i]) { + batch.setUniformBuffer(ZONE_KEYLIGHT_BUFFER, keyLightStack[i]->getLightSchemaBuffer()); + batch.draw(gpu::TRIANGLE_STRIP, 4); + } + } batch.setPipeline(getAmbientPipeline()); - model.setTranslation(glm::vec3(-4.0, 0.0, -10.0)); - batch.setModelTransform(model); - if (keyAmbiLight) { - batch.setUniformBuffer(ZONE_AMBIENT_BUFFER, keyAmbiLight->getAmbientSchemaBuffer()); - - if (keyAmbiLight->getAmbientMap()) { - batch.setResourceTexture(ZONE_AMBIENT_MAP, keyAmbiLight->getAmbientMap()); - } - } - batch.draw(gpu::TRIANGLE_STRIP, 4); + auto numAmbients = ambientLightStack.size(); + for (int i = numAmbients - 1; i >= 0; i--) { + model.setTranslation(glm::vec3(0.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0))); + batch.setModelTransform(model); + if (ambientLightStack[i]) { + batch.setUniformBuffer(ZONE_AMBIENT_BUFFER, ambientLightStack[i]->getAmbientSchemaBuffer()); + if (ambientLightStack[i]->getAmbientMap()) { + batch.setResourceTexture(ZONE_AMBIENT_MAP, ambientLightStack[i]->getAmbientMap()); + } + batch.draw(gpu::TRIANGLE_STRIP, 4); + } + } batch.setPipeline(getBackgroundPipeline()); - model.setTranslation(glm::vec3(-4.0, 3.0, -10.0)); - batch.setModelTransform(model); - if (skybox) { - batch.setResourceTexture(ZONE_SKYBOX_MAP, skybox->getCubemap()); - batch.setUniformBuffer(ZONE_SKYBOX_BUFFER, skybox->getSchemaBuffer()); - } - batch.draw(gpu::TRIANGLE_STRIP, 4); - - + auto numBackgrounds = skyboxStack.size(); + for (int i = numBackgrounds - 1; i >= 0; i--) { + model.setTranslation(glm::vec3(4.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0))); + batch.setModelTransform(model); + if (skyboxStack[i]) { + batch.setResourceTexture(ZONE_SKYBOX_MAP, skyboxStack[i]->getCubemap()); + batch.setUniformBuffer(ZONE_SKYBOX_BUFFER, skyboxStack[i]->getSchemaBuffer()); + batch.draw(gpu::TRIANGLE_STRIP, 4); + } + } }); } diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf index dcfdd20c6a..cc60979605 100644 --- a/libraries/render-utils/src/zone_drawKeyLight.slf +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -26,7 +26,7 @@ void main(void) { <$evalGlobeWidget()$> Light light = getLight(); - vec3 lightDirection = getLightDirection(light); + vec3 lightDirection = normalize(getLightDirection(light)); vec3 lightIrradiance = getLightIrradiance(light); vec3 color = vec3(0.0); @@ -35,7 +35,8 @@ void main(void) { vec3 outSpherePos = normalize(vec3(sphereUV, -sqrt(1.0 - sphereR2))); vec3 outNormal = vec3(getViewInverse() * vec4(outSpherePos, 0.0)); - float val = step(SUN_THRESHOLD, dot(-lightDirection, outNormal)); + + float val = step(SUN_THRESHOLD, dot(-lightDirection, outNormal)); color = lightIrradiance * vec3(val); From 589bcc19ce9b841b91a487f069b35fa5136a95e6 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 19 May 2017 17:50:19 -0700 Subject: [PATCH 18/22] Refining the shader for key and testing removing completely the code dealing with Zone lighting in the ENtityTreeREnderer --- .../src/EntityTreeRenderer.cpp | 26 +++++++++---------- .../src/EntityTreeRenderer.h | 8 +++--- .../src/DeferredLightingEffect.cpp | 7 +++-- .../render-utils/src/zone_drawKeyLight.slf | 3 ++- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 1de476c825..de7fa43026 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -141,7 +141,7 @@ void EntityTreeRenderer::clear() { // reset the zone to the default (while we load the next scene) _layeredZones.clear(); - applyZoneAndHasSkybox(nullptr); + // applyZoneAndHasSkybox(nullptr); OctreeRenderer::clear(); } @@ -198,11 +198,11 @@ void EntityTreeRenderer::update() { // If we haven't already updated and previously attempted to load a texture, // check if the texture loaded and apply it - if (!updated && + /* if (!updated && ((_pendingAmbientTexture && (!_ambientTexture || _ambientTexture->isLoaded())) || (_pendingSkyboxTexture && (!_skyboxTexture || _skyboxTexture->isLoaded())))) { applySkyboxAndHasAmbient(); - } + }*/ // Even if we're not moving the mouse, if we started clicking on an entity and we have // not yet released the hold then this is still considered a holdingClickOnEntity event @@ -371,7 +371,7 @@ bool EntityTreeRenderer::applyLayeredZones() { return true; } - +/* bool EntityTreeRenderer::applyZoneAndHasSkybox(const std::shared_ptr& zone) { auto textureCache = DependencyManager::get(); auto scene = DependencyManager::get(); @@ -427,8 +427,8 @@ bool EntityTreeRenderer::applyZoneAndHasSkybox(const std::shared_ptr& zone) { assert(zone); @@ -483,8 +483,8 @@ bool EntityTreeRenderer::layerZoneAndHasSkybox(const std::shared_ptr(); auto scene = DependencyManager::get(); @@ -539,7 +539,7 @@ bool EntityTreeRenderer::applySkyboxAndHasAmbient() { } return isAmbientSet; -} +}*/ const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer entityItem) { const FBXGeometry* result = NULL; @@ -1169,7 +1169,7 @@ std::pair EntityTreeRenderer:: void EntityTreeRenderer::LayeredZones::apply() { assert(_entityTreeRenderer); - applyPartial(begin()); + // applyPartial(begin()); } void EntityTreeRenderer::LayeredZones::update(std::shared_ptr zone) { @@ -1211,11 +1211,11 @@ void EntityTreeRenderer::LayeredZones::update(std::shared_ptr zo } if (shouldUpdate) { - applyPartial(layer); + // applyPartial(layer); } } } - +/* void EntityTreeRenderer::LayeredZones::applyPartial(iterator layer) { bool hasSkybox = false; _skyboxLayer = end(); @@ -1243,7 +1243,7 @@ void EntityTreeRenderer::LayeredZones::applyPartial(iterator layer) { _skyboxLayer = layer; } - +*/ bool EntityTreeRenderer::LayeredZones::contains(const LayeredZones& other) { bool result = std::equal(other.begin(), other._skyboxLayer, begin()); if (result) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index f4717dca51..92235b1a00 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -147,9 +147,9 @@ private: void addEntityToScene(EntityItemPointer entity); bool findBestZoneAndMaybeContainingEntities(QVector* entitiesContainingAvatar = nullptr); - bool applyZoneAndHasSkybox(const std::shared_ptr& zone); - bool layerZoneAndHasSkybox(const std::shared_ptr& zone); - bool applySkyboxAndHasAmbient(); + // bool applyZoneAndHasSkybox(const std::shared_ptr& zone); + // bool layerZoneAndHasSkybox(const std::shared_ptr& zone); + // bool applySkyboxAndHasAmbient(); bool applyLayeredZones(); void checkAndCallPreload(const EntityItemID& entityID, bool reload = false, bool unloadFirst = false); @@ -223,7 +223,7 @@ private: std::shared_ptr getZone() { return empty() ? nullptr : begin()->zone; } private: - void applyPartial(iterator layer); + // void applyPartial(iterator layer); std::map _map; iterator _skyboxLayer{ end() }; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index b799a7c49e..e1042912aa 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -160,8 +160,11 @@ void DeferredLightingEffect::init() { lp->setAmbientIntensity(0.5f); - lp->setAmbientMap(_defaultSkyboxAmbientTexture); - + lp->setAmbientMap(_defaultSkyboxAmbientTexture); + auto irradianceSH = _defaultSkyboxAmbientTexture->getIrradiance(); + if (irradianceSH) { + lp->setAmbientSphere((*irradianceSH)); + } } void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf index cc60979605..e96239b6dc 100644 --- a/libraries/render-utils/src/zone_drawKeyLight.slf +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -45,7 +45,8 @@ void main(void) { vec3 inSpherePos = normalize(vec3(inSphereUV, sqrt(1.0 - dot(inSphereUV.xy, inSphereUV.xy)))); vec3 inNormal = vec3(getViewInverse() * vec4(inSpherePos, 0.0)); - color += lightIrradiance * vec3(dot(-lightDirection, inNormal)); + vec3 marbleColor = max(lightIrradiance * vec3(dot(-lightDirection, inNormal)), vec3(0.01)); + color += marbleColor; } color = color * 1.0 - base.w + base.xyz * base.w; From c256893575e9935ced4bb789318b5c6aea13247c Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 23 May 2017 18:00:22 -0700 Subject: [PATCH 19/22] some clean up: --- .../src/RenderableZoneEntityItem.cpp | 25 +++-- .../render-utils/src/RenderDeferredTask.cpp | 11 +- libraries/render-utils/src/ZoneRenderer.cpp | 102 +++++++++--------- libraries/render-utils/src/ZoneRenderer.h | 8 +- 4 files changed, 80 insertions(+), 66 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 970672787e..d5579aa022 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -373,12 +373,6 @@ void RenderableZoneEntityItem::updateKeyZoneItemFromEntity(RenderableZoneEntityI if (!success) { keyZonePayload.editBound() = render::Item::Bound(); } - - updateKeySunFromEntity(keyZonePayload); - - updateKeyAmbientFromEntity(keyZonePayload); - - updateKeyBackgroundFromEntity(keyZonePayload); } @@ -387,8 +381,25 @@ void RenderableZoneEntityItem::sceneUpdateRenderItemFromEntity(render::Transacti return; } - transaction.updateItem(_myMetaItem, [&](RenderableZoneEntityItemMeta& data) { + bool sunChanged = _keyLightPropertiesChanged; + bool backgroundChanged = _backgroundPropertiesChanged; + bool stageChanged = _stagePropertiesChanged; + bool skyboxChanged = _skyboxPropertiesChanged; + + transaction.updateItem(_myMetaItem, [=](RenderableZoneEntityItemMeta& data) { + updateKeyZoneItemFromEntity(data); + + if (sunChanged) { + updateKeySunFromEntity(data); + } + + if (sunChanged || skyboxChanged) { + updateKeyAmbientFromEntity(data); + } + if (backgroundChanged || skyboxChanged) { + updateKeyBackgroundFromEntity(data); + } }); } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 21df88d4c4..b844da8bbe 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -123,7 +123,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now. task.addJob("DrawLight", lights); - // Filter zones + // Filter zones from the general metas bucket const auto zones = task.addJob("ZoneRenderer", metas); // Light Clustering @@ -138,12 +138,9 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("RenderDeferred", deferredLightingInputs); - // Use Stencil and draw background in Lighting buffer to complete filling in the opaque - //const auto backgroundInputs = DrawBackgroundDeferred::Inputs(background, lightingModel).hasVarying(); - //task.addJob("DrawBackgroundDeferred", backgroundInputs); - + // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job task.addJob("DrawBackgroundDeferred", lightingModel); - + // Render transparent objects forward in LightingBuffer const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).hasVarying(); task.addJob("DrawTransparentDeferred", transparentsInputs, shapePlumber); @@ -207,7 +204,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawStatus", opaques, DrawStatus(statusIconMap)); } - task.addJob("DebugZoneLighting", deferredFrameTransform); + task.addJob("DrawZoneStack", deferredFrameTransform); } diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index c51e8205cd..3b4870fd3f 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -127,34 +127,34 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I auto deferredTransform = inputs; auto lightStage = DependencyManager::get()->getLightStage(); - std::vector keyLightStack; + std::vector keyLightStack; if (lightStage && lightStage->_currentFrame._sunLights.size()) { - for (auto index : lightStage->_currentFrame._sunLights) { - keyLightStack.push_back(lightStage->getLight(index)); - } + for (auto index : lightStage->_currentFrame._sunLights) { + keyLightStack.push_back(lightStage->getLight(index)); + } } - keyLightStack.push_back(DependencyManager::get()->getGlobalLight()); + keyLightStack.push_back(DependencyManager::get()->getGlobalLight()); - std::vector ambientLightStack; - if (lightStage && lightStage->_currentFrame._ambientLights.size()) { - for (auto index : lightStage->_currentFrame._ambientLights) { - ambientLightStack.push_back(lightStage->getLight(index)); - } - } - ambientLightStack.push_back(DependencyManager::get()->getGlobalLight()); + std::vector ambientLightStack; + if (lightStage && lightStage->_currentFrame._ambientLights.size()) { + for (auto index : lightStage->_currentFrame._ambientLights) { + ambientLightStack.push_back(lightStage->getLight(index)); + } + } + ambientLightStack.push_back(DependencyManager::get()->getGlobalLight()); auto backgroundStage = DependencyManager::get()->getBackgroundStage(); - std::vector skyboxStack; + std::vector skyboxStack; if (backgroundStage && backgroundStage->_currentFrame._backgrounds.size()) { - for (auto index : backgroundStage->_currentFrame._backgrounds) { - auto background = backgroundStage->getBackground(index); - if (background) { - skyboxStack.push_back(background->getSkybox()); - } - } + for (auto index : backgroundStage->_currentFrame._backgrounds) { + auto background = backgroundStage->getBackground(index); + if (background) { + skyboxStack.push_back(background->getSkybox()); + } + } } - skyboxStack.push_back(DependencyManager::get()->getDefaultSkybox()); + skyboxStack.push_back(DependencyManager::get()->getDefaultSkybox()); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { @@ -169,40 +169,40 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I batch.setUniformBuffer(ZONE_DEFERRED_TRANSFORM_BUFFER, deferredTransform->getFrameTransformBuffer()); batch.setPipeline(getKeyLightPipeline()); - auto numKeys = keyLightStack.size(); - for (int i = numKeys - 1; i >= 0; i--) { - model.setTranslation(glm::vec3(-4.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0))); - batch.setModelTransform(model); - if (keyLightStack[i]) { - batch.setUniformBuffer(ZONE_KEYLIGHT_BUFFER, keyLightStack[i]->getLightSchemaBuffer()); - batch.draw(gpu::TRIANGLE_STRIP, 4); - } - } + auto numKeys = keyLightStack.size(); + for (int i = numKeys - 1; i >= 0; i--) { + model.setTranslation(glm::vec3(-4.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0))); + batch.setModelTransform(model); + if (keyLightStack[i]) { + batch.setUniformBuffer(ZONE_KEYLIGHT_BUFFER, keyLightStack[i]->getLightSchemaBuffer()); + batch.draw(gpu::TRIANGLE_STRIP, 4); + } + } batch.setPipeline(getAmbientPipeline()); - auto numAmbients = ambientLightStack.size(); - for (int i = numAmbients - 1; i >= 0; i--) { - model.setTranslation(glm::vec3(0.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0))); - batch.setModelTransform(model); - if (ambientLightStack[i]) { - batch.setUniformBuffer(ZONE_AMBIENT_BUFFER, ambientLightStack[i]->getAmbientSchemaBuffer()); - if (ambientLightStack[i]->getAmbientMap()) { - batch.setResourceTexture(ZONE_AMBIENT_MAP, ambientLightStack[i]->getAmbientMap()); - } - batch.draw(gpu::TRIANGLE_STRIP, 4); - } - } + auto numAmbients = ambientLightStack.size(); + for (int i = numAmbients - 1; i >= 0; i--) { + model.setTranslation(glm::vec3(0.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0))); + batch.setModelTransform(model); + if (ambientLightStack[i]) { + batch.setUniformBuffer(ZONE_AMBIENT_BUFFER, ambientLightStack[i]->getAmbientSchemaBuffer()); + if (ambientLightStack[i]->getAmbientMap()) { + batch.setResourceTexture(ZONE_AMBIENT_MAP, ambientLightStack[i]->getAmbientMap()); + } + batch.draw(gpu::TRIANGLE_STRIP, 4); + } + } batch.setPipeline(getBackgroundPipeline()); - auto numBackgrounds = skyboxStack.size(); - for (int i = numBackgrounds - 1; i >= 0; i--) { - model.setTranslation(glm::vec3(4.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0))); - batch.setModelTransform(model); - if (skyboxStack[i]) { - batch.setResourceTexture(ZONE_SKYBOX_MAP, skyboxStack[i]->getCubemap()); - batch.setUniformBuffer(ZONE_SKYBOX_BUFFER, skyboxStack[i]->getSchemaBuffer()); - batch.draw(gpu::TRIANGLE_STRIP, 4); - } - } + auto numBackgrounds = skyboxStack.size(); + for (int i = numBackgrounds - 1; i >= 0; i--) { + model.setTranslation(glm::vec3(4.0, -3.0 + (i * 1.0), -10.0 - (i * 3.0))); + batch.setModelTransform(model); + if (skyboxStack[i]) { + batch.setResourceTexture(ZONE_SKYBOX_MAP, skyboxStack[i]->getCubemap()); + batch.setUniformBuffer(ZONE_SKYBOX_BUFFER, skyboxStack[i]->getSchemaBuffer()); + batch.draw(gpu::TRIANGLE_STRIP, 4); + } + } }); } diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index 40f9db2995..5737499270 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -54,11 +54,17 @@ protected: class DebugZoneLighting { public: + class Config : public render::JobConfig { + public: + Config(bool enabled = false) : JobConfig(enabled) {} + }; + using Inputs = DeferredFrameTransformPointer; - using JobModel = render::Job::ModelI; + using JobModel = render::Job::ModelI; DebugZoneLighting() {} + void configure(const Config& configuration) {} void run(const render::RenderContextPointer& context, const Inputs& inputs); protected: From 575d4abdf710a7381cfe846d1dee7fed3252449f Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 24 May 2017 17:25:21 -0700 Subject: [PATCH 20/22] bad include fixed maybe --- interface/src/Application.cpp | 8 +------- .../entities-renderer/src/RenderableZoneEntityItem.cpp | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1d74fd31fd..6b41d921de 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -337,7 +337,7 @@ public: // Don't actually crash in debug builds, in case this apparent deadlock is simply from // the developer actively debugging code #ifdef NDEBUG - // deadlockDetectionCrash(); + deadlockDetectionCrash(); #endif } } @@ -5097,12 +5097,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se }); } - // Setup the current Zone Entity lighting - { - // auto stage = DependencyManager::get()->getSkyStage(); - // DependencyManager::get()->setGlobalLight(stage->getSunLight()); - } - { PerformanceTimer perfTimer("SceneProcessTransaction"); _main3DScene->enqueueTransaction(transaction); diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index d5579aa022..7825a50f25 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "EntityTreeRenderer.h" #include "RenderableEntityItem.h" @@ -26,7 +27,6 @@ #include #include "DeferredLightingEffect.h" -#include class RenderableZoneEntityItemMeta { public: From 3eb95d2d193da2436a458e6f1b6d3a77f5c92268 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Thu, 25 May 2017 01:16:45 -0700 Subject: [PATCH 21/22] cleaning the commented code --- interface/src/Application.cpp | 99 -------- interface/src/Application.h | 2 - .../src/EntityTreeRenderer.cpp | 220 ------------------ .../src/EntityTreeRenderer.h | 5 +- .../src/RenderableZoneEntityItem.cpp | 41 ++-- .../utilities/render/deferredLighting.qml | 1 + 6 files changed, 21 insertions(+), 347 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6b41d921de..89bd19cb48 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4874,12 +4874,6 @@ QRect Application::getDesirableApplicationGeometry() const { return applicationGeometry; } -glm::vec3 Application::getSunDirection() const { - // Sun direction is in fact just the location of the sun relative to the origin - auto skyStage = DependencyManager::get()->getSkyStage(); - return skyStage->getSunLight()->getDirection(); -} - // FIXME, preprocessor guard this check to occur only in DEBUG builds static QThread * activeRenderingThread = nullptr; @@ -4946,90 +4940,6 @@ namespace render { } } -// Background Render Data & rendering functions -class BackgroundRenderData { -public: - typedef render::Payload Payload; - typedef Payload::DataPointer Pointer; - - static render::ItemID _item; // unique WorldBoxRenderData -}; - -render::ItemID BackgroundRenderData::_item = 0; - -namespace render { - template <> const ItemKey payloadGetKey(const BackgroundRenderData::Pointer& stuff) { - return ItemKey::Builder::background(); - } - - template <> const Item::Bound payloadGetBound(const BackgroundRenderData::Pointer& stuff) { - return Item::Bound(); - } - - template <> void payloadRender(const BackgroundRenderData::Pointer& background, RenderArgs* args) { - Q_ASSERT(args->_batch); - gpu::Batch& batch = *args->_batch; - - // Background rendering decision - auto skyStage = DependencyManager::get()->getSkyStage(); - auto backgroundMode = skyStage->getBackgroundMode(); - - switch (backgroundMode) { - case model::SunSkyStage::SKY_DEFAULT: { - auto scene = DependencyManager::get()->getStage(); - auto sceneKeyLight = scene->getKeyLight(); - - scene->setSunModelEnable(false); - sceneKeyLight->setColor(ColorUtils::toVec3(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR)); - sceneKeyLight->setIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY); - sceneKeyLight->setAmbientIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY); - sceneKeyLight->setDirection(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION); - // fall through: render a skybox (if available), or the defaults (if requested) - } - - case model::SunSkyStage::SKY_BOX: { - auto skybox = skyStage->getSkybox(); - if (!skybox->empty()) { - PerformanceTimer perfTimer("skybox"); - skybox->render(batch, args->getViewFrustum()); - break; - } - // fall through: render defaults (if requested) - } - - case model::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: { - if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { - auto scene = DependencyManager::get()->getStage(); - auto sceneKeyLight = scene->getKeyLight(); - auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture(); - if (defaultSkyboxAmbientTexture) { - sceneKeyLight->setAmbientSphere(defaultSkyboxAmbientTexture->getIrradiance()); - sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture); - } else { - static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex( - "Failed to get a valid Default Skybox Ambient Texture ? probably because it couldn't be find during initialization step"); - } - // fall through: render defaults skybox - } else { - break; - } - } - - case model::SunSkyStage::SKY_DEFAULT_TEXTURE: - if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { - qApp->getDefaultSkybox()->render(batch, args->getViewFrustum()); - } - break; - - // Any other cases require no extra rendering - case model::SunSkyStage::NO_BACKGROUND: - default: - break; - } - } -} - - void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly) { // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. @@ -5053,15 +4963,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // The pending changes collecting the changes here render::Transaction transaction; - // FIXME: Move this out of here!, Background / skybox should be driven by the enityt content just like the other entities - // Background rendering decision - if (!render::Item::isValidID(BackgroundRenderData::_item)) { - auto backgroundRenderData = make_shared(); - auto backgroundRenderPayload = make_shared(backgroundRenderData); - BackgroundRenderData::_item = _main3DScene->allocateID(); - transaction.resetItem(BackgroundRenderData::_item, backgroundRenderPayload); - } - // Assuming nothing gets rendered through that if (!selfAvatarOnly) { if (DependencyManager::get()->shouldRenderEntities()) { diff --git a/interface/src/Application.h b/interface/src/Application.h index e8507c39e8..9cf03f1cef 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -460,8 +460,6 @@ private: void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions, bool forceResend = false); - glm::vec3 getSunDirection() const; - void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool isZoomed); int sendNackPackets(); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 94e0db60f9..be8f1db31a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include "EntityTreeRenderer.h" @@ -141,7 +140,6 @@ void EntityTreeRenderer::clear() { // reset the zone to the default (while we load the next scene) _layeredZones.clear(); - // applyZoneAndHasSkybox(nullptr); OctreeRenderer::clear(); } @@ -196,14 +194,6 @@ void EntityTreeRenderer::update() { // Handle enter/leave entity logic bool updated = checkEnterLeaveEntities(); - // If we haven't already updated and previously attempted to load a texture, - // check if the texture loaded and apply it - /* if (!updated && - ((_pendingAmbientTexture && (!_ambientTexture || _ambientTexture->isLoaded())) || - (_pendingSkyboxTexture && (!_skyboxTexture || _skyboxTexture->isLoaded())))) { - applySkyboxAndHasAmbient(); - }*/ - // Even if we're not moving the mouse, if we started clicking on an entity and we have // not yet released the hold then this is still considered a holdingClickOnEntity event // and we want to simulate this message here as well as in mouse move @@ -371,176 +361,6 @@ bool EntityTreeRenderer::applyLayeredZones() { return true; } -/* -bool EntityTreeRenderer::applyZoneAndHasSkybox(const std::shared_ptr& zone) { - auto textureCache = DependencyManager::get(); - auto scene = DependencyManager::get(); - auto sceneStage = scene->getStage(); - auto skyStage = scene->getSkyStage(); - auto sceneKeyLight = sceneStage->getKeyLight(); - - // If there is no zone, use the default background - if (!zone) { - _zoneUserData = QString(); - skyStage->getSkybox()->clear(); - - _pendingSkyboxTexture = false; - _skyboxTexture.clear(); - - _pendingAmbientTexture = false; - _ambientTexture.clear(); - - sceneKeyLight->resetAmbientSphere(); - sceneKeyLight->setAmbientMap(nullptr); - - skyStage->setBackgroundMode(model::SunSkyStage::SKY_DEFAULT); - return false; - } - - // Set the keylight - sceneKeyLight->setColor(ColorUtils::toVec3(zone->getKeyLightProperties().getColor())); - sceneKeyLight->setIntensity(zone->getKeyLightProperties().getIntensity()); - sceneKeyLight->setAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity()); - sceneKeyLight->setDirection(zone->getKeyLightProperties().getDirection()); - - // Set the stage - bool isSunModelEnabled = zone->getStageProperties().getSunModelEnabled(); - sceneStage->setSunModelEnable(isSunModelEnabled); - if (isSunModelEnabled) { - sceneStage->setLocation(zone->getStageProperties().getLongitude(), - zone->getStageProperties().getLatitude(), - zone->getStageProperties().getAltitude()); - - auto sceneTime = sceneStage->getTime(); - sceneTime->setHour(zone->getStageProperties().calculateHour()); - sceneTime->setDay(zone->getStageProperties().calculateDay()); - } - - // Set the ambient texture - _ambientTextureURL = zone->getKeyLightProperties().getAmbientURL(); - if (_ambientTextureURL.isEmpty()) { - _pendingAmbientTexture = false; - _ambientTexture.clear(); - } else { - _pendingAmbientTexture = true; - } - - // Set the skybox texture - return layerZoneAndHasSkybox(zone); -}*/ -/* -bool EntityTreeRenderer::layerZoneAndHasSkybox(const std::shared_ptr& zone) { - assert(zone); - - auto textureCache = DependencyManager::get(); - auto scene = DependencyManager::get(); - auto skyStage = scene->getSkyStage(); - auto skybox = skyStage->getSkybox(); - - bool hasSkybox = false; - - switch (zone->getBackgroundMode()) { - case BACKGROUND_MODE_SKYBOX: - hasSkybox = true; - - skybox->setColor(zone->getSkyboxProperties().getColorVec3()); - - if (_zoneUserData != zone->getUserData()) { - _zoneUserData = zone->getUserData(); - std::dynamic_pointer_cast(skybox)->parse(_zoneUserData); - } - - _skyboxTextureURL = zone->getSkyboxProperties().getURL(); - if (_skyboxTextureURL.isEmpty()) { - _pendingSkyboxTexture = false; - _skyboxTexture.clear(); - } else { - _pendingSkyboxTexture = true; - } - - applySkyboxAndHasAmbient(); - skyStage->setBackgroundMode(model::SunSkyStage::SKY_BOX); - - break; - - case BACKGROUND_MODE_INHERIT: - default: - // Clear the skybox to release its textures - skybox->clear(); - _zoneUserData = QString(); - - _pendingSkyboxTexture = false; - _skyboxTexture.clear(); - - // Let the application background through - if (applySkyboxAndHasAmbient()) { - skyStage->setBackgroundMode(model::SunSkyStage::SKY_DEFAULT_TEXTURE); - } else { - skyStage->setBackgroundMode(model::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE); - } - - break; - } - - return hasSkybox; -}*/ -/* -bool EntityTreeRenderer::applySkyboxAndHasAmbient() { - auto textureCache = DependencyManager::get(); - auto scene = DependencyManager::get(); - auto sceneStage = scene->getStage(); - auto skyStage = scene->getSkyStage(); - auto sceneKeyLight = sceneStage->getKeyLight(); - auto skybox = skyStage->getSkybox(); - - bool isAmbientSet = false; - if (_pendingAmbientTexture && !_ambientTexture) { - _ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::CUBE_TEXTURE); - } - if (_ambientTexture && _ambientTexture->isLoaded()) { - _pendingAmbientTexture = false; - - auto texture = _ambientTexture->getGPUTexture(); - if (texture) { - isAmbientSet = true; - sceneKeyLight->setAmbientSphere(texture->getIrradiance()); - sceneKeyLight->setAmbientMap(texture); - } else { - qCDebug(entitiesrenderer) << "Failed to load ambient texture:" << _ambientTexture->getURL(); - } - } - - if (_pendingSkyboxTexture && - (!_skyboxTexture || (_skyboxTexture->getURL() != _skyboxTextureURL))) { - _skyboxTexture = textureCache->getTexture(_skyboxTextureURL, image::TextureUsage::CUBE_TEXTURE); - } - if (_skyboxTexture && _skyboxTexture->isLoaded()) { - _pendingSkyboxTexture = false; - - auto texture = _skyboxTexture->getGPUTexture(); - if (texture) { - skybox->setCubemap(texture); - if (!isAmbientSet) { - sceneKeyLight->setAmbientSphere(texture->getIrradiance()); - sceneKeyLight->setAmbientMap(texture); - isAmbientSet = true; - } - } else { - qCDebug(entitiesrenderer) << "Failed to load skybox texture:" << _skyboxTexture->getURL(); - skybox->setCubemap(nullptr); - } - } else { - skybox->setCubemap(nullptr); - } - - if (!isAmbientSet) { - sceneKeyLight->resetAmbientSphere(); - sceneKeyLight->setAmbientMap(nullptr); - } - - return isAmbientSet; -}*/ - const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer entityItem) { const FBXGeometry* result = NULL; @@ -1168,8 +988,6 @@ std::pair EntityTreeRenderer:: void EntityTreeRenderer::LayeredZones::apply() { assert(_entityTreeRenderer); - - // applyPartial(begin()); } void EntityTreeRenderer::LayeredZones::update(std::shared_ptr zone) { @@ -1184,12 +1002,6 @@ void EntityTreeRenderer::LayeredZones::update(std::shared_ptr zo } else { LayeredZone zoneLayer(zone); - // should we update? only if this zone is tighter than the current skybox zone - bool shouldUpdate = false; - if (_skyboxLayer == end() || zoneLayer <= *_skyboxLayer) { - shouldUpdate = true; - } - // find this zone's layer, if it exists iterator layer = end(); auto it = _map.find(zoneLayer.id); @@ -1209,41 +1021,9 @@ void EntityTreeRenderer::LayeredZones::update(std::shared_ptr zo std::tie(layer, std::ignore) = insert(zoneLayer); _map.emplace(layer->id, layer); } - - if (shouldUpdate) { - // applyPartial(layer); - } } } -/* -void EntityTreeRenderer::LayeredZones::applyPartial(iterator layer) { - bool hasSkybox = false; - _skyboxLayer = end(); - if (layer == end()) { - if (empty()) { - _entityTreeRenderer->applyZoneAndHasSkybox(nullptr); - return; - } else { // a layer was removed - reapply from beginning - layer = begin(); - } - } - - if (layer == begin()) { - hasSkybox = _entityTreeRenderer->applyZoneAndHasSkybox(layer->zone); - } else { - hasSkybox = _entityTreeRenderer->layerZoneAndHasSkybox(layer->zone); - } - - if (layer != end()) { - while (!hasSkybox && ++layer != end()) { - hasSkybox = _entityTreeRenderer->layerZoneAndHasSkybox(layer->zone); - } - } - - _skyboxLayer = layer; -} -*/ bool EntityTreeRenderer::LayeredZones::contains(const LayeredZones& other) { bool result = std::equal(other.begin(), other._skyboxLayer, begin()); if (result) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 92235b1a00..bf4148212b 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -147,9 +147,6 @@ private: void addEntityToScene(EntityItemPointer entity); bool findBestZoneAndMaybeContainingEntities(QVector* entitiesContainingAvatar = nullptr); - // bool applyZoneAndHasSkybox(const std::shared_ptr& zone); - // bool layerZoneAndHasSkybox(const std::shared_ptr& zone); - // bool applySkyboxAndHasAmbient(); bool applyLayeredZones(); void checkAndCallPreload(const EntityItemID& entityID, bool reload = false, bool unloadFirst = false); @@ -223,7 +220,7 @@ private: std::shared_ptr getZone() { return empty() ? nullptr : begin()->zone; } private: - // void applyPartial(iterator layer); + void applyPartial(iterator layer); std::map _map; iterator _skyboxLayer{ end() }; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 7825a50f25..c4960f0cfa 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -245,28 +245,6 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { _model->removeFromScene(scene, transaction); scene->enqueueTransaction(transaction); } - - /* - { - // Set the keylight - sceneKeyLight->setColor(ColorUtils::toVec3(this->getKeyLightProperties().getColor())); - sceneKeyLight->setIntensity(this->getKeyLightProperties().getIntensity()); - sceneKeyLight->setAmbientIntensity(this->getKeyLightProperties().getAmbientIntensity()); - sceneKeyLight->setDirection(this->getKeyLightProperties().getDirection()); - - // Set the stage - bool isSunModelEnabled = this->getStageProperties().getSunModelEnabled(); - sceneStage->setSunModelEnable(isSunModelEnabled); - if (isSunModelEnabled) { - sceneStage->setLocation(this->getStageProperties().getLongitude(), - this->getStageProperties().getLatitude(), - this->getStageProperties().getAltitude()); - - auto sceneTime = sceneStage->getTime(); - sceneTime->setHour(this->getStageProperties().calculateHour()); - sceneTime->setDay(this->getStageProperties().calculateDay()); - } - }*/ } bool RenderableZoneEntityItem::contains(const glm::vec3& point) const { @@ -289,6 +267,9 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render:: auto renderData = std::make_shared(self); auto renderPayload = std::make_shared(renderData); updateKeyZoneItemFromEntity((*renderData)); + updateKeySunFromEntity((*renderData)); + updateKeyAmbientFromEntity((*renderData)); + updateKeyBackgroundFromEntity((*renderData)); render::Item::Status::Getters statusGetters; makeEntityItemStatusGetters(getThisPointer(), statusGetters); @@ -373,6 +354,22 @@ void RenderableZoneEntityItem::updateKeyZoneItemFromEntity(RenderableZoneEntityI if (!success) { keyZonePayload.editBound() = render::Item::Bound(); } + + /* TODO: Implement the sun model behavior / Keep this code here for reference, this is how we + { + // Set the stage + bool isSunModelEnabled = this->getStageProperties().getSunModelEnabled(); + sceneStage->setSunModelEnable(isSunModelEnabled); + if (isSunModelEnabled) { + sceneStage->setLocation(this->getStageProperties().getLongitude(), + this->getStageProperties().getLatitude(), + this->getStageProperties().getAltitude()); + + auto sceneTime = sceneStage->getTime(); + sceneTime->setHour(this->getStageProperties().calculateHour()); + sceneTime->setDay(this->getStageProperties().calculateDay()); + } + }*/ } diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 730aa547e7..ff4621a87a 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -64,6 +64,7 @@ Column { "Point:LightingModel:enablePointLight", "Spot:LightingModel:enableSpotLight", "Light Contour:LightingModel:showLightContour", + "Zone Stack:DrawZoneStack:enabled", "Shadow:RenderShadowTask:enabled" ] CheckBox { From cba913c06828dea77cc153b6577e8f0e8ea1502a Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 25 May 2017 13:01:54 -0700 Subject: [PATCH 22/22] Fixing the case when the bound changes without the rest of the properties --- .../src/RenderableZoneEntityItem.cpp | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index c4960f0cfa..3f7c0937e2 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -145,10 +145,7 @@ void RenderableZoneEntityItem::somethingChangedNotification() { DependencyManager::get()->updateZone(_id); // If graphics elements are changed, we need to update the render items - if (_keyLightPropertiesChanged || _backgroundPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged) { - - notifyChangedRenderItem(); - } + notifyChangedRenderItem(); // Poopagate back to parent ZoneEntityItem::somethingChangedNotification(); @@ -290,17 +287,7 @@ void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const ren } void RenderableZoneEntityItem::notifyBoundChanged() { - if (!render::Item::isValidID(_myMetaItem)) { - return; - } - render::Transaction transaction; - render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); - if (scene) { - transaction.updateItem(_myMetaItem, [](RenderableZoneEntityItemMeta& data) {}); - scene->enqueueTransaction(transaction); - } else { - qCWarning(entitiesrenderer) << "RenderableZoneEntityItem::notifyBoundChanged(), Unexpected null scene, possibly during application shutdown"; - } + notifyChangedRenderItem(); } void RenderableZoneEntityItem::updateKeySunFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) {