From b5da8e7d5cf2aad1f2a171d32cd354151752cd4d Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Wed, 26 Jun 2024 22:37:30 -0700 Subject: [PATCH] wip ambient occlusion --- .../src/scripting/RenderScriptingInterface.h | 13 +- .../src/RenderableZoneEntityItem.cpp | 2 +- .../src/AmbientOcclusionPropertyGroup.cpp | 32 +-- .../src/AmbientOcclusionPropertyGroup.h | 17 +- .../entities/src/EntityItemProperties.cpp | 13 +- libraries/entities/src/EntityPropertyFlags.h | 2 +- libraries/entities/src/ZoneEntityItem.cpp | 4 +- .../graphics/src/graphics/AmbientOcclusion.h | 6 +- .../src/AmbientOcclusionEffect.cpp | 183 +++++++++--------- .../render-utils/src/AmbientOcclusionEffect.h | 78 ++++---- .../src/DeferredLightingEffect.cpp | 10 - .../render-utils/src/DeferredLightingEffect.h | 2 - libraries/render-utils/src/LightingModel.h | 93 ++++----- libraries/render-utils/src/ZoneRenderer.cpp | 1 + .../utilities/render/ambientOcclusionPass.qml | 5 +- .../create/assets/data/createAppTooltips.json | 33 ++++ .../html/js/entityProperties.js | 74 ++++++- .../html/tabs/zone_ambient_occlusion.png | Bin 0 -> 785 bytes .../html/tabs/zone_tonemapping.png | Bin 0 -> 673 bytes 19 files changed, 338 insertions(+), 230 deletions(-) create mode 100644 scripts/system/create/entityProperties/html/tabs/zone_ambient_occlusion.png create mode 100644 scripts/system/create/entityProperties/html/tabs/zone_tonemapping.png diff --git a/interface/src/scripting/RenderScriptingInterface.h b/interface/src/scripting/RenderScriptingInterface.h index 2025c71510..73ef077c3c 100644 --- a/interface/src/scripting/RenderScriptingInterface.h +++ b/interface/src/scripting/RenderScriptingInterface.h @@ -233,18 +233,17 @@ private: mutable ReadWriteLockable _renderSettingLock; // Runtime value of each settings - int _renderMethod{ RENDER_FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED }; - bool _shadowsEnabled{ true }; - bool _ambientOcclusionEnabled{ false }; - AntialiasingConfig::Mode _antialiasingMode{ AntialiasingConfig::Mode::NONE }; - float _viewportResolutionScale{ 1.0f }; + int _renderMethod { RENDER_FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED }; + bool _shadowsEnabled { true }; + bool _ambientOcclusionEnabled { true }; + AntialiasingConfig::Mode _antialiasingMode { AntialiasingConfig::Mode::NONE }; + float _viewportResolutionScale { 1.0f }; QString _fullScreenScreen; - // Actual settings saved on disk Setting::Handle _renderMethodSetting { "renderMethod", RENDER_FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED }; Setting::Handle _shadowsEnabledSetting { "shadowsEnabled", true }; - Setting::Handle _ambientOcclusionEnabledSetting { "ambientOcclusionEnabled", false }; + Setting::Handle _ambientOcclusionEnabledSetting { "ambientOcclusionEnabled", true }; //Setting::Handle _antialiasingModeSetting { "antialiasingMode", AntialiasingConfig::Mode::TAA }; Setting::Handle _antialiasingModeSetting { "antialiasingMode", AntialiasingConfig::Mode::NONE }; Setting::Handle _viewportResolutionScaleSetting { "viewportResolutionScale", 1.0f }; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 9bc6de6627..8a6768f235 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -450,7 +450,7 @@ void ZoneEntityRenderer::updateAmbientOcclusionFromEntity(const TypedEntityPoint ambientOcclusion->setAORadius(_ambientOcclusionProperties.getAORadius()); ambientOcclusion->setAOObscuranceLevel(_ambientOcclusionProperties.getAOObscuranceLevel()); ambientOcclusion->setAOFalloffAngle(_ambientOcclusionProperties.getAOFalloffAngle()); - ambientOcclusion->setAONumSamples(_ambientOcclusionProperties.getAONumSamples()); + ambientOcclusion->setAOSamplingAmount(_ambientOcclusionProperties.getAOSamplingAmount()); ambientOcclusion->setSSAONumSpiralTurns(_ambientOcclusionProperties.getSSAONumSpiralTurns()); } diff --git a/libraries/entities/src/AmbientOcclusionPropertyGroup.cpp b/libraries/entities/src/AmbientOcclusionPropertyGroup.cpp index b5617cabb0..c16f2a00f3 100644 --- a/libraries/entities/src/AmbientOcclusionPropertyGroup.cpp +++ b/libraries/entities/src/AmbientOcclusionPropertyGroup.cpp @@ -43,7 +43,7 @@ void AmbientOcclusionPropertyGroup::copyToScriptValue(const EntityPropertyFlags& COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_AO_RADIUS, AmbientOcclusion, ambientOcclusion, AORadius, aoRadius); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL, AmbientOcclusion, ambientOcclusion, AOObscuranceLevel, aoObscuranceLevel); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE, AmbientOcclusion, ambientOcclusion, AOFalloffAngle, aoFalloffAngle); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES, AmbientOcclusion, ambientOcclusion, AONumSamples, aoNumSamples); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT, AmbientOcclusion, ambientOcclusion, AOSamplingAmount, aoSamplingAmount); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, AmbientOcclusion, ambientOcclusion, SSAONumSpiralTurns, ssaoNumSpiralTurns); } @@ -56,7 +56,7 @@ void AmbientOcclusionPropertyGroup::copyFromScriptValue(const ScriptValue& objec COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, aoRadius, float, setAORadius); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, aoObscuranceLevel, float, setAOObscuranceLevel); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, aoFalloffAngle, float, setAOFalloffAngle); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, aoNumSamples, uint8_t, setAONumSamples); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, aoSamplingAmount, float, setAOSamplingAmount); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, ssaoNumSpiralTurns, float, setSSAONumSpiralTurns); } @@ -69,7 +69,7 @@ void AmbientOcclusionPropertyGroup::merge(const AmbientOcclusionPropertyGroup& o COPY_PROPERTY_IF_CHANGED(aoRadius); COPY_PROPERTY_IF_CHANGED(aoObscuranceLevel); COPY_PROPERTY_IF_CHANGED(aoFalloffAngle); - COPY_PROPERTY_IF_CHANGED(aoNumSamples); + COPY_PROPERTY_IF_CHANGED(aoSamplingAmount); COPY_PROPERTY_IF_CHANGED(ssaoNumSpiralTurns); } @@ -83,7 +83,7 @@ void AmbientOcclusionPropertyGroup::debugDump() const { qCDebug(entities) << " AORadius:" << getAORadius(); qCDebug(entities) << " AOObscuranceLevel:" << getAOObscuranceLevel(); qCDebug(entities) << " AOFalloffAngle:" << getAOFalloffAngle(); - qCDebug(entities) << " AONumSamples:" << getAONumSamples(); + qCDebug(entities) << " AOSamplingAmount:" << getAOSamplingAmount(); qCDebug(entities) << " SSAONumSpiralTurns:" << getSSAONumSpiralTurns(); } @@ -112,8 +112,8 @@ void AmbientOcclusionPropertyGroup::listChangedProperties(QList& out) { if (aoFalloffAngleChanged()) { out << "ambientOcclusion-aoFalloffAngle"; } - if (aoNumSamplesChanged()) { - out << "ambientOcclusion-aoNumSamples"; + if (aoSamplingAmountChanged()) { + out << "ambientOcclusion-aoSamplingAmount"; } if (ssaoNumSpiralTurnsChanged()) { out << "ambientOcclusion-ssaoNumSpiralTurns"; @@ -137,7 +137,7 @@ bool AmbientOcclusionPropertyGroup::appendToEditPacket(OctreePacketData* packetD APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_RADIUS, getAORadius()); APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL, getAOObscuranceLevel()); APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE, getAOFalloffAngle()); - APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES, getAONumSamples()); + APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT, getAOSamplingAmount()); APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, getSSAONumSpiralTurns()); return true; @@ -157,7 +157,7 @@ bool AmbientOcclusionPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& pr READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_RADIUS, float, setAORadius); READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL, float, setAOObscuranceLevel); READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE, float, setAOFalloffAngle); - READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES, uint8_t, setAONumSamples); + READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT, float, setAOSamplingAmount); READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, float, setSSAONumSpiralTurns); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_TECHNIQUE, Technique); @@ -168,7 +168,7 @@ bool AmbientOcclusionPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& pr DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_AO_RADIUS, AORadius); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL, AOObscuranceLevel); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE, AOFalloffAngle); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES, AONumSamples); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT, AOSamplingAmount); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, SSAONumSpiralTurns); processedBytes += bytesRead; @@ -187,7 +187,7 @@ void AmbientOcclusionPropertyGroup::markAllChanged() { _aoRadiusChanged = true; _aoObscuranceLevelChanged = true; _aoFalloffAngleChanged = true; - _aoNumSamplesChanged = true; + _aoSamplingAmountChanged = true; _ssaoNumSpiralTurnsChanged = true; } @@ -202,7 +202,7 @@ EntityPropertyFlags AmbientOcclusionPropertyGroup::getChangedProperties() const CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_AO_RADIUS, aoRadius); CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL, aoObscuranceLevel); CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE, aoFalloffAngle); - CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES, aoNumSamples); + CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT, aoSamplingAmount); CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, ssaoNumSpiralTurns); return changedProperties; @@ -217,7 +217,7 @@ void AmbientOcclusionPropertyGroup::getProperties(EntityItemProperties& properti COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, AORadius, getAORadius); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, AOObscuranceLevel, getAOObscuranceLevel); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, AOFalloffAngle, getAOFalloffAngle); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, AONumSamples, getAONumSamples); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, AOSamplingAmount, getAOSamplingAmount); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, SSAONumSpiralTurns, getSSAONumSpiralTurns); } @@ -232,7 +232,7 @@ bool AmbientOcclusionPropertyGroup::setProperties(const EntityItemProperties& pr SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, AORadius, aoRadius, setAORadius); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, AOObscuranceLevel, aoObscuranceLevel, setAOObscuranceLevel); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, AOFalloffAngle, aoFalloffAngle, setAOFalloffAngle); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, AONumSamples, aoNumSamples, setAONumSamples); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, AOSamplingAmount, aoSamplingAmount, setAOSamplingAmount); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, SSAONumSpiralTurns, ssaoNumSpiralTurns, setSSAONumSpiralTurns); return somethingChanged; @@ -249,7 +249,7 @@ EntityPropertyFlags AmbientOcclusionPropertyGroup::getEntityProperties(EncodeBit requestedProperties += PROP_AMBIENT_OCCLUSION_AO_RADIUS; requestedProperties += PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL; requestedProperties += PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE; - requestedProperties += PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES; + requestedProperties += PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT; requestedProperties += PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS; return requestedProperties; @@ -273,7 +273,7 @@ void AmbientOcclusionPropertyGroup::appendSubclassData(OctreePacketData* packetD APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_RADIUS, getAORadius()); APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL, getAOObscuranceLevel()); APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE, getAOFalloffAngle()); - APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES, getAONumSamples()); + APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT, getAOSamplingAmount()); APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, getSSAONumSpiralTurns()); } @@ -293,7 +293,7 @@ int AmbientOcclusionPropertyGroup::readEntitySubclassDataFromBuffer(const unsign READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_RADIUS, float, setAORadius); READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL, float, setAOObscuranceLevel); READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE, float, setAOFalloffAngle); - READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES, uint8_t, setAONumSamples); + READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT, float, setAOSamplingAmount); READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, float, setSSAONumSpiralTurns); return bytesRead; diff --git a/libraries/entities/src/AmbientOcclusionPropertyGroup.h b/libraries/entities/src/AmbientOcclusionPropertyGroup.h index 9a44c5c8f0..c1a734c9a4 100644 --- a/libraries/entities/src/AmbientOcclusionPropertyGroup.h +++ b/libraries/entities/src/AmbientOcclusionPropertyGroup.h @@ -29,9 +29,20 @@ class ScriptValue; /*@jsdoc * AmbientOcclusion is defined by the following properties: * @typedef {object} Entities.AmbientOcclusion - * @property {AmbientOcclusionTechnique} technique="ssao" - The AO technique used. - * TODO + * @property {AmbientOcclusionTechnique} technique="ssao" - The ambient occlusion technique used. Different techniques have + * different tradeoffs. + * @property {boolean} jitter=false - Whether or not the ambient occlusion sampling is jittered. + * @property {number} resolutionLevel=2 - How high the resolution of the ambient occlusion buffer should be. Higher levels + * mean lower resolution buffers. + * @property {number} edgeSharpness=1.0 - How much to sharpen the edges during the ambient occlusion blurring. + * @property {number} blurRadius=4 - The radius used for blurring, in pixels. + * @property {number} aoRadius=1.0 - The radius used for ambient occlusion. + * @property {number} aoObscuranceLevel=0.5 - Intensify or dim ambient occlusion. + * @property {number} aoFalloffAngle=0.25 - The falloff angle for the AO calculation. + * @property {number} aoSamplingAmount=0.5 - The fraction of AO samples to use, out of the maximum for each technique. + * @property {number} ssaoNumSpiralTurns=7.0 - The angle span used to distribute the AO samples ray directions. SSAO only. */ + class AmbientOcclusionPropertyGroup : public PropertyGroup { public: // EntityItemProperty related helpers @@ -88,7 +99,7 @@ public: DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_RADIUS, AORadius, aoRadius, float, 1.0f); DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL, AOObscuranceLevel, aoObscuranceLevel, float, 0.5f); DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE, AOFalloffAngle, aoFalloffAngle, float, 0.25f); - DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES, AONumSamples, aoNumSamples, uint8_t, 32); + DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT, AOSamplingAmount, aoSamplingAmount, float, 0.5f); DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, SSAONumSpiralTurns, ssaoNumSpiralTurns, float, 7.0f); }; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 4f70d88d8b..1360ab5a58 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -3051,10 +3051,19 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr } { // Tonemapping ADD_GROUP_PROPERTY_TO_MAP(PROP_TONEMAPPING_CURVE, Tonemapping, tonemapping, Curve, curve); - ADD_GROUP_PROPERTY_TO_MAP(PROP_TONEMAPPING_EXPOSURE, Tonemapping, tonemapping, Exposure, exposure); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_TONEMAPPING_EXPOSURE, Tonemapping, tonemapping, Exposure, exposure, -4.0f, -4.0f); } { // Ambient Occlusion - // TODO + ADD_GROUP_PROPERTY_TO_MAP(PROP_AMBIENT_OCCLUSION_TECHNIQUE, AmbientOcclusion, ambientOcclusion, Technique, technique); + ADD_GROUP_PROPERTY_TO_MAP(PROP_AMBIENT_OCCLUSION_JITTER, AmbientOcclusion, ambientOcclusion, Jitter, jitter); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL, AmbientOcclusion, ambientOcclusion, ResolutionLevel, resolutionLevel, 0, 4); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS, AmbientOcclusion, ambientOcclusion, EdgeSharpness, edgeSharpness, 0.0f, 1.0f); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_AMBIENT_OCCLUSION_BLUR_RADIUS, AmbientOcclusion, ambientOcclusion, BlurRadius, blurRadius, 0, 15); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_AMBIENT_OCCLUSION_AO_RADIUS, AmbientOcclusion, ambientOcclusion, AORadius, aoRadius, 0.01f, 2.0f); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL, AmbientOcclusion, ambientOcclusion, AOObscuranceLevel, aoObscuranceLevel, 0.01f, 1.0f); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE, AmbientOcclusion, ambientOcclusion, AOFalloffAngle, aoFalloffAngle, 0.0f, 1.0f); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT, AmbientOcclusion, ambientOcclusion, AOSamplingAmount, aoSamplingAmount, 0.0f, 1.0f); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, AmbientOcclusion, ambientOcclusion, SSAONumSpiralTurns, ssaoNumSpiralTurns, 0.0f, 10.0f); } ADD_PROPERTY_TO_MAP(PROP_FLYING_ALLOWED, FlyingAllowed, flyingAllowed, bool); ADD_PROPERTY_TO_MAP(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 87517bdd3a..f8c1790fc6 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -355,7 +355,7 @@ enum EntityPropertyList { PROP_AMBIENT_OCCLUSION_AO_RADIUS = PROP_DERIVED_50, PROP_AMBIENT_OCCLUSION_AO_OBSCURANCE_LEVEL = PROP_DERIVED_51, PROP_AMBIENT_OCCLUSION_AO_FALLOFF_ANGLE = PROP_DERIVED_52, - PROP_AMBIENT_OCCLUSION_AO_NUM_SAMPLES = PROP_DERIVED_53, + PROP_AMBIENT_OCCLUSION_AO_SAMPLING_AMOUNT = PROP_DERIVED_53, PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS = PROP_DERIVED_54, // Polyvox diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index ee431493a8..a8561f49d9 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -292,8 +292,8 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits APPEND_ENTITY_PROPERTY(PROP_BLOOM_MODE, getBloomMode()); APPEND_ENTITY_PROPERTY(PROP_AVATAR_PRIORITY, getAvatarPriority()); APPEND_ENTITY_PROPERTY(PROP_SCREENSHARE, getScreenshare()); - APPEND_ENTITY_PROPERTY(PROP_TONEMAPPING_MODE, getHazeMode()); - APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_MODE, getBloomMode()); + APPEND_ENTITY_PROPERTY(PROP_TONEMAPPING_MODE, getTonemappingMode()); + APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_MODE, getAmbientOcclusionMode()); } void ZoneEntityItem::debugDump() const { diff --git a/libraries/graphics/src/graphics/AmbientOcclusion.h b/libraries/graphics/src/graphics/AmbientOcclusion.h index 7579b783a3..66a1ad0ea7 100644 --- a/libraries/graphics/src/graphics/AmbientOcclusion.h +++ b/libraries/graphics/src/graphics/AmbientOcclusion.h @@ -28,7 +28,7 @@ namespace graphics { void setAORadius(const float aoRadius) { _aoRadius = aoRadius; } void setAOObscuranceLevel(const float aoObscuranceLevel) { _aoObscuranceLevel = aoObscuranceLevel; } void setAOFalloffAngle(const float aoFalloffAngle) { _aoFalloffAngle = aoFalloffAngle; } - void setAONumSamples(const uint8_t aoNumSamples) { _aoNumSamples = aoNumSamples; } + void setAOSamplingAmount(const float aoSamplingAmount) { _aoSamplingAmount = aoSamplingAmount; } void setSSAONumSpiralTurns(const float ssaoNumSpiralTurns) { _ssaoNumSpiralTurns = ssaoNumSpiralTurns; } AmbientOcclusionTechnique getTechnique() const { return _technique; } @@ -39,7 +39,7 @@ namespace graphics { float getAORadius() const { return _aoRadius; } float getAOObscuranceLevel() const { return _aoObscuranceLevel; } float getAOFalloffAngle() const { return _aoFalloffAngle; } - uint8_t getAONumSamples() const { return _aoNumSamples; } + float getAOSamplingAmount() const { return _aoSamplingAmount; } float getSSAONumSpiralTurns() const { return _ssaoNumSpiralTurns; } private: @@ -51,7 +51,7 @@ namespace graphics { float _aoRadius { 1.0f }; float _aoObscuranceLevel { 0.5f }; float _aoFalloffAngle { 0.25f }; - uint8_t _aoNumSamples { 32 }; + float _aoSamplingAmount { 0.5f }; float _ssaoNumSpiralTurns { 7.0f }; }; using AmbientOcclusionPointer = std::shared_ptr; diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 68eb1b5a06..8c14b0b0ef 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -37,6 +37,9 @@ gpu::PipelinePointer AmbientOcclusionEffect::_mipCreationPipeline; gpu::PipelinePointer AmbientOcclusionEffect::_gatherPipeline; gpu::PipelinePointer AmbientOcclusionEffect::_buildNormalsPipeline; +#define MAX_SSAO_SAMPLES 64.0f +#define MAX_HBAO_SAMPLES 6.0f + AmbientOcclusionFramebuffer::AmbientOcclusionFramebuffer() { } @@ -205,29 +208,7 @@ gpu::TexturePointer AmbientOcclusionFramebuffer::getNormalTexture() { } AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() : - render::GPUJobConfig::Persistent(QStringList() << "Render" << "Engine" << "Ambient Occlusion"), - perspectiveScale{ 1.0f }, - edgeSharpness{ 1.0f }, - blurRadius{ 4 }, - resolutionLevel{ 2 }, - - ssaoRadius{ 1.0f }, - ssaoObscuranceLevel{ 0.4f }, - ssaoFalloffAngle{ 0.15f }, - ssaoNumSpiralTurns{ 7.0f }, - ssaoNumSamples{ 32 }, - - hbaoRadius{ 0.7f }, - hbaoObscuranceLevel{ 0.75f }, - hbaoFalloffAngle{ 0.3f }, - hbaoNumSamples{ 1 }, - - horizonBased{ false }, - ditheringEnabled{ true }, - borderingEnabled{ true }, - fetchMipsEnabled{ true }, - jitterEnabled{ false }{ -} + render::GPUJobConfig::Persistent(QStringList() << "Render" << "Engine" << "Ambient Occlusion") {} void AmbientOcclusionEffectConfig::setSSAORadius(float newRadius) { ssaoRadius = std::max(0.01f, newRadius); emit dirty(); @@ -288,89 +269,105 @@ void AmbientOcclusionEffectConfig::setBlurRadius(int radius) { } AmbientOcclusionEffect::AOParameters::AOParameters() { - _resolutionInfo = glm::vec4{ 0.0f }; - _radiusInfo = glm::vec4{ 0.0f }; - _ditheringInfo = glm::vec4{ 0.0f }; - _sampleInfo = glm::vec4{ 0.0f }; - _falloffInfo = glm::vec4{ 0.0f }; + _resolutionInfo = glm::vec4(0.0f); + _radiusInfo = glm::vec4(0.0f); + _ditheringInfo = glm::vec4(0.0f); + _sampleInfo = glm::vec4(0.0f); + _falloffInfo = glm::vec4(0.0f); } AmbientOcclusionEffect::BlurParameters::BlurParameters() { _blurInfo = { 1.0f, 2.0f, 0.0f, 3.0f }; } -AmbientOcclusionEffect::AmbientOcclusionEffect() { +void AmbientOcclusionEffect::configure(const Config& config) { + _debug = config.debug; + _debugAmbientOcclusion->setTechnique(config.horizonBased ? AmbientOcclusionTechnique::HBAO : AmbientOcclusionTechnique::SSAO); + _debugAmbientOcclusion->setJitter(config.jitterEnabled); + _debugAmbientOcclusion->setResolutionLevel(config.resolutionLevel); + _debugAmbientOcclusion->setEdgeSharpness(config.edgeSharpness); + _debugAmbientOcclusion->setBlurRadius(config.blurRadius); + _debugAmbientOcclusion->setAORadius(config.horizonBased ? config.hbaoRadius : config.ssaoRadius); + _debugAmbientOcclusion->setAOObscuranceLevel(config.horizonBased ? config.hbaoObscuranceLevel : config.ssaoObscuranceLevel); + _debugAmbientOcclusion->setAOFalloffAngle(config.horizonBased ? config.hbaoFalloffAngle : config.ssaoFalloffAngle); + _debugAmbientOcclusion->setAOSamplingAmount(config.horizonBased ? (config.hbaoNumSamples / MAX_HBAO_SAMPLES) : + (config.ssaoNumSamples / MAX_SSAO_SAMPLES)); + _debugAmbientOcclusion->setSSAONumSpiralTurns(config.ssaoNumSpiralTurns); + + _perspectiveScale = config.perspectiveScale; + _ditheringEnabled = config.ditheringEnabled; + _borderingEnabled = config.borderingEnabled; + _fetchMipsEnabled = config.fetchMipsEnabled; } -void AmbientOcclusionEffect::configure(const Config& config) { +void AmbientOcclusionEffect::updateParameters(const graphics::AmbientOcclusionPointer ambientOcclusion) { bool shouldUpdateBlurs = false; bool shouldUpdateTechnique = false; - _isJitterEnabled = config.jitterEnabled; - if (!_framebuffer) { _framebuffer = std::make_shared(); shouldUpdateBlurs = true; } // Update bilateral blur - if (config.blurRadius != _hblurParametersBuffer->getBlurRadius() || _blurEdgeSharpness != config.edgeSharpness) { + if (ambientOcclusion->getBlurRadius() != _hblurParametersBuffer->getBlurRadius() || _blurEdgeSharpness != ambientOcclusion->getEdgeSharpness()) { const float BLUR_EDGE_DISTANCE_SCALE = float(10000 * SSAO_DEPTH_KEY_SCALE); const float BLUR_EDGE_NORMAL_SCALE = 2.0f; auto& hblur = _hblurParametersBuffer.edit()._blurInfo; auto& vblur = _vblurParametersBuffer.edit()._blurInfo; - float blurRadialSigma = float(config.blurRadius) * 0.5f; + float blurRadialSigma = float(ambientOcclusion->getBlurRadius()) * 0.5f; float blurRadialScale = 1.0f / (2.0f*blurRadialSigma*blurRadialSigma); - glm::vec3 blurScales = -glm::vec3(blurRadialScale, glm::vec2(BLUR_EDGE_DISTANCE_SCALE, BLUR_EDGE_NORMAL_SCALE) * config.edgeSharpness); + glm::vec3 blurScales = -glm::vec3(blurRadialScale, glm::vec2(BLUR_EDGE_DISTANCE_SCALE, BLUR_EDGE_NORMAL_SCALE) * ambientOcclusion->getEdgeSharpness()); - _blurEdgeSharpness = config.edgeSharpness; + _blurEdgeSharpness = ambientOcclusion->getEdgeSharpness(); hblur.x = blurScales.x; hblur.y = blurScales.y; hblur.z = blurScales.z; - hblur.w = (float)config.blurRadius; + hblur.w = (float)ambientOcclusion->getBlurRadius(); vblur.x = blurScales.x; vblur.y = blurScales.y; vblur.z = blurScales.z; - vblur.w = (float)config.blurRadius; + vblur.w = (float)ambientOcclusion->getBlurRadius(); } - if (_aoParametersBuffer->isHorizonBased() != config.horizonBased) { + if (_perspectiveScale != _aoParametersBuffer->getPerspectiveScale()) { + _aoParametersBuffer.edit()._resolutionInfo.z = _perspectiveScale; + } + + if (_ditheringEnabled != _aoParametersBuffer->isDitheringEnabled()) { + auto& current = _aoParametersBuffer.edit()._ditheringInfo; + current.x = (float)_ditheringEnabled; + } + + if (_borderingEnabled != _aoParametersBuffer->isBorderingEnabled()) { + auto& current = _aoParametersBuffer.edit()._ditheringInfo; + current.w = (float)_borderingEnabled; + } + + if (_fetchMipsEnabled != _aoParametersBuffer->isFetchMipsEnabled()) { + auto& current = _aoParametersBuffer.edit()._sampleInfo; + current.w = (float)_fetchMipsEnabled; + } + + bool horizonBased = ambientOcclusion->getTechnique() == AmbientOcclusionTechnique::HBAO; + if (_aoParametersBuffer->isHorizonBased() != horizonBased) { auto& current = _aoParametersBuffer.edit()._resolutionInfo; - current.y = config.horizonBased & 1; + current.y = horizonBased & 1; shouldUpdateTechnique = true; } - if (config.fetchMipsEnabled != _aoParametersBuffer->isFetchMipsEnabled()) { - auto& current = _aoParametersBuffer.edit()._sampleInfo; - current.w = (float)config.fetchMipsEnabled; - } - - if (config.perspectiveScale != _aoParametersBuffer->getPerspectiveScale()) { - _aoParametersBuffer.edit()._resolutionInfo.z = config.perspectiveScale; - } - - if (config.resolutionLevel != _aoParametersBuffer->getResolutionLevel()) { + if (ambientOcclusion->getResolutionLevel() != _aoParametersBuffer->getResolutionLevel()) { auto& current = _aoParametersBuffer.edit()._resolutionInfo; - current.x = (float)config.resolutionLevel; + current.x = (float)ambientOcclusion->getResolutionLevel(); shouldUpdateBlurs = true; } - if (config.ditheringEnabled != _aoParametersBuffer->isDitheringEnabled()) { - auto& current = _aoParametersBuffer.edit()._ditheringInfo; - current.x = (float)config.ditheringEnabled; - } - - if (config.borderingEnabled != _aoParametersBuffer->isBorderingEnabled()) { - auto& current = _aoParametersBuffer.edit()._ditheringInfo; - current.w = (float)config.borderingEnabled; - } - - if (config.horizonBased) { + if (horizonBased) { // Configure for HBAO - const auto& radius = config.hbaoRadius; + const auto& radius = ambientOcclusion->getAORadius(); if (shouldUpdateTechnique || radius != _aoParametersBuffer->getRadius()) { auto& current = _aoParametersBuffer.edit()._radiusInfo; current.x = radius; @@ -378,31 +375,32 @@ void AmbientOcclusionEffect::configure(const Config& config) { current.z = 1.0f / current.y; } - if (shouldUpdateTechnique || config.hbaoObscuranceLevel != _aoParametersBuffer->getObscuranceLevel()) { + if (shouldUpdateTechnique || ambientOcclusion->getAOObscuranceLevel() != _aoParametersBuffer->getObscuranceLevel()) { auto& current = _aoParametersBuffer.edit()._radiusInfo; - current.w = config.hbaoObscuranceLevel; + current.w = ambientOcclusion->getAOObscuranceLevel(); } - if (shouldUpdateTechnique || config.hbaoFalloffAngle != _aoParametersBuffer->getFalloffAngle()) { + if (shouldUpdateTechnique || ambientOcclusion->getAOFalloffAngle() != _aoParametersBuffer->getFalloffAngle()) { auto& current = _aoParametersBuffer.edit()._falloffInfo; - current.x = config.hbaoFalloffAngle; + current.x = ambientOcclusion->getAOFalloffAngle(); current.y = 1.0f / (1.0f - current.x); // Compute sin from cos - current.z = sqrtf(1.0f - config.hbaoFalloffAngle * config.hbaoFalloffAngle); + current.z = sqrtf(1.0f - ambientOcclusion->getAOFalloffAngle() * ambientOcclusion->getAOFalloffAngle()); current.w = 1.0f / current.z; } - if (shouldUpdateTechnique || config.hbaoNumSamples != _aoParametersBuffer->getNumSamples()) { + const int numSamples = ambientOcclusion->getAOSamplingAmount() * MAX_SSAO_SAMPLES; + if (shouldUpdateTechnique || numSamples != _aoParametersBuffer->getNumSamples()) { auto& current = _aoParametersBuffer.edit()._sampleInfo; - current.x = config.hbaoNumSamples; - current.y = 1.0f / config.hbaoNumSamples; + current.x = numSamples; + current.y = 1.0f / numSamples; updateRandomSamples(); updateJitterSamples(); } } else { // Configure for SSAO const double RADIUS_POWER = 6.0; - const auto& radius = config.ssaoRadius; + const auto& radius = ambientOcclusion->getAORadius(); if (shouldUpdateTechnique || radius != _aoParametersBuffer->getRadius()) { auto& current = _aoParametersBuffer.edit()._radiusInfo; current.x = radius; @@ -410,25 +408,26 @@ void AmbientOcclusionEffect::configure(const Config& config) { current.z = (float)(10.0 / pow((double)radius, RADIUS_POWER)); } - if (shouldUpdateTechnique || config.ssaoObscuranceLevel != _aoParametersBuffer->getObscuranceLevel()) { + if (shouldUpdateTechnique || ambientOcclusion->getAOObscuranceLevel() != _aoParametersBuffer->getObscuranceLevel()) { auto& current = _aoParametersBuffer.edit()._radiusInfo; - current.w = config.ssaoObscuranceLevel; + current.w = ambientOcclusion->getAOObscuranceLevel(); } - if (shouldUpdateTechnique || config.ssaoFalloffAngle != _aoParametersBuffer->getFalloffAngle()) { + if (shouldUpdateTechnique || ambientOcclusion->getAOFalloffAngle() != _aoParametersBuffer->getFalloffAngle()) { auto& current = _aoParametersBuffer.edit()._falloffInfo; - current.x = config.ssaoFalloffAngle; + current.x = ambientOcclusion->getAOFalloffAngle(); } - if (shouldUpdateTechnique || config.ssaoNumSpiralTurns != _aoParametersBuffer->getNumSpiralTurns()) { + if (shouldUpdateTechnique || ambientOcclusion->getSSAONumSpiralTurns() != _aoParametersBuffer->getNumSpiralTurns()) { auto& current = _aoParametersBuffer.edit()._sampleInfo; - current.z = config.ssaoNumSpiralTurns; + current.z = ambientOcclusion->getSSAONumSpiralTurns(); } - if (shouldUpdateTechnique || config.ssaoNumSamples != _aoParametersBuffer->getNumSamples()) { + const int numSamples = ambientOcclusion->getAOSamplingAmount() * MAX_HBAO_SAMPLES; + if (shouldUpdateTechnique || numSamples != _aoParametersBuffer->getNumSamples()) { auto& current = _aoParametersBuffer.edit()._sampleInfo; - current.x = config.ssaoNumSamples; - current.y = 1.0f / config.ssaoNumSamples; + current.x = numSamples; + current.y = 1.0f / numSamples; updateRandomSamples(); updateJitterSamples(); } @@ -600,12 +599,23 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte RenderArgs* args = renderContext->args; const auto& lightingModel = input.get0(); + const auto ambientOcclusionFrame = input.get4(); - if (!lightingModel->isAmbientOcclusionEnabled()) { + const auto& ambientOcclusionStage = renderContext->_scene->getStage(); + graphics::AmbientOcclusionPointer ambientOcclusion; + if (_debug) { + ambientOcclusion = _debugAmbientOcclusion; + } else if (ambientOcclusionStage && ambientOcclusionFrame->_ambientOcclusions.size()) { + ambientOcclusion = ambientOcclusionStage->getAmbientOcclusion(ambientOcclusionFrame->_ambientOcclusions.front()); + } + + if (!ambientOcclusion || !lightingModel->isAmbientOcclusionEnabled()) { output.edit0().reset(); return; } + updateParameters(ambientOcclusion); + const auto& frameTransform = input.get1(); const auto& linearDepthFramebuffer = input.get3(); @@ -657,7 +667,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte #endif // Update sample rotation - if (_isJitterEnabled) { + if (ambientOcclusion->getJitter()) { updateJitterSamples(); _frameId = (_frameId + 1) % (SSAO_RANDOM_SAMPLE_COUNT); } @@ -831,11 +841,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte config->setGPUBatchRunTime(_gpuTimer->getGPUAverage(), _gpuTimer->getBatchAverage()); } -DebugAmbientOcclusion::DebugAmbientOcclusion() { -} - void DebugAmbientOcclusion::configure(const Config& config) { - _showCursorPixel = config.showCursorPixel; auto cursorPos = glm::vec2(_parametersBuffer->pixelInfo); @@ -916,9 +922,6 @@ void DebugAmbientOcclusion::run(const render::RenderContextPointer& renderContex batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, fullResDepthTexture); batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, nullptr); }); - } - diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.h b/libraries/render-utils/src/AmbientOcclusionEffect.h index 100de27e1a..3c49dba3d4 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.h +++ b/libraries/render-utils/src/AmbientOcclusionEffect.h @@ -71,15 +71,16 @@ protected: #endif glm::ivec2 _frameSize; - int _resolutionLevel{ 0 }; - int _depthResolutionLevel{ 0 }; - bool _isStereo{ false }; + int _resolutionLevel { 0 }; + int _depthResolutionLevel { 0 }; + bool _isStereo { false }; }; using AmbientOcclusionFramebufferPointer = std::shared_ptr; class AmbientOcclusionEffectConfig : public render::GPUJobConfig::Persistent { Q_OBJECT + Q_PROPERTY(bool debug MEMBER debug NOTIFY dirty) Q_PROPERTY(bool horizonBased MEMBER horizonBased NOTIFY dirty) Q_PROPERTY(bool ditheringEnabled MEMBER ditheringEnabled NOTIFY dirty) Q_PROPERTY(bool borderingEnabled MEMBER borderingEnabled NOTIFY dirty) @@ -109,42 +110,44 @@ public: const int MAX_RESOLUTION_LEVEL = 4; const int MAX_BLUR_RADIUS = 15; - void setEdgeSharpness(float sharpness); void setResolutionLevel(int level); + void setEdgeSharpness(float sharpness); void setBlurRadius(int radius); void setSSAORadius(float newRadius); void setSSAOObscuranceLevel(float level); void setSSAOFalloffAngle(float bias); - void setSSAONumSpiralTurns(float turns); void setSSAONumSamples(int samples); + void setSSAONumSpiralTurns(float turns); void setHBAORadius(float newRadius); void setHBAOObscuranceLevel(float level); void setHBAOFalloffAngle(float bias); void setHBAONumSamples(int samples); - float perspectiveScale; - float edgeSharpness; - int blurRadius; // 0 means no blurring - int resolutionLevel; + bool debug { false }; - float ssaoRadius; - float ssaoObscuranceLevel; // intensify or dim down the obscurance effect - float ssaoFalloffAngle; - float ssaoNumSpiralTurns; // defining an angle span to distribute the samples ray directions - int ssaoNumSamples; + bool jitterEnabled { false }; // Add small jittering to AO samples at each frame + bool horizonBased { false }; // Use horizon based AO + int resolutionLevel { 2 }; + float edgeSharpness { 1.0f }; + int blurRadius { 4 }; // 0 means no blurring - float hbaoRadius; - float hbaoObscuranceLevel; // intensify or dim down the obscurance effect - float hbaoFalloffAngle; - int hbaoNumSamples; + float ssaoRadius { 1.0f }; + float ssaoObscuranceLevel { 0.4f }; // intensify or dim down the obscurance effect + float ssaoFalloffAngle { 0.15f }; + int ssaoNumSamples { 32 }; + float ssaoNumSpiralTurns { 7.0f }; // defining an angle span to distribute the samples ray directions - bool horizonBased; // Use horizon based AO - bool ditheringEnabled; // randomize the distribution of taps per pixel, should always be true - bool borderingEnabled; // avoid evaluating information from non existing pixels out of the frame, should always be true - bool fetchMipsEnabled; // fetch taps in sub mips to otpimize cache, should always be true - bool jitterEnabled; // Add small jittering to AO samples at each frame + float hbaoRadius { 0.7f }; + float hbaoObscuranceLevel { 0.75f }; // intensify or dim down the obscurance effect + float hbaoFalloffAngle { 0.3f }; + int hbaoNumSamples { 1 }; + + float perspectiveScale { 1.0f }; + bool ditheringEnabled { true }; // randomize the distribution of taps per pixel, should always be true + bool borderingEnabled { true }; // avoid evaluating information from non existing pixels out of the frame, should always be true + bool fetchMipsEnabled { true }; // fetch taps in sub mips to otpimize cache, should always be true signals: void dirty(); @@ -160,7 +163,7 @@ public: using Config = AmbientOcclusionEffectConfig; using JobModel = render::Job::ModelIO; - AmbientOcclusionEffect(); + AmbientOcclusionEffect() {} void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output); @@ -168,7 +171,6 @@ public: // Class describing the uniform buffer with all the parameters common to the AO shaders class AOParameters : public AmbientOcclusionParams { public: - AOParameters(); int getResolutionLevel() const { return _resolutionInfo.x; } @@ -184,7 +186,6 @@ public: bool isDitheringEnabled() const { return _ditheringInfo.x != 0.0f; } bool isBorderingEnabled() const { return _ditheringInfo.w != 0.0f; } bool isHorizonBased() const { return _resolutionInfo.y != 0.0f; } - }; using AOParametersBuffer = gpu::StructBuffer; @@ -193,17 +194,15 @@ private: // Class describing the uniform buffer with all the parameters common to the bilateral blur shaders class BlurParameters : public AmbientOcclusionBlurParams { public: - BlurParameters(); float getEdgeSharpness() const { return (float)_blurInfo.x; } int getBlurRadius() const { return (int)_blurInfo.w; } - }; using BlurParametersBuffer = gpu::StructBuffer; - using FrameParametersBuffer = gpu::StructBuffer< AmbientOcclusionFrameParams>; + void updateParameters(const graphics::AmbientOcclusionPointer ambientOcclusion); void updateBlurParameters(); void updateFramebufferSizes(); void updateRandomSamples(); @@ -215,7 +214,7 @@ private: FrameParametersBuffer _aoFrameParametersBuffer[SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT]; BlurParametersBuffer _vblurParametersBuffer; BlurParametersBuffer _hblurParametersBuffer; - float _blurEdgeSharpness{ 0.0f }; + float _blurEdgeSharpness { 0.0f }; static const gpu::PipelinePointer& getOcclusionPipeline(); static const gpu::PipelinePointer& getBilateralBlurPipeline(); @@ -231,9 +230,14 @@ private: AmbientOcclusionFramebufferPointer _framebuffer; std::array _randomSamples; - int _frameId{ 0 }; - bool _isJitterEnabled{ true }; - + int _frameId { 0 }; + bool _debug { false }; + float _perspectiveScale { 1.0f }; + bool _ditheringEnabled { true }; + bool _borderingEnabled { true }; + bool _fetchMipsEnabled { true }; + graphics::AmbientOcclusionPointer _debugAmbientOcclusion { std::make_shared() }; + gpu::RangeTimerPointer _gpuTimer; friend class DebugAmbientOcclusion; @@ -248,8 +252,8 @@ class DebugAmbientOcclusionConfig : public render::Job::Config { public: DebugAmbientOcclusionConfig() : render::Job::Config(false) {} - bool showCursorPixel{ false }; - glm::vec2 debugCursorTexcoord{ 0.5f, 0.5f }; + bool showCursorPixel { false }; + glm::vec2 debugCursorTexcoord { 0.5f, 0.5f }; signals: void dirty(); @@ -262,7 +266,7 @@ public: using Config = DebugAmbientOcclusionConfig; using JobModel = render::Job::ModelI; - DebugAmbientOcclusion(); + DebugAmbientOcclusion() {} void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); @@ -283,7 +287,7 @@ private: gpu::PipelinePointer _debugPipeline; - bool _showCursorPixel{ false }; + bool _showCursorPixel { false }; }; #endif // hifi_AmbientOcclusionEffect_h diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index fe9e5eb245..0ff1c435e1 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -672,14 +672,4 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) { _defaultTonemappingID = tonemappingStage->addTonemapping(_defaultTonemapping); } } - - if (!_defaultAmbientOcclusion) { - auto ambientOcclusionStage = renderContext->_scene->getStage(); - if (ambientOcclusionStage) { - auto ambientOcclusion = std::make_shared(); - - _defaultAmbientOcclusion = ambientOcclusion; - _defaultAmbientOcclusionID = ambientOcclusionStage->addAmbientOcclusion(_defaultAmbientOcclusion); - } - } } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index d19c1de2e9..73c43c52a3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -170,8 +170,6 @@ protected: HazeStage::Index _defaultHazeID { HazeStage::INVALID_INDEX }; graphics::TonemappingPointer _defaultTonemapping { nullptr }; TonemappingStage::Index _defaultTonemappingID { TonemappingStage::INVALID_INDEX }; - graphics::AmbientOcclusionPointer _defaultAmbientOcclusion { nullptr }; - AmbientOcclusionStage::Index _defaultAmbientOcclusionID { AmbientOcclusionStage::INVALID_INDEX }; graphics::SkyboxPointer _defaultSkybox { new ProceduralSkybox() }; NetworkTexturePointer _defaultSkyboxNetworkTexture; NetworkTexturePointer _defaultAmbientNetworkTexture; diff --git a/libraries/render-utils/src/LightingModel.h b/libraries/render-utils/src/LightingModel.h index a488abcb09..5298fb2ceb 100644 --- a/libraries/render-utils/src/LightingModel.h +++ b/libraries/render-utils/src/LightingModel.h @@ -4,6 +4,7 @@ // // Created by Sam Gateau 7/1/2016. // Copyright 2016 High Fidelity, Inc. +// Copyright 2024 Overte e.V. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -17,14 +18,13 @@ #include #include -// LightingModel is a helper class gathering in one place the flags to enable the lighting contributions +// LightingModel is a helper class gathering in one place the flags to enable the lighting contributions class LightingModel { public: using UniformBufferView = gpu::BufferView; LightingModel(); - void setUnlit(bool enable); bool isUnlitEnabled() const; @@ -76,7 +76,6 @@ public: void setBlendshape(bool enable); bool isBlendshapeEnabled() const; - void setAmbientOcclusion(bool enable); bool isAmbientOcclusionEnabled() const; void setShadow(bool enable); @@ -86,55 +85,49 @@ public: gpu::TexturePointer getAmbientFresnelLUT() const { return _ambientFresnelLUT; } protected: - - // Class describing the uniform buffer with the transform info common to the AO shaders // It s changing every frame class Parameters { public: - float enableUnlit{ 1.0f }; - float enableEmissive{ 1.0f }; - float enableLightmap{ 1.0f }; - float enableBackground{ 1.0f }; + float enableUnlit { 1.0f }; + float enableEmissive { 1.0f }; + float enableLightmap { 1.0f }; + float enableBackground { 1.0f }; - float enableScattering{ 1.0f }; - float enableDiffuse{ 1.0f }; - float enableSpecular{ 1.0f }; - float enableAlbedo{ 1.0f }; + float enableScattering { 1.0f }; + float enableDiffuse { 1.0f }; + float enableSpecular { 1.0f }; + float enableAlbedo { 1.0f }; - float enableAmbientLight{ 1.0f }; - float enableDirectionalLight{ 1.0f }; - float enablePointLight{ 1.0f }; - float enableSpotLight{ 1.0f }; + float enableAmbientLight { 1.0f }; + float enableDirectionalLight { 1.0f }; + float enablePointLight { 1.0f }; + float enableSpotLight { 1.0f }; float showLightContour { 0.0f }; // false by default - float enableObscurance{ 1.0f }; + float enableObscurance { 1.0f }; float enableMaterialTexturing { 1.0f }; float enableWireframe { 0.0f }; // false by default - float enableHaze{ 1.0f }; - float enableBloom{ 1.0f }; - float enableSkinning{ 1.0f }; - float enableBlendshape{ 1.0f }; + float enableHaze { 1.0f }; + float enableBloom { 1.0f }; + float enableSkinning { 1.0f }; + float enableBlendshape { 1.0f }; - float enableAmbientOcclusion{ 0.0f }; // false by default - float enableShadow{ 1.0f }; - float spare1{ 1.0f }; - float spare2{ 1.0f }; + float enableAmbientOcclusion { 1.0f }; + float enableShadow { 1.0f }; + float spare1 { 1.0f }; + float spare2 { 1.0f }; Parameters() {} }; UniformBufferView _parametersBuffer; static gpu::TexturePointer _ambientFresnelLUT; }; - using LightingModelPointer = std::shared_ptr; - - - class MakeLightingModelConfig : public render::Job::Config { Q_OBJECT @@ -168,39 +161,37 @@ class MakeLightingModelConfig : public render::Job::Config { Q_PROPERTY(bool enableAmbientOcclusion READ isAmbientOcclusionEnabled WRITE setAmbientOcclusion NOTIFY dirty) Q_PROPERTY(bool enableShadow READ isShadowEnabled WRITE setShadow NOTIFY dirty) - public: MakeLightingModelConfig() : render::Job::Config() {} // Make Lighting Model is always on - bool enableUnlit{ true }; - bool enableEmissive{ true }; - bool enableLightmap{ true }; - bool enableBackground{ true }; - bool enableObscurance{ true }; + bool enableUnlit { true }; + bool enableEmissive { true }; + bool enableLightmap { true }; + bool enableBackground { true }; + bool enableObscurance { true }; - bool enableScattering{ true }; - bool enableDiffuse{ true }; - bool enableSpecular{ true }; + bool enableScattering { true }; + bool enableDiffuse { true }; + bool enableSpecular { true }; - bool enableAlbedo{ true }; + bool enableAlbedo { true }; bool enableMaterialTexturing { true }; - bool enableAmbientLight{ true }; - bool enableDirectionalLight{ true }; - bool enablePointLight{ true }; - bool enableSpotLight{ true }; + bool enableAmbientLight { true }; + bool enableDirectionalLight { true }; + bool enablePointLight { true }; + bool enableSpotLight { true }; bool showLightContour { false }; // false by default bool enableWireframe { false }; // false by default - bool enableHaze{ true }; - bool enableBloom{ true }; - bool enableSkinning{ true }; - bool enableBlendshape{ true }; - - bool enableAmbientOcclusion{ false }; // false by default - bool enableShadow{ true }; + bool enableHaze { true }; + bool enableBloom { true }; + bool enableSkinning { true }; + bool enableBlendshape { true }; + bool enableAmbientOcclusion { true }; + bool enableShadow { true }; void setAmbientOcclusion(bool enable) { enableAmbientOcclusion = enable; emit dirty();} bool isAmbientOcclusionEnabled() const { return enableAmbientOcclusion; } diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 397d1bce52..866b3c407c 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -116,6 +116,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() { } return _ambientPipeline; } + const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { if (!_backgroundPipeline) { gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::zone_drawSkybox); diff --git a/scripts/developer/utilities/render/ambientOcclusionPass.qml b/scripts/developer/utilities/render/ambientOcclusionPass.qml index 5c20d64345..75b927a2c9 100644 --- a/scripts/developer/utilities/render/ambientOcclusionPass.qml +++ b/scripts/developer/utilities/render/ambientOcclusionPass.qml @@ -55,6 +55,7 @@ Rectangle { Column { Repeater { model: [ + "debugEnabled:debug", "horizonBased:horizonBased", "jitterEnabled:jitterEnabled", "ditheringEnabled:ditheringEnabled", @@ -72,7 +73,7 @@ Rectangle { Column { Repeater { model: [ - "debugEnabled:showCursorPixel" + "showCursorPixel:showCursorPixel" ] HifiControls.CheckBox { boxSize: 20 @@ -100,8 +101,6 @@ Rectangle { ] } - - TabView { anchors.left: parent.left anchors.right: parent.right diff --git a/scripts/system/create/assets/data/createAppTooltips.json b/scripts/system/create/assets/data/createAppTooltips.json index 32f4ddcbe6..58b0e36ffb 100644 --- a/scripts/system/create/assets/data/createAppTooltips.json +++ b/scripts/system/create/assets/data/createAppTooltips.json @@ -174,6 +174,39 @@ "tonemapping.exposure": { "tooltip": "The exposure used during tonemapping." }, + "ambientOcclusionMode": { + "tooltip": "Configures the ambient occlusion in this zone." + }, + "ambientOcclusion.technique": { + "tooltip": "The ambient occlusion technique used. Different techniques have different tradeoffs." + }, + "ambientOcclusion.jitter": { + "tooltip": "Whether or not the ambient occlusion sampling is jittered." + }, + "ambientOcclusion.resolutionLevel": { + "tooltip": "How high the resolution of the ambient occlusion buffer should be. Higher levels mean lower resolution buffers." + }, + "ambientOcclusion.edgeSharpness": { + "tooltip": "How much to sharpen the edges during the ambient occlusion blurring." + }, + "ambientOcclusion.blurRadius": { + "tooltip": "The radius used for blurring, in pixels." + }, + "ambientOcclusion.aoRadius": { + "tooltip": "The radius used for ambient occlusion." + }, + "ambientOcclusion.aoObscuranceLevel": { + "tooltip": "Intensify or dim ambient occlusion." + }, + "ambientOcclusion.aoFalloffAngle": { + "tooltip": "The falloff angle for the AO calculation." + }, + "ambientOcclusion.aoSamplingAmount": { + "tooltip": "The fraction of AO samples to use, out of the maximum for each technique." + }, + "ambientOcclusion.ssaoNumSpiralTurns": { + "tooltip": "The angle span used to distribute the AO samples ray directions. SSAO only." + }, "audio.reverbEnabled": { "tooltip": "If reverb should be enabled for listeners in this zone." }, diff --git a/scripts/system/create/entityProperties/html/js/entityProperties.js b/scripts/system/create/entityProperties/html/js/entityProperties.js index 43258dd344..f281fc3839 100644 --- a/scripts/system/create/entityProperties/html/js/entityProperties.js +++ b/scripts/system/create/entityProperties/html/js/entityProperties.js @@ -658,11 +658,81 @@ const GROUPS = [ propertyID: "ambientOcclusionMode", }, { - label: "Ambient Occlusion", + label: "Technique", type: "dropdown", options: { ssao: "SSAO", hbao: "HBAO" }, propertyID: "ambientOcclusion.technique", - showPropertyRule: { "tonemappingMode": "enabled" }, + showPropertyRule: { "ambientOcclusionMode": "enabled" }, + }, + { + label: "Jitter", + type: "bool", + propertyID: "ambientOcclusion.jitter", + showPropertyRule: { "ambientOcclusionMode": "enabled" }, + }, + { + label: "Resolution Level", + type: "number-draggable", + step: 1, + decimals: 0, + propertyID: "ambientOcclusion.resolutionLevel", + showPropertyRule: { "ambientOcclusionMode": "enabled" }, + }, + { + label: "Edge Sharpness", + type: "number-draggable", + step: 0.01, + decimals: 2, + propertyID: "ambientOcclusion.edgeSharpness", + showPropertyRule: { "ambientOcclusionMode": "enabled" }, + }, + { + label: "Blur Radius (pixels)", + type: "number-draggable", + step: 1, + decimals: 0, + propertyID: "ambientOcclusion.blurRadius", + showPropertyRule: { "ambientOcclusionMode": "enabled" }, + }, + { + label: "AO Radius", + type: "number-draggable", + step: 0.01, + decimals: 2, + propertyID: "ambientOcclusion.aoRadius", + showPropertyRule: { "ambientOcclusionMode": "enabled" }, + }, + { + label: "Intensity", + type: "number-draggable", + step: 0.01, + decimals: 2, + propertyID: "ambientOcclusion.aoObscuranceLevel", + showPropertyRule: { "ambientOcclusionMode": "enabled" }, + }, + { + label: "Falloff Angle", + type: "number-draggable", + step: 0.01, + decimals: 2, + propertyID: "ambientOcclusion.aoFalloffAngle", + showPropertyRule: { "ambientOcclusionMode": "enabled" }, + }, + { + label: "Sampling Amount", + type: "number-draggable", + step: 0.01, + decimals: 2, + propertyID: "ambientOcclusion.aoSamplingAmount", + showPropertyRule: { "ambientOcclusionMode": "enabled" }, + }, + { + label: "Num Spiral Turns", + type: "number-draggable", + step: 0.01, + decimals: 2, + propertyID: "ambientOcclusion.ssaoNumSpiralTurns", + showPropertyRule: { "ambientOcclusionMode": "enabled" }, } ] }, diff --git a/scripts/system/create/entityProperties/html/tabs/zone_ambient_occlusion.png b/scripts/system/create/entityProperties/html/tabs/zone_ambient_occlusion.png new file mode 100644 index 0000000000000000000000000000000000000000..ace90dbcbc8d090d778c2a3b3ac4663cd42a6255 GIT binary patch literal 785 zcmWlUe@sjP9KgTt-MhQze!WLI#Z7OKnq|6k^P^Gkx~uLek|aduwAC+|{Nb3SWhx>Ph@1OQTlUY893 z5g~8^0C)F!}{$<0K{P-5O6p{1y-cV)BrrFKJ|BVJpfR9_1T#KCu0DZ3V`V# z0P_vNk^nGn1W3FFFz--ZL0=jGT4~T}a*ls6`GdirmI{ctWY#0KMY^Uosongg!e=X5 zU&N+->0td~Wm6K%@0~@je~v;ZqEKv4D1-@3VL69aj$LRm(=~Z~V*{P|P)^ z%gBYTP4HTmTop(Yw>1Yu&G~EU678!O(ZI(0h1}QKdnC91P>~{DL)Mcp!@}peDI;Rl zWK>8Sd8S;2ywv1lsmp0K$4mPYc*<2F;X%1SL*boNq*=bNfs%bvy0+u(UOssU4IOmR z?zvUOtCZdogrkSE*3$}%q%-ms=MUwV)?|pgfnsR+AehSHKND@mtJHn2ex5nsJN6y% z6*6FAZhu`*=DZ+L%Z_pg`S78%>BAo~%F>>6`KK-GZ%W&JLf-upQ?tahIp=vCD!9RFgd za?J90*_(`{(B{gWN#ILwdSPKFYJG`KxbtFal5FW6K6l?`ssU62i2XZz_tNVb002Yk KMqNva(fS{(|0FN~ literal 0 HcmV?d00001 diff --git a/scripts/system/create/entityProperties/html/tabs/zone_tonemapping.png b/scripts/system/create/entityProperties/html/tabs/zone_tonemapping.png new file mode 100644 index 0000000000000000000000000000000000000000..06f93f57e46af2679a891d7498f7d01adf89e641 GIT binary patch literal 673 zcmWm4ZAcSw901_o-RXr_fGCb)AE zS1q+UOGQXaK?p?6BFK{I3>OL&lwu*nCX@s*k#H0(_Tl;V+%}u^;uuv70EmqSodp0C zQ6vul0@ri*0YK1XxOfdfD2>8kXgE4Jm$b!Nfa&gzKc#&DfT|6aVu1Dp0EZJG9073r z0BAV{uu}<;JpdrT;0d_{!CG-%X&a`h(lM+t@Q~q1hbF9d`;#!pVw`pK7 zEI|%>Xx%X&>)~n)53I=liC${Ldex_C@NNa-+&Ut5)fH@4ygG2F>dn)|Dz6Z2awr;lZkStT^bRVJ4@ zS#}jTRI*#jxTJ=DaSEX@_7d0`)CweO@Ov0G$d;(N(ZbF;%2?VRukV(#nHbIrR5@pL zWAzphAG=`Q#7Sfh?!vT;ns?UzT6_O)L0!C9KaoRZNd2RJ8@{DCKm3xv8YD=>t9!Oh zP@NpRye_es*}Wgi9xKXF-tACZO+wbDU5djv3iw*Pk@dV$FarQ!EHvpR^DDdl1F1gY AP5=M^ literal 0 HcmV?d00001