mirror of
https://github.com/overte-org/overte.git
synced 2025-04-10 12:32:50 +02:00
Merge pull request #1050 from HifiExperiments/zoneProps
Zone properties for tonemapping and ambient occlusion
This commit is contained in:
commit
3dad0f14a2
49 changed files with 2057 additions and 415 deletions
|
@ -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<int> _renderMethodSetting { "renderMethod", RENDER_FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED };
|
||||
Setting::Handle<bool> _shadowsEnabledSetting { "shadowsEnabled", true };
|
||||
Setting::Handle<bool> _ambientOcclusionEnabledSetting { "ambientOcclusionEnabled", false };
|
||||
Setting::Handle<bool> _ambientOcclusionEnabledSetting { "ambientOcclusionEnabled", true };
|
||||
//Setting::Handle<AntialiasingConfig::Mode> _antialiasingModeSetting { "antialiasingMode", AntialiasingConfig::Mode::TAA };
|
||||
Setting::Handle<int> _antialiasingModeSetting { "antialiasingMode", AntialiasingConfig::Mode::NONE };
|
||||
Setting::Handle<float> _viewportResolutionScaleSetting { "viewportResolutionScale", 1.0f };
|
||||
|
|
|
@ -68,6 +68,20 @@ void ZoneEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity
|
|||
_bloomIndex = INVALID_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
if (_tonemappingStage) {
|
||||
if (!TonemappingStage::isIndexInvalid(_tonemappingIndex)) {
|
||||
_tonemappingStage->removeTonemapping(_tonemappingIndex);
|
||||
_tonemappingIndex = INVALID_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
if (_ambientOcclusionStage) {
|
||||
if (!AmbientOcclusionStage::isIndexInvalid(_ambientOcclusionIndex)) {
|
||||
_ambientOcclusionStage->removeAmbientOcclusion(_ambientOcclusionIndex);
|
||||
_ambientOcclusionIndex = INVALID_INDEX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
||||
|
@ -96,6 +110,16 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
assert(_bloomStage);
|
||||
}
|
||||
|
||||
if (!_tonemappingStage) {
|
||||
_tonemappingStage = args->_scene->getStage<TonemappingStage>();
|
||||
assert(_tonemappingStage);
|
||||
}
|
||||
|
||||
if (!_ambientOcclusionStage) {
|
||||
_ambientOcclusionStage = args->_scene->getStage<AmbientOcclusionStage>();
|
||||
assert(_ambientOcclusionStage);
|
||||
}
|
||||
|
||||
{ // Sun
|
||||
if (_needSunUpdate) {
|
||||
if (LightStage::isIndexInvalid(_sunIndex)) {
|
||||
|
@ -149,6 +173,24 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (_needTonemappingUpdate) {
|
||||
if (TonemappingStage::isIndexInvalid(_tonemappingIndex)) {
|
||||
_tonemappingIndex = _tonemappingStage->addTonemapping(_tonemapping);
|
||||
}
|
||||
_needTonemappingUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (_needAmbientOcclusionUpdate) {
|
||||
if (AmbientOcclusionStage::isIndexInvalid(_ambientOcclusionIndex)) {
|
||||
_ambientOcclusionIndex = _ambientOcclusionStage->addAmbientOcclusion(_ambientOcclusion);
|
||||
}
|
||||
_needAmbientOcclusionUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_visible) {
|
||||
// Finally, push the lights visible in the frame
|
||||
//
|
||||
|
@ -184,6 +226,18 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
} else if (_bloomMode == COMPONENT_MODE_ENABLED) {
|
||||
_bloomStage->_currentFrame.pushBloom(_bloomIndex);
|
||||
}
|
||||
|
||||
if (_tonemappingMode == COMPONENT_MODE_DISABLED) {
|
||||
_tonemappingStage->_currentFrame.pushTonemapping(0); // Use the fallback tonemapping for "off"
|
||||
} else if (_tonemappingMode == COMPONENT_MODE_ENABLED) {
|
||||
_tonemappingStage->_currentFrame.pushTonemapping(_tonemappingIndex);
|
||||
}
|
||||
|
||||
if (_ambientOcclusionMode == COMPONENT_MODE_DISABLED) {
|
||||
_ambientOcclusionStage->_currentFrame.pushAmbientOcclusion(INVALID_INDEX);
|
||||
} else if (_ambientOcclusionMode == COMPONENT_MODE_ENABLED) {
|
||||
_ambientOcclusionStage->_currentFrame.pushAmbientOcclusion(_ambientOcclusionIndex);
|
||||
}
|
||||
}
|
||||
|
||||
CullTest::_containingZones.insert(_entityID);
|
||||
|
@ -216,6 +270,8 @@ void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointe
|
|||
bool skyboxChanged = entity->skyboxPropertiesChanged() || proceduralUserDataChanged;
|
||||
bool hazeChanged = entity->hazePropertiesChanged();
|
||||
bool bloomChanged = entity->bloomPropertiesChanged();
|
||||
bool tonemappingChanged = entity->tonemappingPropertiesChanged();
|
||||
bool ambientOcclusionChanged = entity->ambientOcclusionPropertiesChanged();
|
||||
entity->resetRenderingPropertiesChanged();
|
||||
|
||||
if (transformChanged) {
|
||||
|
@ -255,6 +311,16 @@ void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointe
|
|||
updateBloomFromEntity(entity);
|
||||
}
|
||||
|
||||
if (tonemappingChanged) {
|
||||
_tonemappingProperties = entity->getTonemappingProperties();
|
||||
updateTonemappingFromEntity(entity);
|
||||
}
|
||||
|
||||
if (ambientOcclusionChanged) {
|
||||
_ambientOcclusionProperties = entity->getAmbientOcclusionProperties();
|
||||
updateAmbientOcclusionFromEntity(entity);
|
||||
}
|
||||
|
||||
bool visuallyReady = true;
|
||||
uint32_t skyboxMode = entity->getSkyboxMode();
|
||||
if (skyboxMode == COMPONENT_MODE_ENABLED && !_skyboxTextureURL.isEmpty()) {
|
||||
|
@ -275,7 +341,9 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
|
|||
entity->ambientLightPropertiesChanged() ||
|
||||
entity->hazePropertiesChanged() ||
|
||||
entity->bloomPropertiesChanged() ||
|
||||
entity->skyboxPropertiesChanged()) {
|
||||
entity->skyboxPropertiesChanged() ||
|
||||
entity->tonemappingPropertiesChanged() ||
|
||||
entity->ambientOcclusionPropertiesChanged()) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -360,6 +428,32 @@ void ZoneEntityRenderer::updateBloomFromEntity(const TypedEntityPointer& entity)
|
|||
bloom->setBloomSize(_bloomProperties.getBloomSize());
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::updateTonemappingFromEntity(const TypedEntityPointer& entity) {
|
||||
_tonemappingMode = (ComponentMode)entity->getTonemappingMode();
|
||||
|
||||
const auto& tonemapping = editTonemapping();
|
||||
|
||||
tonemapping->setCurve(_tonemappingProperties.getCurve());
|
||||
tonemapping->setExposure(_tonemappingProperties.getExposure());
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::updateAmbientOcclusionFromEntity(const TypedEntityPointer& entity) {
|
||||
_ambientOcclusionMode = (ComponentMode)entity->getAmbientOcclusionMode();
|
||||
|
||||
const auto& ambientOcclusion = editAmbientOcclusion();
|
||||
|
||||
ambientOcclusion->setTechnique(_ambientOcclusionProperties.getTechnique());
|
||||
ambientOcclusion->setJitter(_ambientOcclusionProperties.getJitter());
|
||||
ambientOcclusion->setResolutionLevel(_ambientOcclusionProperties.getResolutionLevel());
|
||||
ambientOcclusion->setEdgeSharpness(_ambientOcclusionProperties.getEdgeSharpness());
|
||||
ambientOcclusion->setBlurRadius(_ambientOcclusionProperties.getBlurRadius());
|
||||
ambientOcclusion->setAORadius(_ambientOcclusionProperties.getAORadius());
|
||||
ambientOcclusion->setAOObscuranceLevel(_ambientOcclusionProperties.getAOObscuranceLevel());
|
||||
ambientOcclusion->setAOFalloffAngle(_ambientOcclusionProperties.getAOFalloffAngle());
|
||||
ambientOcclusion->setAOSamplingAmount(_ambientOcclusionProperties.getAOSamplingAmount());
|
||||
ambientOcclusion->setSSAONumSpiralTurns(_ambientOcclusionProperties.getSSAONumSpiralTurns());
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::updateKeyBackgroundFromEntity(const TypedEntityPointer& entity) {
|
||||
_skyboxMode = (ComponentMode)entity->getSkyboxMode();
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <BackgroundStage.h>
|
||||
#include <HazeStage.h>
|
||||
#include <BloomStage.h>
|
||||
#include <TonemappingStage.h>
|
||||
#include <AmbientOcclusionStage.h>
|
||||
#include <TextureCache.h>
|
||||
#include "RenderableEntityItem.h"
|
||||
#include <ComponentMode.h>
|
||||
|
@ -47,6 +49,8 @@ private:
|
|||
void updateHazeFromEntity(const TypedEntityPointer& entity);
|
||||
void updateKeyBackgroundFromEntity(const TypedEntityPointer& entity);
|
||||
void updateBloomFromEntity(const TypedEntityPointer& entity);
|
||||
void updateTonemappingFromEntity(const TypedEntityPointer& entity);
|
||||
void updateAmbientOcclusionFromEntity(const TypedEntityPointer& entity);
|
||||
void updateAmbientMap();
|
||||
void updateSkyboxMap();
|
||||
void setAmbientURL(const QString& ambientUrl);
|
||||
|
@ -61,6 +65,8 @@ private:
|
|||
graphics::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); }
|
||||
graphics::HazePointer editHaze() { _needHazeUpdate = true; return _haze; }
|
||||
graphics::BloomPointer editBloom() { _needBloomUpdate = true; return _bloom; }
|
||||
graphics::TonemappingPointer editTonemapping() { _needTonemappingUpdate = true; return _tonemapping; }
|
||||
graphics::AmbientOcclusionPointer editAmbientOcclusion() { _needAmbientOcclusionUpdate = true; return _ambientOcclusion; }
|
||||
|
||||
glm::vec3 _lastPosition;
|
||||
glm::vec3 _lastDimensions;
|
||||
|
@ -73,12 +79,16 @@ private:
|
|||
const graphics::SunSkyStagePointer _background { std::make_shared<graphics::SunSkyStage>() };
|
||||
const graphics::HazePointer _haze { std::make_shared<graphics::Haze>() };
|
||||
const graphics::BloomPointer _bloom { std::make_shared<graphics::Bloom>() };
|
||||
const graphics::TonemappingPointer _tonemapping { std::make_shared<graphics::Tonemapping>() };
|
||||
const graphics::AmbientOcclusionPointer _ambientOcclusion { std::make_shared<graphics::AmbientOcclusion>() };
|
||||
|
||||
ComponentMode _keyLightMode { COMPONENT_MODE_INHERIT };
|
||||
ComponentMode _ambientLightMode { COMPONENT_MODE_INHERIT };
|
||||
ComponentMode _skyboxMode { COMPONENT_MODE_INHERIT };
|
||||
ComponentMode _hazeMode { COMPONENT_MODE_INHERIT };
|
||||
ComponentMode _bloomMode { COMPONENT_MODE_INHERIT };
|
||||
ComponentMode _tonemappingMode { COMPONENT_MODE_INHERIT };
|
||||
ComponentMode _ambientOcclusionMode { COMPONENT_MODE_INHERIT };
|
||||
|
||||
indexed_container::Index _sunIndex { LightStage::INVALID_INDEX };
|
||||
indexed_container::Index _ambientIndex { LightStage::INVALID_INDEX };
|
||||
|
@ -92,27 +102,37 @@ private:
|
|||
BloomStagePointer _bloomStage;
|
||||
BloomStage::Index _bloomIndex { BloomStage::INVALID_INDEX };
|
||||
|
||||
bool _needUpdate{ true };
|
||||
bool _needSunUpdate{ true };
|
||||
bool _needAmbientUpdate{ true };
|
||||
bool _needBackgroundUpdate{ true };
|
||||
bool _needHazeUpdate{ true };
|
||||
TonemappingStagePointer _tonemappingStage;
|
||||
TonemappingStage::Index _tonemappingIndex { TonemappingStage::INVALID_INDEX };
|
||||
|
||||
AmbientOcclusionStagePointer _ambientOcclusionStage;
|
||||
AmbientOcclusionStage::Index _ambientOcclusionIndex { AmbientOcclusionStage::INVALID_INDEX };
|
||||
|
||||
bool _needUpdate { true };
|
||||
bool _needSunUpdate { true };
|
||||
bool _needAmbientUpdate { true };
|
||||
bool _needBackgroundUpdate { true };
|
||||
bool _needHazeUpdate { true };
|
||||
bool _needBloomUpdate { true };
|
||||
bool _needTonemappingUpdate { true };
|
||||
bool _needAmbientOcclusionUpdate { true };
|
||||
|
||||
KeyLightPropertyGroup _keyLightProperties;
|
||||
AmbientLightPropertyGroup _ambientLightProperties;
|
||||
HazePropertyGroup _hazeProperties;
|
||||
SkyboxPropertyGroup _skyboxProperties;
|
||||
BloomPropertyGroup _bloomProperties;
|
||||
TonemappingPropertyGroup _tonemappingProperties;
|
||||
AmbientOcclusionPropertyGroup _ambientOcclusionProperties;
|
||||
|
||||
// More attributes used for rendering:
|
||||
QString _ambientTextureURL;
|
||||
NetworkTexturePointer _ambientTexture;
|
||||
bool _pendingAmbientTexture{ false };
|
||||
bool _pendingAmbientTexture { false };
|
||||
|
||||
QString _skyboxTextureURL;
|
||||
NetworkTexturePointer _skyboxTexture;
|
||||
bool _pendingSkyboxTexture{ false };
|
||||
bool _pendingSkyboxTexture { false };
|
||||
|
||||
QString _proceduralUserData;
|
||||
};
|
||||
|
|
300
libraries/entities/src/AmbientOcclusionPropertyGroup.cpp
Normal file
300
libraries/entities/src/AmbientOcclusionPropertyGroup.cpp
Normal file
|
@ -0,0 +1,300 @@
|
|||
//
|
||||
// AmbientOcclusionPropertyGroup.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by HifiExperiments on 6/23/24
|
||||
// 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
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "AmbientOcclusionPropertyGroup.h"
|
||||
|
||||
#include <OctreePacketData.h>
|
||||
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
inline void addAmbientOcclusionTechnique(QHash<QString, AmbientOcclusionTechnique>& lookup, AmbientOcclusionTechnique technique) { lookup[AmbientOcclusionTechniqueHelpers::getNameForAmbientOcclusionTechnique(technique)] = technique; }
|
||||
const QHash<QString, AmbientOcclusionTechnique> stringToAmbientOcclusionTechniqueLookup = [] {
|
||||
QHash<QString, AmbientOcclusionTechnique> toReturn;
|
||||
addAmbientOcclusionTechnique(toReturn, AmbientOcclusionTechnique::SSAO);
|
||||
addAmbientOcclusionTechnique(toReturn, AmbientOcclusionTechnique::HBAO);
|
||||
return toReturn;
|
||||
}();
|
||||
QString AmbientOcclusionPropertyGroup::getTechniqueAsString() const { return AmbientOcclusionTechniqueHelpers::getNameForAmbientOcclusionTechnique(_technique); }
|
||||
void AmbientOcclusionPropertyGroup::setTechniqueFromString(const QString& technique) {
|
||||
auto techniqueItr = stringToAmbientOcclusionTechniqueLookup.find(technique.toLower());
|
||||
if (techniqueItr != stringToAmbientOcclusionTechniqueLookup.end()) {
|
||||
_technique = techniqueItr.value();
|
||||
_techniqueChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AmbientOcclusionPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine,
|
||||
bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags, bool isMyOwnAvatarEntity) const {
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_AMBIENT_OCCLUSION_TECHNIQUE, AmbientOcclusion, ambientOcclusion, Technique, technique, getTechniqueAsString);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_JITTER, AmbientOcclusion, ambientOcclusion, Jitter, jitter);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL, AmbientOcclusion, ambientOcclusion, ResolutionLevel, resolutionLevel);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS, AmbientOcclusion, ambientOcclusion, EdgeSharpness, edgeSharpness);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_BLUR_RADIUS, AmbientOcclusion, ambientOcclusion, BlurRadius, blurRadius);
|
||||
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_SAMPLING_AMOUNT, AmbientOcclusion, ambientOcclusion, AOSamplingAmount, aoSamplingAmount);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, AmbientOcclusion, ambientOcclusion, SSAONumSpiralTurns, ssaoNumSpiralTurns);
|
||||
}
|
||||
|
||||
void AmbientOcclusionPropertyGroup::copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) {
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_ENUM(ambientOcclusion, technique, Technique);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, jitter, bool, setJitter);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, resolutionLevel, uint8_t, setResolutionLevel);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, edgeSharpness, float, setEdgeSharpness);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, blurRadius, uint8_t, setBlurRadius);
|
||||
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, aoSamplingAmount, float, setAOSamplingAmount);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ambientOcclusion, ssaoNumSpiralTurns, float, setSSAONumSpiralTurns);
|
||||
}
|
||||
|
||||
void AmbientOcclusionPropertyGroup::merge(const AmbientOcclusionPropertyGroup& other) {
|
||||
COPY_PROPERTY_IF_CHANGED(technique);
|
||||
COPY_PROPERTY_IF_CHANGED(jitter);
|
||||
COPY_PROPERTY_IF_CHANGED(resolutionLevel);
|
||||
COPY_PROPERTY_IF_CHANGED(edgeSharpness);
|
||||
COPY_PROPERTY_IF_CHANGED(blurRadius);
|
||||
COPY_PROPERTY_IF_CHANGED(aoRadius);
|
||||
COPY_PROPERTY_IF_CHANGED(aoObscuranceLevel);
|
||||
COPY_PROPERTY_IF_CHANGED(aoFalloffAngle);
|
||||
COPY_PROPERTY_IF_CHANGED(aoSamplingAmount);
|
||||
COPY_PROPERTY_IF_CHANGED(ssaoNumSpiralTurns);
|
||||
}
|
||||
|
||||
void AmbientOcclusionPropertyGroup::debugDump() const {
|
||||
qCDebug(entities) << " AmbientOcclusionPropertyGroup: ---------------------------------------------";
|
||||
qCDebug(entities) << " Technique:" << getTechniqueAsString();
|
||||
qCDebug(entities) << " Jitter:" << getJitter();
|
||||
qCDebug(entities) << " ResolutionLevel:" << getResolutionLevel();
|
||||
qCDebug(entities) << " EdgeSharpness:" << getEdgeSharpness();
|
||||
qCDebug(entities) << " BlurRadius:" << getBlurRadius();
|
||||
qCDebug(entities) << " AORadius:" << getAORadius();
|
||||
qCDebug(entities) << " AOObscuranceLevel:" << getAOObscuranceLevel();
|
||||
qCDebug(entities) << " AOFalloffAngle:" << getAOFalloffAngle();
|
||||
qCDebug(entities) << " AOSamplingAmount:" << getAOSamplingAmount();
|
||||
qCDebug(entities) << " SSAONumSpiralTurns:" << getSSAONumSpiralTurns();
|
||||
}
|
||||
|
||||
void AmbientOcclusionPropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||
if (techniqueChanged()) {
|
||||
out << "ambientOcclusion-technique";
|
||||
}
|
||||
if (jitterChanged()) {
|
||||
out << "ambientOcclusion-jitter";
|
||||
}
|
||||
if (resolutionLevelChanged()) {
|
||||
out << "ambientOcclusion-resolutionLevel";
|
||||
}
|
||||
if (edgeSharpnessChanged()) {
|
||||
out << "ambientOcclusion-edgeSharpness";
|
||||
}
|
||||
if (blurRadiusChanged()) {
|
||||
out << "ambientOcclusion-blurRadius";
|
||||
}
|
||||
if (aoRadiusChanged()) {
|
||||
out << "ambientOcclusion-aoRadius";
|
||||
}
|
||||
if (aoObscuranceLevelChanged()) {
|
||||
out << "ambientOcclusion-aoObscuranceLevel";
|
||||
}
|
||||
if (aoFalloffAngleChanged()) {
|
||||
out << "ambientOcclusion-aoFalloffAngle";
|
||||
}
|
||||
if (aoSamplingAmountChanged()) {
|
||||
out << "ambientOcclusion-aoSamplingAmount";
|
||||
}
|
||||
if (ssaoNumSpiralTurnsChanged()) {
|
||||
out << "ambientOcclusion-ssaoNumSpiralTurns";
|
||||
}
|
||||
}
|
||||
|
||||
bool AmbientOcclusionPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_TECHNIQUE, (uint32_t)getTechnique());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_JITTER, getJitter());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL, getResolutionLevel());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS, getEdgeSharpness());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_BLUR_RADIUS, getBlurRadius());
|
||||
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_SAMPLING_AMOUNT, getAOSamplingAmount());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, getSSAONumSpiralTurns());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AmbientOcclusionPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) {
|
||||
|
||||
int bytesRead = 0;
|
||||
bool overwriteLocalData = true;
|
||||
bool somethingChanged = false;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_TECHNIQUE, AmbientOcclusionTechnique, setTechnique);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_JITTER, bool, setJitter);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL, uint8_t, setResolutionLevel);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS, float, setEdgeSharpness);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_BLUR_RADIUS, uint8_t, setBlurRadius);
|
||||
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_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);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_JITTER, Jitter);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL, ResolutionLevel);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS, EdgeSharpness);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_BLUR_RADIUS, BlurRadius);
|
||||
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_SAMPLING_AMOUNT, AOSamplingAmount);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, SSAONumSpiralTurns);
|
||||
|
||||
processedBytes += bytesRead;
|
||||
|
||||
Q_UNUSED(somethingChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AmbientOcclusionPropertyGroup::markAllChanged() {
|
||||
_techniqueChanged = true;
|
||||
_jitterChanged = true;
|
||||
_resolutionLevelChanged = true;
|
||||
_edgeSharpnessChanged = true;
|
||||
_blurRadiusChanged = true;
|
||||
_aoRadiusChanged = true;
|
||||
_aoObscuranceLevelChanged = true;
|
||||
_aoFalloffAngleChanged = true;
|
||||
_aoSamplingAmountChanged = true;
|
||||
_ssaoNumSpiralTurnsChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags AmbientOcclusionPropertyGroup::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_TECHNIQUE, technique);
|
||||
CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_JITTER, jitter);
|
||||
CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL, resolutionLevel);
|
||||
CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS, edgeSharpness);
|
||||
CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_BLUR_RADIUS, blurRadius);
|
||||
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_SAMPLING_AMOUNT, aoSamplingAmount);
|
||||
CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, ssaoNumSpiralTurns);
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
||||
void AmbientOcclusionPropertyGroup::getProperties(EntityItemProperties& properties) const {
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, Technique, getTechnique);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, Jitter, getJitter);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, ResolutionLevel, getResolutionLevel);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, EdgeSharpness, getEdgeSharpness);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, BlurRadius, getBlurRadius);
|
||||
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, AOSamplingAmount, getAOSamplingAmount);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AmbientOcclusion, SSAONumSpiralTurns, getSSAONumSpiralTurns);
|
||||
}
|
||||
|
||||
bool AmbientOcclusionPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, Technique, technique, setTechnique);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, Jitter, jitter, setJitter);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, ResolutionLevel, resolutionLevel, setResolutionLevel);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, EdgeSharpness, edgeSharpness, setEdgeSharpness);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, BlurRadius, blurRadius, setBlurRadius);
|
||||
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, AOSamplingAmount, aoSamplingAmount, setAOSamplingAmount);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AmbientOcclusion, SSAONumSpiralTurns, ssaoNumSpiralTurns, setSSAONumSpiralTurns);
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
EntityPropertyFlags AmbientOcclusionPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||
EntityPropertyFlags requestedProperties;
|
||||
|
||||
requestedProperties += PROP_AMBIENT_OCCLUSION_TECHNIQUE;
|
||||
requestedProperties += PROP_AMBIENT_OCCLUSION_JITTER;
|
||||
requestedProperties += PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL;
|
||||
requestedProperties += PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS;
|
||||
requestedProperties += PROP_AMBIENT_OCCLUSION_BLUR_RADIUS;
|
||||
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_SAMPLING_AMOUNT;
|
||||
requestedProperties += PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
void AmbientOcclusionPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_TECHNIQUE, (uint32_t)getTechnique());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_JITTER, getJitter());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL, getResolutionLevel());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS, getEdgeSharpness());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_BLUR_RADIUS, getBlurRadius());
|
||||
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_SAMPLING_AMOUNT, getAOSamplingAmount());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, getSSAONumSpiralTurns());
|
||||
}
|
||||
|
||||
int AmbientOcclusionPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) {
|
||||
|
||||
int bytesRead = 0;
|
||||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_TECHNIQUE, AmbientOcclusionTechnique, setTechnique);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_JITTER, bool, setJitter);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL, uint8_t, setResolutionLevel);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS, float, setEdgeSharpness);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_BLUR_RADIUS, uint8_t, setBlurRadius);
|
||||
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_SAMPLING_AMOUNT, float, setAOSamplingAmount);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, float, setSSAONumSpiralTurns);
|
||||
|
||||
return bytesRead;
|
||||
}
|
108
libraries/entities/src/AmbientOcclusionPropertyGroup.h
Normal file
108
libraries/entities/src/AmbientOcclusionPropertyGroup.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
//
|
||||
// AmbientOcclusionPropertyGroup.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by HifiExperiments on 6/23/24
|
||||
// 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
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#ifndef hifi_AmbientOcclusionPropertyGroup_h
|
||||
#define hifi_AmbientOcclusionPropertyGroup_h
|
||||
|
||||
#include <AmbientOcclusionTechnique.h>
|
||||
|
||||
#include "PropertyGroup.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
class EntityItemProperties;
|
||||
class EncodeBitstreamParams;
|
||||
class OctreePacketData;
|
||||
class EntityTreeElementExtraEncodeData;
|
||||
class ReadBitstreamToTreeParams;
|
||||
class ScriptEngine;
|
||||
class ScriptValue;
|
||||
|
||||
/*@jsdoc
|
||||
* AmbientOcclusion is defined by the following properties:
|
||||
* @typedef {object} Entities.AmbientOcclusion
|
||||
* @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
|
||||
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
|
||||
ScriptEngine* engine, bool skipDefaults,
|
||||
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
|
||||
bool isMyOwnAvatarEntity) const override;
|
||||
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
|
||||
|
||||
void merge(const AmbientOcclusionPropertyGroup& other);
|
||||
|
||||
virtual void debugDump() const override;
|
||||
virtual void listChangedProperties(QList<QString>& out) override;
|
||||
|
||||
virtual bool appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags,
|
||||
const unsigned char*& dataAt, int& processedBytes) override;
|
||||
virtual void markAllChanged() override;
|
||||
virtual EntityPropertyFlags getChangedProperties() const override;
|
||||
|
||||
// EntityItem related helpers
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual void getProperties(EntityItemProperties& propertiesOut) const override;
|
||||
|
||||
/// returns true if something changed
|
||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||
|
||||
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
// FIXME: On some machines, SSAO seems to be causing performance problems. Let's default to HBAO for now and maybe
|
||||
// revisit when we have Vulkan
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_AMBIENT_OCCLUSION_TECHNIQUE, Technique, technique, AmbientOcclusionTechnique, AmbientOcclusionTechnique::HBAO);
|
||||
DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_JITTER, Jitter, jitter, bool, false);
|
||||
DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL, ResolutionLevel, resolutionLevel, uint8_t, 2);
|
||||
DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS, EdgeSharpness, edgeSharpness, float, 1.0f);
|
||||
DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_BLUR_RADIUS, BlurRadius, blurRadius, uint8_t, 4);
|
||||
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_SAMPLING_AMOUNT, AOSamplingAmount, aoSamplingAmount, float, 0.5f);
|
||||
DEFINE_PROPERTY(PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS, SSAONumSpiralTurns, ssaoNumSpiralTurns, float, 7.0f);
|
||||
};
|
||||
|
||||
#endif // hifi_AmbientOcclusionPropertyGroup_h
|
|
@ -48,6 +48,8 @@ BloomPropertyGroup EntityItemProperties::_staticBloom;
|
|||
ZoneAudioPropertyGroup EntityItemProperties::_staticAudio;
|
||||
KeyLightPropertyGroup EntityItemProperties::_staticKeyLight;
|
||||
AmbientLightPropertyGroup EntityItemProperties::_staticAmbientLight;
|
||||
TonemappingPropertyGroup EntityItemProperties::_staticTonemapping;
|
||||
AmbientOcclusionPropertyGroup EntityItemProperties::_staticAmbientOcclusion;
|
||||
GrabPropertyGroup EntityItemProperties::_staticGrab;
|
||||
PulsePropertyGroup EntityItemProperties::_staticPulse;
|
||||
RingGizmoPropertyGroup EntityItemProperties::_staticRing;
|
||||
|
@ -90,6 +92,8 @@ void EntityItemProperties::debugDump() const {
|
|||
getAmbientLight().debugDump();
|
||||
getBloom().debugDump();
|
||||
getAudio().debugDump();
|
||||
getTonemapping().debugDump();
|
||||
getAmbientOcclusion().debugDump();
|
||||
getGrab().debugDump();
|
||||
|
||||
qCDebug(entities) << " changed properties...";
|
||||
|
@ -254,6 +258,8 @@ QString EntityItemProperties::getKeyLightModeAsString() const { return getCompon
|
|||
QString EntityItemProperties::getAmbientLightModeAsString() const { return getComponentModeAsString(_ambientLightMode); }
|
||||
QString EntityItemProperties::getHazeModeAsString() const { return getComponentModeAsString(_hazeMode); }
|
||||
QString EntityItemProperties::getBloomModeAsString() const { return getComponentModeAsString(_bloomMode); }
|
||||
QString EntityItemProperties::getTonemappingModeAsString() const { return getComponentModeAsString(_tonemappingMode); }
|
||||
QString EntityItemProperties::getAmbientOcclusionModeAsString() const { return getComponentModeAsString(_ambientOcclusionMode); }
|
||||
void EntityItemProperties::setSkyboxModeFromString(const QString& mode) {
|
||||
auto modeItr = stringToComponentMode.find(mode.toLower());
|
||||
if (modeItr != stringToComponentMode.end()) {
|
||||
|
@ -289,6 +295,20 @@ void EntityItemProperties::setBloomModeFromString(const QString& mode) {
|
|||
_bloomModeChanged = true;
|
||||
}
|
||||
}
|
||||
void EntityItemProperties::setTonemappingModeFromString(const QString& mode) {
|
||||
auto modeItr = stringToComponentMode.find(mode.toLower());
|
||||
if (modeItr != stringToComponentMode.end()) {
|
||||
_tonemappingMode = modeItr.value();
|
||||
_tonemappingModeChanged = true;
|
||||
}
|
||||
}
|
||||
void EntityItemProperties::setAmbientOcclusionModeFromString(const QString& mode) {
|
||||
auto modeItr = stringToComponentMode.find(mode.toLower());
|
||||
if (modeItr != stringToComponentMode.end()) {
|
||||
_ambientOcclusionMode = modeItr.value();
|
||||
_ambientOcclusionModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void addAvatarPriorityMode(QHash<QString, AvatarPriorityMode>& lookup, AvatarPriorityMode mode) { lookup[AvatarPriorityModeHelpers::getNameForAvatarPriorityMode(mode)] = mode; }
|
||||
const QHash<QString, AvatarPriorityMode> stringToAvatarPriority = [] {
|
||||
|
@ -625,6 +645,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
changedProperties += _haze.getChangedProperties();
|
||||
changedProperties += _bloom.getChangedProperties();
|
||||
changedProperties += _audio.getChangedProperties();
|
||||
changedProperties += _tonemapping.getChangedProperties();
|
||||
changedProperties += _ambientOcclusion.getChangedProperties();
|
||||
CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
||||
CHECK_PROPERTY_CHANGE(PROP_FILTER_URL, filterURL);
|
||||
|
@ -635,6 +657,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_BLOOM_MODE, bloomMode);
|
||||
CHECK_PROPERTY_CHANGE(PROP_AVATAR_PRIORITY, avatarPriority);
|
||||
CHECK_PROPERTY_CHANGE(PROP_SCREENSHARE, screenshare);
|
||||
CHECK_PROPERTY_CHANGE(PROP_TONEMAPPING_MODE, tonemappingMode);
|
||||
CHECK_PROPERTY_CHANGE(PROP_AMBIENT_OCCLUSION_MODE, ambientOcclusionMode);
|
||||
|
||||
// Polyvox
|
||||
CHECK_PROPERTY_CHANGE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize);
|
||||
|
@ -1587,6 +1611,12 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
*
|
||||
* @property {Entities.ZoneAudio} audio - The audio properties of the zone.
|
||||
*
|
||||
* @property {Entities.ComponentMode} tonemappingMode="inherit" - Configures the tonemapping in the zone.
|
||||
* @property {Entities.Tonemapping} tonemapping - The tonemapping properties of the zone.
|
||||
*
|
||||
* @property {Entities.ComponentMode} ambientOcclusionMode="inherit" - Configures the ambient occlusion in the zone.
|
||||
* @property {Entities.AmbientOcclusion} ambientOcclusion - The ambient occlusion properties of the zone.
|
||||
*
|
||||
* @property {boolean} flyingAllowed=true - <code>true</code> if visitors can fly in the zone; <code>false</code> if they
|
||||
* cannot. Only works for domain entities.
|
||||
* @property {boolean} ghostingAllowed=true - <code>true</code> if visitors with avatar collisions turned off will not
|
||||
|
@ -1951,6 +1981,8 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
|
|||
_haze.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
|
||||
_bloom.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
|
||||
_audio.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
|
||||
_tonemapping.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
|
||||
_ambientOcclusion.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties, returnNothingOnEmptyPropertyFlags, isMyOwnAvatarEntity);
|
||||
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
||||
|
@ -1963,6 +1995,8 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BLOOM_MODE, bloomMode, getBloomModeAsString());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_AVATAR_PRIORITY, avatarPriority, getAvatarPriorityAsString());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SCREENSHARE, screenshare, getScreenshareAsString());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_TONEMAPPING_MODE, tonemappingMode, getTonemappingModeAsString());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_AMBIENT_OCCLUSION_MODE, ambientOcclusionMode, getAmbientOcclusionModeAsString());
|
||||
}
|
||||
|
||||
// Web only
|
||||
|
@ -2349,6 +2383,8 @@ void EntityItemProperties::copyFromScriptValue(const ScriptValue& object, bool h
|
|||
_haze.copyFromScriptValue(object, namesSet, _defaultSettings);
|
||||
_bloom.copyFromScriptValue(object, namesSet, _defaultSettings);
|
||||
_audio.copyFromScriptValue(object, namesSet, _defaultSettings);
|
||||
_tonemapping.copyFromScriptValue(object, namesSet, _defaultSettings);
|
||||
_ambientOcclusion.copyFromScriptValue(object, namesSet, _defaultSettings);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(flyingAllowed, bool, setFlyingAllowed);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(ghostingAllowed, bool, setGhostingAllowed);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(filterURL, QString, setFilterURL);
|
||||
|
@ -2359,6 +2395,8 @@ void EntityItemProperties::copyFromScriptValue(const ScriptValue& object, bool h
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(bloomMode, BloomMode);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(avatarPriority, AvatarPriority);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(screenshare, Screenshare);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(tonemappingMode, TonemappingMode);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(ambientOcclusionMode, AmbientOcclusionMode);
|
||||
|
||||
// Polyvox
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelVolumeSize, vec3, setVoxelVolumeSize);
|
||||
|
@ -2653,6 +2691,8 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
_haze.merge(other._haze);
|
||||
_bloom.merge(other._bloom);
|
||||
_audio.merge(other._audio);
|
||||
_tonemapping.merge(other._tonemapping);
|
||||
_ambientOcclusion.merge(other._ambientOcclusion);
|
||||
COPY_PROPERTY_IF_CHANGED(flyingAllowed);
|
||||
COPY_PROPERTY_IF_CHANGED(ghostingAllowed);
|
||||
COPY_PROPERTY_IF_CHANGED(filterURL);
|
||||
|
@ -2663,6 +2703,8 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(bloomMode);
|
||||
COPY_PROPERTY_IF_CHANGED(avatarPriority);
|
||||
COPY_PROPERTY_IF_CHANGED(screenshare);
|
||||
COPY_PROPERTY_IF_CHANGED(tonemappingMode);
|
||||
COPY_PROPERTY_IF_CHANGED(ambientOcclusionMode);
|
||||
|
||||
// Polyvox
|
||||
COPY_PROPERTY_IF_CHANGED(voxelVolumeSize);
|
||||
|
@ -3079,6 +3121,22 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr
|
|||
ADD_GROUP_PROPERTY_TO_MAP(PROP_LISTENER_ZONES, Audio, audio, ListenerZones, listenerZones);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_LISTENER_ATTENUATION_COEFFICIENTS, Audio, audio, ListenerAttenuationCoefficients, listenerAttenuationCoefficients);
|
||||
}
|
||||
{ // Tonemapping
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_TONEMAPPING_CURVE, Tonemapping, tonemapping, Curve, curve);
|
||||
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_TONEMAPPING_EXPOSURE, Tonemapping, tonemapping, Exposure, exposure, -4.0f, -4.0f);
|
||||
}
|
||||
{ // Ambient Occlusion
|
||||
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);
|
||||
ADD_PROPERTY_TO_MAP(PROP_FILTER_URL, FilterURL, filterURL, QString);
|
||||
|
@ -3089,6 +3147,8 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr
|
|||
ADD_PROPERTY_TO_MAP(PROP_BLOOM_MODE, BloomMode, bloomMode, uint32_t);
|
||||
ADD_PROPERTY_TO_MAP(PROP_AVATAR_PRIORITY, AvatarPriority, avatarPriority, uint32_t);
|
||||
ADD_PROPERTY_TO_MAP(PROP_SCREENSHARE, Screenshare, screenshare, uint32_t);
|
||||
ADD_PROPERTY_TO_MAP(PROP_TONEMAPPING_MODE, TonemappingMode, tonemappingMode, uint32_t);
|
||||
ADD_PROPERTY_TO_MAP(PROP_AMBIENT_OCCLUSION_MODE, AmbientOcclusionMode, ambientOcclusionMode, uint32_t);
|
||||
|
||||
// Polyvox
|
||||
ADD_PROPERTY_TO_MAP(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, vec3);
|
||||
|
@ -3516,6 +3576,12 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
_staticAudio.setProperties(properties);
|
||||
_staticAudio.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
||||
_staticTonemapping.setProperties(properties);
|
||||
_staticTonemapping.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
||||
_staticAmbientOcclusion.setProperties(properties);
|
||||
_staticAmbientOcclusion.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, properties.getFlyingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, properties.getGhostingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, properties.getFilterURL());
|
||||
|
@ -3527,6 +3593,8 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
APPEND_ENTITY_PROPERTY(PROP_BLOOM_MODE, (uint32_t)properties.getBloomMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AVATAR_PRIORITY, (uint32_t)properties.getAvatarPriority());
|
||||
APPEND_ENTITY_PROPERTY(PROP_SCREENSHARE, (uint32_t)properties.getScreenshare());
|
||||
APPEND_ENTITY_PROPERTY(PROP_TONEMAPPING_MODE, (uint32_t)properties.getTonemappingMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_MODE, (uint32_t)properties.getAmbientOcclusionMode());
|
||||
}
|
||||
|
||||
if (properties.getType() == EntityTypes::PolyVox) {
|
||||
|
@ -4006,6 +4074,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
properties.getHaze().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
properties.getBloom().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
properties.getAudio().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
properties.getTonemapping().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
properties.getAmbientOcclusion().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FLYING_ALLOWED, bool, setFlyingAllowed);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||
|
@ -4018,6 +4088,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BLOOM_MODE, uint32_t, setBloomMode);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AVATAR_PRIORITY, uint32_t, setAvatarPriority);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SCREENSHARE, uint32_t, setScreenshare);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TONEMAPPING_MODE, uint32_t, setTonemappingMode);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AMBIENT_OCCLUSION_MODE, uint32_t, setAmbientOcclusionMode);
|
||||
}
|
||||
|
||||
if (properties.getType() == EntityTypes::PolyVox) {
|
||||
|
@ -4399,6 +4471,8 @@ void EntityItemProperties::markAllChanged() {
|
|||
_haze.markAllChanged();
|
||||
_bloom.markAllChanged();
|
||||
_audio.markAllChanged();
|
||||
_tonemapping.markAllChanged();
|
||||
_ambientOcclusion.markAllChanged();
|
||||
_flyingAllowedChanged = true;
|
||||
_ghostingAllowedChanged = true;
|
||||
_filterURLChanged = true;
|
||||
|
@ -4409,6 +4483,8 @@ void EntityItemProperties::markAllChanged() {
|
|||
_bloomModeChanged = true;
|
||||
_avatarPriorityChanged = true;
|
||||
_screenshareChanged = true;
|
||||
_tonemappingModeChanged = true;
|
||||
_ambientOcclusionModeChanged = true;
|
||||
|
||||
// Polyvox
|
||||
_voxelVolumeSizeChanged = true;
|
||||
|
@ -5021,6 +5097,8 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
getHaze().listChangedProperties(out);
|
||||
getBloom().listChangedProperties(out);
|
||||
getAudio().listChangedProperties(out);
|
||||
getTonemapping().listChangedProperties(out);
|
||||
getAmbientOcclusion().listChangedProperties(out);
|
||||
if (flyingAllowedChanged()) {
|
||||
out += "flyingAllowed";
|
||||
}
|
||||
|
@ -5051,6 +5129,12 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
if (screenshareChanged()) {
|
||||
out += "screenshare";
|
||||
}
|
||||
if (tonemappingModeChanged()) {
|
||||
out += "tonemappingMode";
|
||||
}
|
||||
if (ambientOcclusionModeChanged()) {
|
||||
out += "ambientOcclusionMode";
|
||||
}
|
||||
|
||||
// Polyvox
|
||||
if (voxelVolumeSizeChanged()) {
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
#include "PulsePropertyGroup.h"
|
||||
#include "RingGizmoPropertyGroup.h"
|
||||
#include "ZoneAudioPropertyGroup.h"
|
||||
#include "TonemappingPropertyGroup.h"
|
||||
#include "AmbientOcclusionPropertyGroup.h"
|
||||
|
||||
#include "MaterialMappingMode.h"
|
||||
#include "BillboardMode.h"
|
||||
|
@ -346,6 +348,8 @@ public:
|
|||
DEFINE_PROPERTY_GROUP(Haze, haze, HazePropertyGroup);
|
||||
DEFINE_PROPERTY_GROUP(Bloom, bloom, BloomPropertyGroup);
|
||||
DEFINE_PROPERTY_GROUP(Audio, audio, ZoneAudioPropertyGroup);
|
||||
DEFINE_PROPERTY_GROUP(Tonemapping, tonemapping, TonemappingPropertyGroup);
|
||||
DEFINE_PROPERTY_GROUP(AmbientOcclusion, ambientOcclusion, AmbientOcclusionPropertyGroup);
|
||||
DEFINE_PROPERTY(PROP_FLYING_ALLOWED, FlyingAllowed, flyingAllowed, bool, ZoneEntityItem::DEFAULT_FLYING_ALLOWED);
|
||||
DEFINE_PROPERTY(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool, ZoneEntityItem::DEFAULT_GHOSTING_ALLOWED);
|
||||
DEFINE_PROPERTY(PROP_FILTER_URL, FilterURL, filterURL, QString, ZoneEntityItem::DEFAULT_FILTER_URL);
|
||||
|
@ -356,6 +360,8 @@ public:
|
|||
DEFINE_PROPERTY_REF_ENUM(PROP_BLOOM_MODE, BloomMode, bloomMode, uint32_t, (uint32_t)COMPONENT_MODE_INHERIT);
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_AVATAR_PRIORITY, AvatarPriority, avatarPriority, uint32_t, (uint32_t)COMPONENT_MODE_INHERIT);
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_SCREENSHARE, Screenshare, screenshare, uint32_t, (uint32_t)COMPONENT_MODE_INHERIT);
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_TONEMAPPING_MODE, TonemappingMode, tonemappingMode, uint32_t, (uint32_t)COMPONENT_MODE_INHERIT);
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_AMBIENT_OCCLUSION_MODE, AmbientOcclusionMode, ambientOcclusionMode, uint32_t, (uint32_t)COMPONENT_MODE_INHERIT);
|
||||
|
||||
// Polyvox
|
||||
DEFINE_PROPERTY_REF(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3, PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE);
|
||||
|
|
|
@ -175,6 +175,23 @@ enum EntityPropertyList {
|
|||
PROP_DERIVED_38,
|
||||
PROP_DERIVED_39,
|
||||
PROP_DERIVED_40,
|
||||
PROP_DERIVED_41,
|
||||
PROP_DERIVED_42,
|
||||
PROP_DERIVED_43,
|
||||
PROP_DERIVED_44,
|
||||
PROP_DERIVED_45,
|
||||
PROP_DERIVED_46,
|
||||
PROP_DERIVED_47,
|
||||
PROP_DERIVED_48,
|
||||
PROP_DERIVED_49,
|
||||
PROP_DERIVED_50,
|
||||
PROP_DERIVED_51,
|
||||
PROP_DERIVED_52,
|
||||
PROP_DERIVED_53,
|
||||
PROP_DERIVED_54,
|
||||
PROP_DERIVED_55,
|
||||
PROP_DERIVED_56,
|
||||
PROP_DERIVED_57,
|
||||
|
||||
PROP_AFTER_LAST_ITEM,
|
||||
|
||||
|
@ -276,44 +293,44 @@ enum EntityPropertyList {
|
|||
|
||||
// Zone
|
||||
// Keylight
|
||||
PROP_KEYLIGHT_COLOR = PROP_DERIVED_0,
|
||||
PROP_KEYLIGHT_INTENSITY = PROP_DERIVED_1,
|
||||
PROP_KEYLIGHT_DIRECTION = PROP_DERIVED_2,
|
||||
PROP_KEYLIGHT_CAST_SHADOW = PROP_DERIVED_3,
|
||||
PROP_KEYLIGHT_SHADOW_BIAS = PROP_DERIVED_4,
|
||||
PROP_KEYLIGHT_SHADOW_MAX_DISTANCE = PROP_DERIVED_5,
|
||||
PROP_KEY_LIGHT_MODE = PROP_DERIVED_0,
|
||||
PROP_KEYLIGHT_COLOR = PROP_DERIVED_1,
|
||||
PROP_KEYLIGHT_INTENSITY = PROP_DERIVED_2,
|
||||
PROP_KEYLIGHT_DIRECTION = PROP_DERIVED_3,
|
||||
PROP_KEYLIGHT_CAST_SHADOW = PROP_DERIVED_4,
|
||||
PROP_KEYLIGHT_SHADOW_BIAS = PROP_DERIVED_5,
|
||||
PROP_KEYLIGHT_SHADOW_MAX_DISTANCE = PROP_DERIVED_6,
|
||||
// Ambient light
|
||||
PROP_AMBIENT_LIGHT_INTENSITY = PROP_DERIVED_6,
|
||||
PROP_AMBIENT_LIGHT_URL = PROP_DERIVED_7,
|
||||
PROP_AMBIENT_LIGHT_COLOR = PROP_DERIVED_8,
|
||||
PROP_AMBIENT_LIGHT_MODE = PROP_DERIVED_7,
|
||||
PROP_AMBIENT_LIGHT_INTENSITY = PROP_DERIVED_8,
|
||||
PROP_AMBIENT_LIGHT_URL = PROP_DERIVED_9,
|
||||
PROP_AMBIENT_LIGHT_COLOR = PROP_DERIVED_10,
|
||||
// Skybox
|
||||
PROP_SKYBOX_COLOR = PROP_DERIVED_9,
|
||||
PROP_SKYBOX_URL = PROP_DERIVED_10,
|
||||
PROP_SKYBOX_MODE = PROP_DERIVED_11,
|
||||
PROP_SKYBOX_COLOR = PROP_DERIVED_12,
|
||||
PROP_SKYBOX_URL = PROP_DERIVED_13,
|
||||
// Haze
|
||||
PROP_HAZE_RANGE = PROP_DERIVED_11,
|
||||
PROP_HAZE_COLOR = PROP_DERIVED_12,
|
||||
PROP_HAZE_GLARE_COLOR = PROP_DERIVED_13,
|
||||
PROP_HAZE_ENABLE_GLARE = PROP_DERIVED_14,
|
||||
PROP_HAZE_GLARE_ANGLE = PROP_DERIVED_15,
|
||||
PROP_HAZE_ALTITUDE_EFFECT = PROP_DERIVED_16,
|
||||
PROP_HAZE_CEILING = PROP_DERIVED_17,
|
||||
PROP_HAZE_BASE_REF = PROP_DERIVED_18,
|
||||
PROP_HAZE_BACKGROUND_BLEND = PROP_DERIVED_19,
|
||||
PROP_HAZE_ATTENUATE_KEYLIGHT = PROP_DERIVED_20,
|
||||
PROP_HAZE_KEYLIGHT_RANGE = PROP_DERIVED_21,
|
||||
PROP_HAZE_KEYLIGHT_ALTITUDE = PROP_DERIVED_22,
|
||||
PROP_HAZE_MODE = PROP_DERIVED_14,
|
||||
PROP_HAZE_RANGE = PROP_DERIVED_15,
|
||||
PROP_HAZE_COLOR = PROP_DERIVED_16,
|
||||
PROP_HAZE_GLARE_COLOR = PROP_DERIVED_17,
|
||||
PROP_HAZE_ENABLE_GLARE = PROP_DERIVED_18,
|
||||
PROP_HAZE_GLARE_ANGLE = PROP_DERIVED_19,
|
||||
PROP_HAZE_ALTITUDE_EFFECT = PROP_DERIVED_20,
|
||||
PROP_HAZE_CEILING = PROP_DERIVED_21,
|
||||
PROP_HAZE_BASE_REF = PROP_DERIVED_22,
|
||||
PROP_HAZE_BACKGROUND_BLEND = PROP_DERIVED_23,
|
||||
PROP_HAZE_ATTENUATE_KEYLIGHT = PROP_DERIVED_24,
|
||||
PROP_HAZE_KEYLIGHT_RANGE = PROP_DERIVED_25,
|
||||
PROP_HAZE_KEYLIGHT_ALTITUDE = PROP_DERIVED_26,
|
||||
// Bloom
|
||||
PROP_BLOOM_INTENSITY = PROP_DERIVED_23,
|
||||
PROP_BLOOM_THRESHOLD = PROP_DERIVED_24,
|
||||
PROP_BLOOM_SIZE = PROP_DERIVED_25,
|
||||
PROP_FLYING_ALLOWED = PROP_DERIVED_26,
|
||||
PROP_GHOSTING_ALLOWED = PROP_DERIVED_27,
|
||||
PROP_FILTER_URL = PROP_DERIVED_28,
|
||||
PROP_KEY_LIGHT_MODE = PROP_DERIVED_29,
|
||||
PROP_AMBIENT_LIGHT_MODE = PROP_DERIVED_30,
|
||||
PROP_SKYBOX_MODE = PROP_DERIVED_31,
|
||||
PROP_HAZE_MODE = PROP_DERIVED_32,
|
||||
PROP_BLOOM_MODE = PROP_DERIVED_33,
|
||||
PROP_BLOOM_MODE = PROP_DERIVED_27,
|
||||
PROP_BLOOM_INTENSITY = PROP_DERIVED_28,
|
||||
PROP_BLOOM_THRESHOLD = PROP_DERIVED_29,
|
||||
PROP_BLOOM_SIZE = PROP_DERIVED_30,
|
||||
PROP_FLYING_ALLOWED = PROP_DERIVED_31,
|
||||
PROP_GHOSTING_ALLOWED = PROP_DERIVED_32,
|
||||
PROP_FILTER_URL = PROP_DERIVED_33,
|
||||
// Avatar priority
|
||||
PROP_AVATAR_PRIORITY = PROP_DERIVED_34,
|
||||
// Screen-sharing
|
||||
|
@ -324,6 +341,22 @@ enum EntityPropertyList {
|
|||
PROP_REVERB_WET_LEVEL = PROP_DERIVED_38,
|
||||
PROP_LISTENER_ZONES = PROP_DERIVED_39,
|
||||
PROP_LISTENER_ATTENUATION_COEFFICIENTS = PROP_DERIVED_40,
|
||||
// Tonemapping
|
||||
PROP_TONEMAPPING_MODE = PROP_DERIVED_41,
|
||||
PROP_TONEMAPPING_CURVE = PROP_DERIVED_42,
|
||||
PROP_TONEMAPPING_EXPOSURE = PROP_DERIVED_43,
|
||||
// Ambient Occlusion
|
||||
PROP_AMBIENT_OCCLUSION_MODE = PROP_DERIVED_44,
|
||||
PROP_AMBIENT_OCCLUSION_TECHNIQUE = PROP_DERIVED_45,
|
||||
PROP_AMBIENT_OCCLUSION_JITTER = PROP_DERIVED_46,
|
||||
PROP_AMBIENT_OCCLUSION_RESOLUTION_LEVEL = PROP_DERIVED_47,
|
||||
PROP_AMBIENT_OCCLUSION_EDGE_SHARPNESS = PROP_DERIVED_48,
|
||||
PROP_AMBIENT_OCCLUSION_BLUR_RADIUS = PROP_DERIVED_49,
|
||||
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_SAMPLING_AMOUNT = PROP_DERIVED_53,
|
||||
PROP_AMBIENT_OCCLUSION_SSAO_NUM_SPIRAL_TURNS = PROP_DERIVED_54,
|
||||
|
||||
// Polyvox
|
||||
PROP_VOXEL_VOLUME_SIZE = PROP_DERIVED_0,
|
||||
|
|
167
libraries/entities/src/TonemappingPropertyGroup.cpp
Normal file
167
libraries/entities/src/TonemappingPropertyGroup.cpp
Normal file
|
@ -0,0 +1,167 @@
|
|||
//
|
||||
// TonemappingPropertyGroup.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by HifiExperiments on 6/23/24
|
||||
// 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
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "TonemappingPropertyGroup.h"
|
||||
|
||||
#include <OctreePacketData.h>
|
||||
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
inline void addTonemappingCurve(QHash<QString, TonemappingCurve>& lookup, TonemappingCurve curve) { lookup[TonemappingCurveHelpers::getNameForTonemappingCurve(curve)] = curve; }
|
||||
const QHash<QString, TonemappingCurve> stringToTonemappingCurveLookup = [] {
|
||||
QHash<QString, TonemappingCurve> toReturn;
|
||||
addTonemappingCurve(toReturn, TonemappingCurve::RGB);
|
||||
addTonemappingCurve(toReturn, TonemappingCurve::SRGB);
|
||||
addTonemappingCurve(toReturn, TonemappingCurve::FILMIC);
|
||||
addTonemappingCurve(toReturn, TonemappingCurve::REINHARD);
|
||||
return toReturn;
|
||||
}();
|
||||
QString TonemappingPropertyGroup::getCurveAsString() const { return TonemappingCurveHelpers::getNameForTonemappingCurve(_curve); }
|
||||
void TonemappingPropertyGroup::setCurveFromString(const QString& curve) {
|
||||
auto curveItr = stringToTonemappingCurveLookup.find(curve.toLower());
|
||||
if (curveItr != stringToTonemappingCurveLookup.end()) {
|
||||
_curve = curveItr.value();
|
||||
_curveChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TonemappingPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine,
|
||||
bool skipDefaults, EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags, bool isMyOwnAvatarEntity) const {
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_TONEMAPPING_CURVE, Tonemapping, tonemapping, Curve, curve, getCurveAsString);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_TONEMAPPING_EXPOSURE, Tonemapping, tonemapping, Exposure, exposure);
|
||||
}
|
||||
|
||||
void TonemappingPropertyGroup::copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) {
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_ENUM(tonemapping, curve, Curve);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(tonemapping, exposure, float, setExposure);
|
||||
}
|
||||
|
||||
void TonemappingPropertyGroup::merge(const TonemappingPropertyGroup& other) {
|
||||
COPY_PROPERTY_IF_CHANGED(curve);
|
||||
COPY_PROPERTY_IF_CHANGED(exposure);
|
||||
}
|
||||
|
||||
void TonemappingPropertyGroup::debugDump() const {
|
||||
qCDebug(entities) << " TonemappingPropertyGroup: ---------------------------------------------";
|
||||
qCDebug(entities) << " Curve:" << getCurveAsString();
|
||||
qCDebug(entities) << " Exposure:" << getExposure();
|
||||
}
|
||||
|
||||
void TonemappingPropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||
if (curveChanged()) {
|
||||
out << "tonemapping-curve";
|
||||
}
|
||||
if (exposureChanged()) {
|
||||
out << "tonemapping-exposure";
|
||||
}
|
||||
}
|
||||
|
||||
bool TonemappingPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_TONEMAPPING_CURVE, (uint32_t)getCurve());
|
||||
APPEND_ENTITY_PROPERTY(PROP_TONEMAPPING_EXPOSURE, getExposure());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TonemappingPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) {
|
||||
|
||||
int bytesRead = 0;
|
||||
bool overwriteLocalData = true;
|
||||
bool somethingChanged = false;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_TONEMAPPING_CURVE, TonemappingCurve, setCurve);
|
||||
READ_ENTITY_PROPERTY(PROP_TONEMAPPING_EXPOSURE, float, setExposure);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_TONEMAPPING_CURVE, Curve);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_TONEMAPPING_EXPOSURE, Exposure);
|
||||
|
||||
processedBytes += bytesRead;
|
||||
|
||||
Q_UNUSED(somethingChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TonemappingPropertyGroup::markAllChanged() {
|
||||
_curveChanged = true;
|
||||
_exposureChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags TonemappingPropertyGroup::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_TONEMAPPING_CURVE, curve);
|
||||
CHECK_PROPERTY_CHANGE(PROP_TONEMAPPING_EXPOSURE, exposure);
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
||||
void TonemappingPropertyGroup::getProperties(EntityItemProperties& properties) const {
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Tonemapping, Curve, getCurve);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Tonemapping, Exposure, getExposure);
|
||||
}
|
||||
|
||||
bool TonemappingPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Tonemapping, Curve, curve, setCurve);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Tonemapping, Exposure, exposure, setExposure);
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
EntityPropertyFlags TonemappingPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||
EntityPropertyFlags requestedProperties;
|
||||
|
||||
requestedProperties += PROP_TONEMAPPING_CURVE;
|
||||
requestedProperties += PROP_TONEMAPPING_EXPOSURE;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
void TonemappingPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_TONEMAPPING_CURVE, (uint32_t)getCurve());
|
||||
APPEND_ENTITY_PROPERTY(PROP_TONEMAPPING_EXPOSURE, getExposure());
|
||||
}
|
||||
|
||||
int TonemappingPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) {
|
||||
|
||||
int bytesRead = 0;
|
||||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_TONEMAPPING_CURVE, TonemappingCurve, setCurve);
|
||||
READ_ENTITY_PROPERTY(PROP_TONEMAPPING_EXPOSURE, float, setExposure);
|
||||
|
||||
return bytesRead;
|
||||
}
|
87
libraries/entities/src/TonemappingPropertyGroup.h
Normal file
87
libraries/entities/src/TonemappingPropertyGroup.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// TonemappingPropertyGroup.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by HifiExperiments on 6/23/24
|
||||
// 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
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#ifndef hifi_TonemappingPropertyGroup_h
|
||||
#define hifi_TonemappingPropertyGroup_h
|
||||
|
||||
#include <TonemappingCurve.h>
|
||||
|
||||
#include "PropertyGroup.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
class EntityItemProperties;
|
||||
class EncodeBitstreamParams;
|
||||
class OctreePacketData;
|
||||
class EntityTreeElementExtraEncodeData;
|
||||
class ReadBitstreamToTreeParams;
|
||||
class ScriptEngine;
|
||||
class ScriptValue;
|
||||
|
||||
/*@jsdoc
|
||||
* Tonemapping is defined by the following properties:
|
||||
* @typedef {object} Entities.Tonemapping
|
||||
* @property {TonemappingCurve} curve="srgb" - The tonemapping curve used.
|
||||
* @property {number} exposure=0.0 - The applied exposure.
|
||||
*/
|
||||
class TonemappingPropertyGroup : public PropertyGroup {
|
||||
public:
|
||||
// EntityItemProperty related helpers
|
||||
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties,
|
||||
ScriptEngine* engine, bool skipDefaults,
|
||||
EntityItemProperties& defaultEntityProperties, bool returnNothingOnEmptyPropertyFlags,
|
||||
bool isMyOwnAvatarEntity) const override;
|
||||
virtual void copyFromScriptValue(const ScriptValue& object, const QSet<QString> &namesSet, bool& _defaultSettings) override;
|
||||
|
||||
void merge(const TonemappingPropertyGroup& other);
|
||||
|
||||
virtual void debugDump() const override;
|
||||
virtual void listChangedProperties(QList<QString>& out) override;
|
||||
|
||||
virtual bool appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags,
|
||||
const unsigned char*& dataAt, int& processedBytes) override;
|
||||
virtual void markAllChanged() override;
|
||||
virtual EntityPropertyFlags getChangedProperties() const override;
|
||||
|
||||
// EntityItem related helpers
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual void getProperties(EntityItemProperties& propertiesOut) const override;
|
||||
|
||||
/// returns true if something changed
|
||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||
|
||||
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_TONEMAPPING_CURVE, Curve, curve, TonemappingCurve, TonemappingCurve::SRGB);
|
||||
DEFINE_PROPERTY(PROP_TONEMAPPING_EXPOSURE, Exposure, exposure, float, 0.0);
|
||||
};
|
||||
|
||||
#endif // hifi_TonemappingPropertyGroup_h
|
|
@ -61,6 +61,8 @@ EntityItemProperties ZoneEntityItem::getProperties(const EntityPropertyFlags& de
|
|||
_hazeProperties.getProperties(properties);
|
||||
_bloomProperties.getProperties(properties);
|
||||
_audioProperties.getProperties(properties);
|
||||
_tonemappingProperties.getProperties(properties);
|
||||
_ambientOcclusionProperties.getProperties(properties);
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(flyingAllowed, getFlyingAllowed);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ghostingAllowed, getGhostingAllowed);
|
||||
|
@ -73,6 +75,8 @@ EntityItemProperties ZoneEntityItem::getProperties(const EntityPropertyFlags& de
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(bloomMode, getBloomMode);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(avatarPriority, getAvatarPriority);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(screenshare, getScreenshare);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(tonemappingMode, getTonemappingMode);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ambientOcclusionMode, getAmbientOcclusionMode);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
@ -92,6 +96,8 @@ bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& propertie
|
|||
_hazePropertiesChanged |= _hazeProperties.setProperties(properties);
|
||||
_bloomPropertiesChanged |= _bloomProperties.setProperties(properties);
|
||||
bool audioPropertiesChanged = _audioProperties.setProperties(properties);
|
||||
_tonemappingPropertiesChanged |= _tonemappingProperties.setProperties(properties);
|
||||
_ambientOcclusionPropertiesChanged |= _ambientOcclusionProperties.setProperties(properties);
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(flyingAllowed, setFlyingAllowed);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ghostingAllowed, setGhostingAllowed);
|
||||
|
@ -104,9 +110,12 @@ bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& propertie
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(bloomMode, setBloomMode);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(avatarPriority, setAvatarPriority);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(screenshare, setScreenshare);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(tonemappingMode, setTonemappingMode);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ambientOcclusionMode, setAmbientOcclusionMode);
|
||||
|
||||
somethingChanged |= _keyLightPropertiesChanged || _ambientLightPropertiesChanged || _skyboxPropertiesChanged ||
|
||||
_hazePropertiesChanged || _bloomPropertiesChanged || audioPropertiesChanged;
|
||||
_hazePropertiesChanged || _bloomPropertiesChanged || audioPropertiesChanged ||
|
||||
_tonemappingPropertiesChanged || _ambientOcclusionPropertiesChanged;
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
@ -177,6 +186,20 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
|||
dataAt += bytesFromAudio;
|
||||
}
|
||||
|
||||
{
|
||||
int bytesFromTonemapping = _tonemappingProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData, somethingChanged);
|
||||
bytesRead += bytesFromTonemapping;
|
||||
dataAt += bytesFromTonemapping;
|
||||
}
|
||||
|
||||
{
|
||||
int bytesFromAmbientOcclusion = _ambientOcclusionProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData, somethingChanged);
|
||||
bytesRead += bytesFromAmbientOcclusion;
|
||||
dataAt += bytesFromAmbientOcclusion;
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, bool, setFlyingAllowed);
|
||||
READ_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||
READ_ENTITY_PROPERTY(PROP_FILTER_URL, QString, setFilterURL);
|
||||
|
@ -188,6 +211,8 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
|||
READ_ENTITY_PROPERTY(PROP_BLOOM_MODE, uint32_t, setBloomMode);
|
||||
READ_ENTITY_PROPERTY(PROP_AVATAR_PRIORITY, uint32_t, setAvatarPriority);
|
||||
READ_ENTITY_PROPERTY(PROP_SCREENSHARE, uint32_t, setScreenshare);
|
||||
READ_ENTITY_PROPERTY(PROP_TONEMAPPING_MODE, uint32_t, setTonemappingMode);
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_MODE, uint32_t, setAmbientOcclusionMode);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
@ -204,6 +229,8 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
|||
requestedProperties += _hazeProperties.getEntityProperties(params);
|
||||
requestedProperties += _bloomProperties.getEntityProperties(params);
|
||||
requestedProperties += _audioProperties.getEntityProperties(params);
|
||||
requestedProperties += _tonemappingProperties.getEntityProperties(params);
|
||||
requestedProperties += _ambientOcclusionProperties.getEntityProperties(params);
|
||||
|
||||
requestedProperties += PROP_FLYING_ALLOWED;
|
||||
requestedProperties += PROP_GHOSTING_ALLOWED;
|
||||
|
@ -216,6 +243,8 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
|||
requestedProperties += PROP_SKYBOX_MODE;
|
||||
requestedProperties += PROP_HAZE_MODE;
|
||||
requestedProperties += PROP_BLOOM_MODE;
|
||||
requestedProperties += PROP_TONEMAPPING_MODE;
|
||||
requestedProperties += PROP_AMBIENT_OCCLUSION_MODE;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
@ -247,32 +276,40 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
|
|||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
_audioProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
_tonemappingProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
_ambientOcclusionProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, getFlyingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, getGhostingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, getFilterURL());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEY_LIGHT_MODE, (uint32_t)getKeyLightMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_LIGHT_MODE, (uint32_t)getAmbientLightMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_SKYBOX_MODE, (uint32_t)getSkyboxMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_MODE, (uint32_t)getHazeMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_BLOOM_MODE, (uint32_t)getBloomMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_KEY_LIGHT_MODE, getKeyLightMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_LIGHT_MODE, getAmbientLightMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_SKYBOX_MODE, getSkyboxMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_MODE, getHazeMode());
|
||||
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, getTonemappingMode());
|
||||
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_OCCLUSION_MODE, getAmbientOcclusionMode());
|
||||
}
|
||||
|
||||
void ZoneEntityItem::debugDump() const {
|
||||
quint64 now = usecTimestampNow();
|
||||
qCDebug(entities) << " ZoneEntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
||||
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
|
||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||
qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getComponentModeAsString(_hazeMode);
|
||||
qCDebug(entities) << " _keyLightMode:" << EntityItemProperties::getComponentModeAsString(_keyLightMode);
|
||||
qCDebug(entities) << " _ambientLightMode:" << EntityItemProperties::getComponentModeAsString(_ambientLightMode);
|
||||
qCDebug(entities) << " _skyboxMode:" << EntityItemProperties::getComponentModeAsString(_skyboxMode);
|
||||
qCDebug(entities) << " _bloomMode:" << EntityItemProperties::getComponentModeAsString(_bloomMode);
|
||||
qCDebug(entities) << " _avatarPriority:" << getAvatarPriority();
|
||||
qCDebug(entities) << " ZoneEntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
||||
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
|
||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||
qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getComponentModeAsString(_hazeMode);
|
||||
qCDebug(entities) << " _keyLightMode:" << EntityItemProperties::getComponentModeAsString(_keyLightMode);
|
||||
qCDebug(entities) << " _ambientLightMode:" << EntityItemProperties::getComponentModeAsString(_ambientLightMode);
|
||||
qCDebug(entities) << " _skyboxMode:" << EntityItemProperties::getComponentModeAsString(_skyboxMode);
|
||||
qCDebug(entities) << " _bloomMode:" << EntityItemProperties::getComponentModeAsString(_bloomMode);
|
||||
qCDebug(entities) << " _avatarPriority:" << getAvatarPriority();
|
||||
qCDebug(entities) << " _tonemappingMode:" << EntityItemProperties::getComponentModeAsString(_tonemappingMode);
|
||||
qCDebug(entities) << " _ambientOcclusionMode:" << EntityItemProperties::getComponentModeAsString(_ambientOcclusionMode);
|
||||
|
||||
_keyLightProperties.debugDump();
|
||||
_ambientLightProperties.debugDump();
|
||||
|
@ -280,6 +317,8 @@ void ZoneEntityItem::debugDump() const {
|
|||
_hazeProperties.debugDump();
|
||||
_bloomProperties.debugDump();
|
||||
_audioProperties.debugDump();
|
||||
_tonemappingProperties.debugDump();
|
||||
_ambientOcclusionProperties.debugDump();
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setShapeType(ShapeType type) {
|
||||
|
@ -408,53 +447,11 @@ void ZoneEntityItem::resetRenderingPropertiesChanged() {
|
|||
_skyboxPropertiesChanged = false;
|
||||
_hazePropertiesChanged = false;
|
||||
_bloomPropertiesChanged = false;
|
||||
_tonemappingPropertiesChanged = false;
|
||||
_ambientOcclusionPropertiesChanged = false;
|
||||
});
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _hazeMode) {
|
||||
_hazeMode = value;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ZoneEntityItem::getHazeMode() const {
|
||||
return _hazeMode;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setBloomMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _bloomMode) {
|
||||
_bloomMode = value;
|
||||
_bloomPropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ZoneEntityItem::getBloomMode() const {
|
||||
return _bloomMode;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setKeyLightMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _keyLightMode) {
|
||||
_keyLightMode = value;
|
||||
_keyLightPropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ZoneEntityItem::getKeyLightMode() const {
|
||||
return _keyLightMode;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setAmbientLightMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _ambientLightMode) {
|
||||
_ambientLightMode = value;
|
||||
_ambientLightPropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ZoneEntityItem::getAmbientLightMode() const {
|
||||
return _ambientLightMode;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setSkyboxMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _skyboxMode) {
|
||||
_skyboxMode = value;
|
||||
|
@ -462,8 +459,46 @@ void ZoneEntityItem::setSkyboxMode(const uint32_t value) {
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t ZoneEntityItem::getSkyboxMode() const {
|
||||
return _skyboxMode;
|
||||
void ZoneEntityItem::setKeyLightMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _keyLightMode) {
|
||||
_keyLightMode = value;
|
||||
_keyLightPropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setAmbientLightMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _ambientLightMode) {
|
||||
_ambientLightMode = value;
|
||||
_ambientLightPropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _hazeMode) {
|
||||
_hazeMode = value;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setBloomMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _bloomMode) {
|
||||
_bloomMode = value;
|
||||
_bloomPropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setTonemappingMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _tonemappingMode) {
|
||||
_tonemappingMode = value;
|
||||
_tonemappingPropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setAmbientOcclusionMode(const uint32_t value) {
|
||||
if (value < COMPONENT_MODE_ITEM_COUNT && value != _ambientOcclusionMode) {
|
||||
_ambientOcclusionMode = value;
|
||||
_ambientOcclusionPropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setUserData(const QString& value) {
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "HazePropertyGroup.h"
|
||||
#include "BloomPropertyGroup.h"
|
||||
#include "ZoneAudioPropertyGroup.h"
|
||||
#include "TonemappingPropertyGroup.h"
|
||||
#include "AmbientOcclusionPropertyGroup.h"
|
||||
|
||||
class ZoneEntityItem : public EntityItem {
|
||||
public:
|
||||
|
@ -68,36 +70,20 @@ public:
|
|||
|
||||
virtual bool matchesJSONFilters(const QJsonObject& jsonFilters) const override;
|
||||
|
||||
KeyLightPropertyGroup getKeyLightProperties() const { return resultWithReadLock<KeyLightPropertyGroup>([&] { return _keyLightProperties; }); }
|
||||
AmbientLightPropertyGroup getAmbientLightProperties() const { return resultWithReadLock<AmbientLightPropertyGroup>([&] { return _ambientLightProperties; }); }
|
||||
|
||||
void setHazeMode(const uint32_t value);
|
||||
uint32_t getHazeMode() const;
|
||||
void setSkyboxMode(uint32_t value);
|
||||
uint32_t getSkyboxMode() const { return _skyboxMode; }
|
||||
|
||||
void setKeyLightMode(uint32_t value);
|
||||
uint32_t getKeyLightMode() const;
|
||||
uint32_t getKeyLightMode() const { return _keyLightMode; }
|
||||
|
||||
void setAmbientLightMode(uint32_t value);
|
||||
uint32_t getAmbientLightMode() const;
|
||||
uint32_t getAmbientLightMode() const { return _ambientLightMode; }
|
||||
|
||||
void setSkyboxMode(uint32_t value);
|
||||
uint32_t getSkyboxMode() const;
|
||||
void setHazeMode(const uint32_t value);
|
||||
uint32_t getHazeMode() const { return _hazeMode; }
|
||||
|
||||
void setBloomMode(const uint32_t value);
|
||||
uint32_t getBloomMode() const;
|
||||
|
||||
SkyboxPropertyGroup getSkyboxProperties() const { return resultWithReadLock<SkyboxPropertyGroup>([&] { return _skyboxProperties; }); }
|
||||
|
||||
const HazePropertyGroup& getHazeProperties() const { return _hazeProperties; }
|
||||
const BloomPropertyGroup& getBloomProperties() const { return _bloomProperties; }
|
||||
const ZoneAudioPropertyGroup& getAudioProperties() const { return _audioProperties; }
|
||||
|
||||
bool getFlyingAllowed() const { return _flyingAllowed; }
|
||||
void setFlyingAllowed(bool value) { _flyingAllowed = value; }
|
||||
bool getGhostingAllowed() const { return _ghostingAllowed; }
|
||||
void setGhostingAllowed(bool value) { _ghostingAllowed = value; }
|
||||
QString getFilterURL() const;
|
||||
void setFilterURL(const QString url);
|
||||
uint32_t getBloomMode() const { return _bloomMode; }
|
||||
|
||||
uint32_t getAvatarPriority() const { return _avatarPriority; }
|
||||
void setAvatarPriority(uint32_t value) { _avatarPriority = value; }
|
||||
|
@ -105,6 +91,28 @@ public:
|
|||
uint32_t getScreenshare() const { return _screenshare; }
|
||||
void setScreenshare(uint32_t value) { _screenshare = value; }
|
||||
|
||||
void setTonemappingMode(uint32_t value);
|
||||
uint32_t getTonemappingMode() const { return _tonemappingMode; }
|
||||
|
||||
void setAmbientOcclusionMode(const uint32_t value);
|
||||
uint32_t getAmbientOcclusionMode() const { return _ambientOcclusionMode; }
|
||||
|
||||
SkyboxPropertyGroup getSkyboxProperties() const { return resultWithReadLock<SkyboxPropertyGroup>([&] { return _skyboxProperties; }); }
|
||||
KeyLightPropertyGroup getKeyLightProperties() const { return resultWithReadLock<KeyLightPropertyGroup>([&] { return _keyLightProperties; }); }
|
||||
AmbientLightPropertyGroup getAmbientLightProperties() const { return resultWithReadLock<AmbientLightPropertyGroup>([&] { return _ambientLightProperties; }); }
|
||||
const HazePropertyGroup& getHazeProperties() const { return _hazeProperties; }
|
||||
const BloomPropertyGroup& getBloomProperties() const { return _bloomProperties; }
|
||||
const ZoneAudioPropertyGroup& getAudioProperties() const { return _audioProperties; }
|
||||
const TonemappingPropertyGroup& getTonemappingProperties() const { return _tonemappingProperties; }
|
||||
const AmbientOcclusionPropertyGroup& getAmbientOcclusionProperties() const { return _ambientOcclusionProperties; }
|
||||
|
||||
bool getFlyingAllowed() const { return _flyingAllowed; }
|
||||
void setFlyingAllowed(bool value) { _flyingAllowed = value; }
|
||||
bool getGhostingAllowed() const { return _ghostingAllowed; }
|
||||
void setGhostingAllowed(bool value) { _ghostingAllowed = value; }
|
||||
QString getFilterURL() const;
|
||||
void setFilterURL(const QString url);
|
||||
|
||||
void setUserData(const QString& value) override;
|
||||
|
||||
bool keyLightPropertiesChanged() const { return _keyLightPropertiesChanged; }
|
||||
|
@ -112,6 +120,8 @@ public:
|
|||
bool skyboxPropertiesChanged() const { return _skyboxPropertiesChanged; }
|
||||
bool hazePropertiesChanged() const { return _hazePropertiesChanged; }
|
||||
bool bloomPropertiesChanged() const { return _bloomPropertiesChanged; }
|
||||
bool tonemappingPropertiesChanged() const { return _tonemappingPropertiesChanged; }
|
||||
bool ambientOcclusionPropertiesChanged() const { return _ambientOcclusionPropertiesChanged; }
|
||||
|
||||
void resetRenderingPropertiesChanged();
|
||||
|
||||
|
@ -142,35 +152,35 @@ protected:
|
|||
ShapeType _shapeType { DEFAULT_SHAPE_TYPE };
|
||||
QString _compoundShapeURL;
|
||||
|
||||
// The following 3 values are the defaults for zone creation
|
||||
uint32_t _keyLightMode { COMPONENT_MODE_INHERIT };
|
||||
uint32_t _skyboxMode { COMPONENT_MODE_INHERIT };
|
||||
uint32_t _ambientLightMode { COMPONENT_MODE_INHERIT };
|
||||
|
||||
uint32_t _hazeMode { COMPONENT_MODE_INHERIT };
|
||||
uint32_t _bloomMode { COMPONENT_MODE_INHERIT };
|
||||
uint32_t _avatarPriority { COMPONENT_MODE_INHERIT };
|
||||
uint32_t _screenshare { COMPONENT_MODE_INHERIT };
|
||||
uint32_t _tonemappingMode { COMPONENT_MODE_INHERIT };
|
||||
uint32_t _ambientOcclusionMode { COMPONENT_MODE_INHERIT };
|
||||
|
||||
SkyboxPropertyGroup _skyboxProperties;
|
||||
HazePropertyGroup _hazeProperties;
|
||||
BloomPropertyGroup _bloomProperties;
|
||||
ZoneAudioPropertyGroup _audioProperties;
|
||||
TonemappingPropertyGroup _tonemappingProperties;
|
||||
AmbientOcclusionPropertyGroup _ambientOcclusionProperties;
|
||||
|
||||
bool _flyingAllowed { DEFAULT_FLYING_ALLOWED };
|
||||
bool _ghostingAllowed { DEFAULT_GHOSTING_ALLOWED };
|
||||
QString _filterURL { DEFAULT_FILTER_URL };
|
||||
|
||||
// Avatar-updates priority
|
||||
uint32_t _avatarPriority { COMPONENT_MODE_INHERIT };
|
||||
|
||||
// Screen-sharing zone
|
||||
uint32_t _screenshare { COMPONENT_MODE_INHERIT };
|
||||
|
||||
// Dirty flags turn true when either keylight properties is changing values.
|
||||
bool _keyLightPropertiesChanged { false };
|
||||
bool _ambientLightPropertiesChanged { false };
|
||||
bool _skyboxPropertiesChanged { false };
|
||||
bool _hazePropertiesChanged { false };
|
||||
bool _bloomPropertiesChanged { false };
|
||||
bool _tonemappingPropertiesChanged { false };
|
||||
bool _ambientOcclusionPropertiesChanged { false };
|
||||
|
||||
static bool _drawZoneBoundaries;
|
||||
static bool _zonesArePickable;
|
||||
|
|
59
libraries/graphics/src/graphics/AmbientOcclusion.h
Normal file
59
libraries/graphics/src/graphics/AmbientOcclusion.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// AmbientOcclusion.h
|
||||
// libraries/graphics/src/graphics
|
||||
//
|
||||
// Created by HifiExperiments 6/24/24
|
||||
// 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
|
||||
//
|
||||
#ifndef hifi_model_AmbientOcclusion_h
|
||||
#define hifi_model_AmbientOcclusion_h
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <AmbientOcclusionTechnique.h>
|
||||
|
||||
namespace graphics {
|
||||
class AmbientOcclusion {
|
||||
public:
|
||||
AmbientOcclusion() {}
|
||||
|
||||
void setTechnique(const AmbientOcclusionTechnique technique) { _technique = technique; }
|
||||
void setJitter(const bool jitter) { _jitter = jitter; }
|
||||
void setResolutionLevel(const uint8_t resolutionLevel) { _resolutionLevel = resolutionLevel; }
|
||||
void setEdgeSharpness(const float edgeSharpness) { _edgeSharpness = edgeSharpness; }
|
||||
void setBlurRadius(const uint8_t blurRadius) { _blurRadius = blurRadius; }
|
||||
void setAORadius(const float aoRadius) { _aoRadius = aoRadius; }
|
||||
void setAOObscuranceLevel(const float aoObscuranceLevel) { _aoObscuranceLevel = aoObscuranceLevel; }
|
||||
void setAOFalloffAngle(const float aoFalloffAngle) { _aoFalloffAngle = aoFalloffAngle; }
|
||||
void setAOSamplingAmount(const float aoSamplingAmount) { _aoSamplingAmount = aoSamplingAmount; }
|
||||
void setSSAONumSpiralTurns(const float ssaoNumSpiralTurns) { _ssaoNumSpiralTurns = ssaoNumSpiralTurns; }
|
||||
|
||||
AmbientOcclusionTechnique getTechnique() const { return _technique; }
|
||||
bool getJitter() const { return _jitter; }
|
||||
uint8_t getResolutionLevel() const { return _resolutionLevel; }
|
||||
float getEdgeSharpness() const { return _edgeSharpness; }
|
||||
uint8_t getBlurRadius() const { return _blurRadius; }
|
||||
float getAORadius() const { return _aoRadius; }
|
||||
float getAOObscuranceLevel() const { return _aoObscuranceLevel; }
|
||||
float getAOFalloffAngle() const { return _aoFalloffAngle; }
|
||||
float getAOSamplingAmount() const { return _aoSamplingAmount; }
|
||||
float getSSAONumSpiralTurns() const { return _ssaoNumSpiralTurns; }
|
||||
|
||||
private:
|
||||
AmbientOcclusionTechnique _technique { AmbientOcclusionTechnique::SSAO };
|
||||
bool _jitter { false };
|
||||
uint8_t _resolutionLevel { 2 };
|
||||
float _edgeSharpness { 1.0f };
|
||||
uint8_t _blurRadius { 4 };
|
||||
float _aoRadius { 1.0f };
|
||||
float _aoObscuranceLevel { 0.5f };
|
||||
float _aoFalloffAngle { 0.25f };
|
||||
float _aoSamplingAmount { 0.5f };
|
||||
float _ssaoNumSpiralTurns { 7.0f };
|
||||
};
|
||||
using AmbientOcclusionPointer = std::shared_ptr<AmbientOcclusion>;
|
||||
}
|
||||
#endif // hifi_model_AmbientOcclusion_h
|
35
libraries/graphics/src/graphics/Tonemapping.h
Normal file
35
libraries/graphics/src/graphics/Tonemapping.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// Tonemapping.h
|
||||
// libraries/graphics/src/graphics
|
||||
//
|
||||
// Created by HifiExperiments on 6/24/24
|
||||
// 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
|
||||
//
|
||||
#ifndef hifi_model_Tonemapping_h
|
||||
#define hifi_model_Tonemapping_h
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <TonemappingCurve.h>
|
||||
|
||||
namespace graphics {
|
||||
class Tonemapping {
|
||||
public:
|
||||
Tonemapping() {}
|
||||
|
||||
void setCurve(const TonemappingCurve curve) { _curve = curve; }
|
||||
void setExposure(const float exposure) { _exposure = exposure; }
|
||||
|
||||
TonemappingCurve getCurve() const { return _curve; }
|
||||
float getExposure() const { return _exposure; }
|
||||
|
||||
private:
|
||||
TonemappingCurve _curve { TonemappingCurve::SRGB };
|
||||
float _exposure { 0.0f };
|
||||
};
|
||||
using TonemappingPointer = std::shared_ptr<Tonemapping>;
|
||||
}
|
||||
#endif // hifi_model_Tonemapping_h
|
|
@ -299,6 +299,7 @@ enum class EntityVersion : PacketVersion {
|
|||
ShapeUnlit,
|
||||
AmbientColor,
|
||||
SoundEntities,
|
||||
TonemappingAndAmbientOcclusion,
|
||||
|
||||
// Add new versions above here
|
||||
NUM_PACKET_TYPE,
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include "TextEffect.h"
|
||||
#include "TextAlignment.h"
|
||||
#include "MirrorMode.h"
|
||||
#include "TonemappingCurve.h"
|
||||
#include "AmbientOcclusionTechnique.h"
|
||||
|
||||
#include "OctreeConstants.h"
|
||||
#include "OctreeElement.h"
|
||||
|
@ -285,6 +287,8 @@ public:
|
|||
static int unpackDataFromBytes(const unsigned char* dataBytes, TextEffect& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, TextAlignment& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, MirrorMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, TonemappingCurve& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, AmbientOcclusionTechnique& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec2& result);
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec3& result);
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, glm::u8vec3& result);
|
||||
|
|
|
@ -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<AmbientOcclusionFramebuffer>();
|
||||
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,33 @@ 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()) {
|
||||
const float falloffAngle = std::min(1.0f - EPSILON, ambientOcclusion->getAOFalloffAngle());
|
||||
if (shouldUpdateTechnique || falloffAngle != _aoParametersBuffer->getFalloffAngle()) {
|
||||
auto& current = _aoParametersBuffer.edit()._falloffInfo;
|
||||
current.x = config.hbaoFalloffAngle;
|
||||
current.x = falloffAngle;
|
||||
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 - current.x * current.x);
|
||||
current.w = 1.0f / current.z;
|
||||
}
|
||||
|
||||
if (shouldUpdateTechnique || config.hbaoNumSamples != _aoParametersBuffer->getNumSamples()) {
|
||||
const int numSamples = std::max(1, (int)(ambientOcclusion->getAOSamplingAmount() * MAX_HBAO_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 +409,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 = std::max(1, (int)(ambientOcclusion->getAOSamplingAmount() * MAX_SSAO_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 +600,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<AmbientOcclusionStage>();
|
||||
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 +668,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 +842,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 +923,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);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "DeferredFrameTransform.h"
|
||||
#include "DeferredFramebuffer.h"
|
||||
#include "SurfaceGeometryPass.h"
|
||||
#include "AmbientOcclusionStage.h"
|
||||
|
||||
#include "ssao_shared.h"
|
||||
|
||||
|
@ -70,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<AmbientOcclusionFramebuffer>;
|
||||
|
||||
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)
|
||||
|
@ -108,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();
|
||||
|
@ -153,12 +157,13 @@ signals:
|
|||
|
||||
class AmbientOcclusionEffect {
|
||||
public:
|
||||
using Input = render::VaryingSet4<LightingModelPointer, DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>;
|
||||
using Input = render::VaryingSet5<LightingModelPointer, DeferredFrameTransformPointer, DeferredFramebufferPointer,
|
||||
LinearDepthFramebufferPointer, AmbientOcclusionStage::FramePointer>;
|
||||
using Output = render::VaryingSet2<AmbientOcclusionFramebufferPointer, gpu::BufferView>;
|
||||
using Config = AmbientOcclusionEffectConfig;
|
||||
using JobModel = render::Job::ModelIO<AmbientOcclusionEffect, Input, Output, Config>;
|
||||
|
||||
AmbientOcclusionEffect();
|
||||
AmbientOcclusionEffect() {}
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
|
||||
|
@ -166,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; }
|
||||
|
@ -182,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<AOParameters>;
|
||||
|
||||
|
@ -191,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<BlurParameters>;
|
||||
|
||||
using FrameParametersBuffer = gpu::StructBuffer< AmbientOcclusionFrameParams>;
|
||||
|
||||
void updateParameters(const graphics::AmbientOcclusionPointer ambientOcclusion);
|
||||
void updateBlurParameters();
|
||||
void updateFramebufferSizes();
|
||||
void updateRandomSamples();
|
||||
|
@ -213,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();
|
||||
|
@ -229,9 +230,14 @@ private:
|
|||
|
||||
AmbientOcclusionFramebufferPointer _framebuffer;
|
||||
std::array<float, SSAO_RANDOM_SAMPLE_COUNT * SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT> _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<graphics::AmbientOcclusion>() };
|
||||
|
||||
gpu::RangeTimerPointer _gpuTimer;
|
||||
|
||||
friend class DebugAmbientOcclusion;
|
||||
|
@ -246,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();
|
||||
|
@ -260,7 +266,7 @@ public:
|
|||
using Config = DebugAmbientOcclusionConfig;
|
||||
using JobModel = render::Job::ModelI<DebugAmbientOcclusion, Inputs, Config>;
|
||||
|
||||
DebugAmbientOcclusion();
|
||||
DebugAmbientOcclusion() {}
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||
|
@ -281,7 +287,7 @@ private:
|
|||
|
||||
gpu::PipelinePointer _debugPipeline;
|
||||
|
||||
bool _showCursorPixel{ false };
|
||||
bool _showCursorPixel { false };
|
||||
};
|
||||
|
||||
#endif // hifi_AmbientOcclusionEffect_h
|
||||
|
|
56
libraries/render-utils/src/AmbientOcclusionStage.cpp
Normal file
56
libraries/render-utils/src/AmbientOcclusionStage.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// AmbientOcclusionStage.cpp
|
||||
//
|
||||
// Created by HifiExperiments on 6/24/24
|
||||
// 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
|
||||
//
|
||||
#include "AmbientOcclusionStage.h"
|
||||
|
||||
#include <gpu/Context.h>
|
||||
|
||||
std::string AmbientOcclusionStage::_stageName { "AMBIENT_OCCLUSION_STAGE" };
|
||||
const AmbientOcclusionStage::Index AmbientOcclusionStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX };
|
||||
|
||||
AmbientOcclusionStage::Index AmbientOcclusionStage::findAmbientOcclusion(const AmbientOcclusionPointer& ambientOcclusion) const {
|
||||
auto found = _ambientOcclusionMap.find(ambientOcclusion);
|
||||
if (found != _ambientOcclusionMap.end()) {
|
||||
return INVALID_INDEX;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
}
|
||||
|
||||
AmbientOcclusionStage::Index AmbientOcclusionStage::addAmbientOcclusion(const AmbientOcclusionPointer& ambientOcclusion) {
|
||||
auto found = _ambientOcclusionMap.find(ambientOcclusion);
|
||||
if (found == _ambientOcclusionMap.end()) {
|
||||
auto ambientOcclusionId = _ambientOcclusions.newElement(ambientOcclusion);
|
||||
// Avoid failing to allocate a ambientOcclusion, just pass
|
||||
if (ambientOcclusionId != INVALID_INDEX) {
|
||||
// Insert the ambientOcclusion and its index in the reverse map
|
||||
_ambientOcclusionMap.insert(AmbientOcclusionMap::value_type(ambientOcclusion, ambientOcclusionId));
|
||||
}
|
||||
return ambientOcclusionId;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
}
|
||||
|
||||
AmbientOcclusionStage::AmbientOcclusionPointer AmbientOcclusionStage::removeAmbientOcclusion(Index index) {
|
||||
AmbientOcclusionPointer removed = _ambientOcclusions.freeElement(index);
|
||||
if (removed) {
|
||||
_ambientOcclusionMap.erase(removed);
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
AmbientOcclusionStageSetup::AmbientOcclusionStageSetup() {}
|
||||
|
||||
void AmbientOcclusionStageSetup::run(const render::RenderContextPointer& renderContext) {
|
||||
auto stage = renderContext->_scene->getStage(AmbientOcclusionStage::getName());
|
||||
if (!stage) {
|
||||
renderContext->_scene->resetStage(AmbientOcclusionStage::getName(), std::make_shared<AmbientOcclusionStage>());
|
||||
}
|
||||
}
|
84
libraries/render-utils/src/AmbientOcclusionStage.h
Normal file
84
libraries/render-utils/src/AmbientOcclusionStage.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// AmbientOcclusionStage.h
|
||||
//
|
||||
// Created by HifiExperiments on 6/24/24
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_render_utils_AmbientOcclusionStage_h
|
||||
#define hifi_render_utils_AmbientOcclusionStage_h
|
||||
|
||||
#include <graphics/Stage.h>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <render/IndexedContainer.h>
|
||||
#include <render/Stage.h>
|
||||
|
||||
#include <render/Forward.h>
|
||||
#include <render/DrawTask.h>
|
||||
#include <graphics/AmbientOcclusion.h>
|
||||
|
||||
// AmbientOcclusion stage to set up ambientOcclusion-related rendering tasks
|
||||
class AmbientOcclusionStage : public render::Stage {
|
||||
public:
|
||||
static std::string _stageName;
|
||||
static const std::string& getName() { return _stageName; }
|
||||
|
||||
using Index = render::indexed_container::Index;
|
||||
static const Index INVALID_INDEX;
|
||||
static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; }
|
||||
|
||||
using AmbientOcclusionPointer = graphics::AmbientOcclusionPointer;
|
||||
using AmbientOcclusions = render::indexed_container::IndexedPointerVector<graphics::AmbientOcclusion>;
|
||||
using AmbientOcclusionMap = std::unordered_map<AmbientOcclusionPointer, Index>;
|
||||
|
||||
using AmbientOcclusionIndices = std::vector<Index>;
|
||||
|
||||
Index findAmbientOcclusion(const AmbientOcclusionPointer& ambientOcclusion) const;
|
||||
Index addAmbientOcclusion(const AmbientOcclusionPointer& ambientOcclusion);
|
||||
|
||||
AmbientOcclusionPointer removeAmbientOcclusion(Index index);
|
||||
|
||||
bool checkAmbientOcclusionId(Index index) const { return _ambientOcclusions.checkIndex(index); }
|
||||
|
||||
Index getNumAmbientOcclusions() const { return _ambientOcclusions.getNumElements(); }
|
||||
Index getNumFreeAmbientOcclusions() const { return _ambientOcclusions.getNumFreeIndices(); }
|
||||
Index getNumAllocatedAmbientOcclusions() const { return _ambientOcclusions.getNumAllocatedIndices(); }
|
||||
|
||||
AmbientOcclusionPointer getAmbientOcclusion(Index ambientOcclusionId) const {
|
||||
return _ambientOcclusions.get(ambientOcclusionId);
|
||||
}
|
||||
|
||||
AmbientOcclusions _ambientOcclusions;
|
||||
AmbientOcclusionMap _ambientOcclusionMap;
|
||||
|
||||
class Frame {
|
||||
public:
|
||||
Frame() {}
|
||||
|
||||
void clear() { _ambientOcclusions.clear(); }
|
||||
|
||||
void pushAmbientOcclusion(AmbientOcclusionStage::Index index) { _ambientOcclusions.emplace_back(index); }
|
||||
|
||||
AmbientOcclusionStage::AmbientOcclusionIndices _ambientOcclusions;
|
||||
};
|
||||
using FramePointer = std::shared_ptr<Frame>;
|
||||
|
||||
Frame _currentFrame;
|
||||
};
|
||||
using AmbientOcclusionStagePointer = std::shared_ptr<AmbientOcclusionStage>;
|
||||
|
||||
class AmbientOcclusionStageSetup {
|
||||
public:
|
||||
using JobModel = render::Job::Model<AmbientOcclusionStageSetup>;
|
||||
|
||||
AmbientOcclusionStageSetup();
|
||||
void run(const render::RenderContextPointer& renderContext);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif
|
|
@ -25,6 +25,14 @@ void FetchCurrentFrames::run(const render::RenderContextPointer& renderContext,
|
|||
auto bloomStage = renderContext->_scene->getStage<BloomStage>();
|
||||
assert(bloomStage);
|
||||
output.edit3() = std::make_shared<BloomStage::Frame>(bloomStage->_currentFrame);
|
||||
|
||||
auto tonemappingStage = renderContext->_scene->getStage<TonemappingStage>();
|
||||
assert(tonemappingStage);
|
||||
output.edit4() = std::make_shared<TonemappingStage::Frame>(tonemappingStage->_currentFrame);
|
||||
|
||||
auto ambientOcclusionStage = renderContext->_scene->getStage<AmbientOcclusionStage>();
|
||||
assert(ambientOcclusionStage);
|
||||
output.edit5() = std::make_shared<AmbientOcclusionStage::Frame>(ambientOcclusionStage->_currentFrame);
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,4 +55,3 @@ void AssembleLightingStageTask::build(JobModel& task, const render::Varying& inp
|
|||
|
||||
output = Output(currentStageFrames, zones);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,16 @@
|
|||
#include "BackgroundStage.h"
|
||||
#include "HazeStage.h"
|
||||
#include "BloomStage.h"
|
||||
#include "TonemappingStage.h"
|
||||
#include "AmbientOcclusionStage.h"
|
||||
|
||||
#include "ZoneRenderer.h"
|
||||
|
||||
|
||||
class FetchCurrentFrames {
|
||||
public:
|
||||
using Output = render::VaryingSet4<LightStage::FramePointer, BackgroundStage::FramePointer, HazeStage::FramePointer, BloomStage::FramePointer>;
|
||||
using Output = render::VaryingSet6<LightStage::FramePointer, BackgroundStage::FramePointer, HazeStage::FramePointer,
|
||||
BloomStage::FramePointer, TonemappingStage::FramePointer, AmbientOcclusionStage::FramePointer>;
|
||||
using JobModel = render::Job::ModelO<FetchCurrentFrames, Output>;
|
||||
|
||||
FetchCurrentFrames() {}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include <graphics/ShaderConstants.h>
|
||||
|
||||
std::string BackgroundStage::_stageName { "BACKGROUND_STAGE"};
|
||||
std::string BackgroundStage::_stageName { "BACKGROUND_STAGE" };
|
||||
const BackgroundStage::Index BackgroundStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX };
|
||||
|
||||
BackgroundStage::Index BackgroundStage::findBackground(const BackgroundPointer& background) const {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include <gpu/Context.h>
|
||||
|
||||
std::string BloomStage::_stageName { "BLOOM_STAGE"};
|
||||
std::string BloomStage::_stageName { "BLOOM_STAGE" };
|
||||
const BloomStage::Index BloomStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX };
|
||||
|
||||
BloomStage::Index BloomStage::findBloom(const BloomPointer& bloom) const {
|
||||
|
|
|
@ -81,26 +81,4 @@ public:
|
|||
protected:
|
||||
};
|
||||
|
||||
class FetchBloomConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float bloomIntensity MEMBER bloomIntensity WRITE setBloomIntensity NOTIFY dirty);
|
||||
Q_PROPERTY(float bloomThreshold MEMBER bloomThreshold WRITE setBloomThreshold NOTIFY dirty);
|
||||
Q_PROPERTY(float bloomSize MEMBER bloomSize WRITE setBloomSize NOTIFY dirty);
|
||||
|
||||
public:
|
||||
FetchBloomConfig() : render::Job::Config() {}
|
||||
|
||||
float bloomIntensity { graphics::Bloom::INITIAL_BLOOM_INTENSITY };
|
||||
float bloomThreshold { graphics::Bloom::INITIAL_BLOOM_THRESHOLD };
|
||||
float bloomSize { graphics::Bloom::INITIAL_BLOOM_SIZE };
|
||||
|
||||
public slots:
|
||||
void setBloomIntensity(const float value) { bloomIntensity = value; emit dirty(); }
|
||||
void setBloomThreshold(const float value) { bloomThreshold = value; emit dirty(); }
|
||||
void setBloomSize(const float value) { bloomSize = value; emit dirty(); }
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -662,5 +662,14 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) {
|
|||
_defaultHazeID = hazeStage->addHaze(_defaultHaze);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_defaultTonemapping) {
|
||||
auto tonemappingStage = renderContext->_scene->getStage<TonemappingStage>();
|
||||
if (tonemappingStage) {
|
||||
auto tonemapping = std::make_shared<graphics::Tonemapping>();
|
||||
|
||||
_defaultTonemapping = tonemapping;
|
||||
_defaultTonemappingID = tonemappingStage->addTonemapping(_defaultTonemapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "LightClusters.h"
|
||||
#include "BackgroundStage.h"
|
||||
#include "HazeStage.h"
|
||||
#include "TonemappingStage.h"
|
||||
|
||||
#include "SurfaceGeometryPass.h"
|
||||
#include "SubsurfaceScattering.h"
|
||||
|
@ -162,11 +163,13 @@ public:
|
|||
|
||||
protected:
|
||||
graphics::LightPointer _defaultLight;
|
||||
LightStage::Index _defaultLightID{ LightStage::INVALID_INDEX };
|
||||
LightStage::Index _defaultLightID { LightStage::INVALID_INDEX };
|
||||
graphics::SunSkyStagePointer _defaultBackground;
|
||||
BackgroundStage::Index _defaultBackgroundID{ BackgroundStage::INVALID_INDEX };
|
||||
graphics::HazePointer _defaultHaze{ nullptr };
|
||||
HazeStage::Index _defaultHazeID{ HazeStage::INVALID_INDEX };
|
||||
BackgroundStage::Index _defaultBackgroundID { BackgroundStage::INVALID_INDEX };
|
||||
graphics::HazePointer _defaultHaze { nullptr };
|
||||
HazeStage::Index _defaultHazeID { HazeStage::INVALID_INDEX };
|
||||
graphics::TonemappingPointer _defaultTonemapping { nullptr };
|
||||
TonemappingStage::Index _defaultTonemappingID { TonemappingStage::INVALID_INDEX };
|
||||
graphics::SkyboxPointer _defaultSkybox { new ProceduralSkybox() };
|
||||
NetworkTexturePointer _defaultSkyboxNetworkTexture;
|
||||
NetworkTexturePointer _defaultAmbientNetworkTexture;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include <gpu/Context.h>
|
||||
|
||||
std::string HazeStage::_stageName { "HAZE_STAGE"};
|
||||
std::string HazeStage::_stageName { "HAZE_STAGE" };
|
||||
const HazeStage::Index HazeStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX };
|
||||
|
||||
HazeStage::Index HazeStage::findHaze(const HazePointer& haze) const {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "ViewFrustum.h"
|
||||
|
||||
std::string LightStage::_stageName { "LIGHT_STAGE"};
|
||||
std::string LightStage::_stageName { "LIGHT_STAGE" };
|
||||
// The bias matrix goes from homogeneous coordinates to UV coords (see http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/#basic-shader)
|
||||
const glm::mat4 LightStage::Shadow::_biasMatrix {
|
||||
0.5, 0.0, 0.0, 0.0,
|
||||
|
|
|
@ -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 <render/Forward.h>
|
||||
#include <render/DrawTask.h>
|
||||
|
||||
// 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<LightingModel>;
|
||||
|
||||
|
||||
|
||||
|
||||
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; }
|
||||
|
|
|
@ -137,6 +137,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
const auto backgroundFrame = currentStageFrames[1];
|
||||
const auto& hazeFrame = currentStageFrames[2];
|
||||
const auto& bloomFrame = currentStageFrames[3];
|
||||
const auto& tonemappingFrame = currentStageFrames[4];
|
||||
const auto& ambientOcclusionFrame = currentStageFrames[5];
|
||||
|
||||
// Shadow Task Outputs
|
||||
const auto& shadowTaskOutputs = inputs.get3();
|
||||
|
@ -198,7 +200,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
const auto scatteringResource = task.addJob<SubsurfaceScattering>("Scattering");
|
||||
|
||||
// AO job
|
||||
const auto ambientOcclusionInputs = AmbientOcclusionEffect::Input(lightingModel, deferredFrameTransform, deferredFramebuffer, linearDepthTarget).asVarying();
|
||||
const auto ambientOcclusionInputs = AmbientOcclusionEffect::Input(lightingModel, deferredFrameTransform, deferredFramebuffer, linearDepthTarget, ambientOcclusionFrame).asVarying();
|
||||
const auto ambientOcclusionOutputs = task.addJob<AmbientOcclusionEffect>("AmbientOcclusion", ambientOcclusionInputs);
|
||||
const auto ambientOcclusionFramebuffer = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Output>(0);
|
||||
const auto ambientOcclusionUniforms = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Output>(1);
|
||||
|
@ -250,8 +252,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
const auto destFramebuffer = static_cast<gpu::FramebufferPointer>(nullptr);
|
||||
|
||||
// Lighting Buffer ready for tone mapping
|
||||
const auto toneMappingInputs = ToneMapAndResample::Input(lightingFramebuffer, destFramebuffer).asVarying();
|
||||
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapping", toneMappingInputs, depth);
|
||||
const auto toneMappingInputs = ToneMapAndResample::Input(lightingFramebuffer, destFramebuffer, tonemappingFrame).asVarying();
|
||||
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapping", toneMappingInputs);
|
||||
|
||||
// Debugging task is happening in the "over" layer after tone mapping and just before HUD
|
||||
{ // Debug the bounds of the rendered items, still look at the zbuffer
|
||||
|
|
|
@ -108,6 +108,7 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
|
|||
const auto lightFrame = currentStageFrames[0];
|
||||
const auto backgroundFrame = currentStageFrames[1];
|
||||
const auto hazeFrame = currentStageFrames[2];
|
||||
const auto tonemappingFrame = currentStageFrames[4];
|
||||
|
||||
const auto& zones = lightingStageInputs[1];
|
||||
|
||||
|
@ -178,8 +179,8 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
|
|||
|
||||
const auto destFramebuffer = static_cast<gpu::FramebufferPointer>(nullptr);
|
||||
|
||||
const auto toneMappingInputs = ToneMapAndResample::Input(resolvedFramebuffer, destFramebuffer).asVarying();
|
||||
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapping", toneMappingInputs, depth);
|
||||
const auto toneMappingInputs = ToneMapAndResample::Input(resolvedFramebuffer, destFramebuffer, tonemappingFrame).asVarying();
|
||||
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapping", toneMappingInputs);
|
||||
// HUD Layer
|
||||
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(toneMappedBuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
|
||||
task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs);
|
||||
|
|
|
@ -25,10 +25,9 @@ using namespace shader::render_utils::program;
|
|||
gpu::PipelinePointer ToneMapAndResample::_pipeline;
|
||||
gpu::PipelinePointer ToneMapAndResample::_mirrorPipeline;
|
||||
|
||||
ToneMapAndResample::ToneMapAndResample(size_t depth) {
|
||||
ToneMapAndResample::ToneMapAndResample() {
|
||||
Parameters parameters;
|
||||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||
_depth = depth;
|
||||
}
|
||||
|
||||
void ToneMapAndResample::init() {
|
||||
|
@ -44,13 +43,13 @@ void ToneMapAndResample::init() {
|
|||
|
||||
void ToneMapAndResample::setExposure(float exposure) {
|
||||
auto& params = _parametersBuffer.get<Parameters>();
|
||||
if (params._exposure != exposure) {
|
||||
_parametersBuffer.edit<Parameters>()._exposure = exposure;
|
||||
if (_exposure != exposure) {
|
||||
_exposure = exposure;
|
||||
_parametersBuffer.edit<Parameters>()._twoPowExposure = pow(2.0, exposure);
|
||||
}
|
||||
}
|
||||
|
||||
void ToneMapAndResample::setToneCurve(ToneCurve curve) {
|
||||
void ToneMapAndResample::setCurve(TonemappingCurve curve) {
|
||||
auto& params = _parametersBuffer.get<Parameters>();
|
||||
if (params._toneCurve != (int)curve) {
|
||||
_parametersBuffer.edit<Parameters>()._toneCurve = (int)curve;
|
||||
|
@ -58,8 +57,9 @@ void ToneMapAndResample::setToneCurve(ToneCurve curve) {
|
|||
}
|
||||
|
||||
void ToneMapAndResample::configure(const Config& config) {
|
||||
setExposure(config.exposure);
|
||||
setToneCurve((ToneCurve)config.curve);
|
||||
_debug = config.debug;
|
||||
_debugExposure = config.exposure;
|
||||
_debugCurve = (TonemappingCurve)config.curve;
|
||||
}
|
||||
|
||||
void ToneMapAndResample::run(const RenderContextPointer& renderContext, const Input& input, Output& output) {
|
||||
|
@ -70,6 +70,21 @@ void ToneMapAndResample::run(const RenderContextPointer& renderContext, const In
|
|||
|
||||
auto lightingBuffer = input.get0()->getRenderBuffer(0);
|
||||
auto destinationFramebuffer = input.get1();
|
||||
const auto tonemappingFrame = input.get2();
|
||||
|
||||
const auto& tonemappingStage = renderContext->_scene->getStage<TonemappingStage>();
|
||||
graphics::TonemappingPointer tonemapping;
|
||||
if (tonemappingStage && tonemappingFrame->_tonemappings.size()) {
|
||||
tonemapping = tonemappingStage->getTonemapping(tonemappingFrame->_tonemappings.front());
|
||||
}
|
||||
|
||||
if (_debug) {
|
||||
setCurve(_debugCurve);
|
||||
setExposure(_debugExposure);
|
||||
} else if (tonemapping) {
|
||||
setCurve(tonemapping->getCurve());
|
||||
setExposure(tonemapping->getExposure());
|
||||
}
|
||||
|
||||
if (!destinationFramebuffer) {
|
||||
destinationFramebuffer = args->_blitFramebuffer;
|
||||
|
|
|
@ -20,28 +20,24 @@
|
|||
#include <render/Forward.h>
|
||||
#include <render/DrawTask.h>
|
||||
|
||||
enum class ToneCurve {
|
||||
// Different tone curve available
|
||||
None,
|
||||
Gamma22,
|
||||
Reinhard,
|
||||
Filmic,
|
||||
};
|
||||
#include "TonemappingStage.h"
|
||||
|
||||
class ToneMappingConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float exposure MEMBER exposure WRITE setExposure);
|
||||
Q_PROPERTY(int curve MEMBER curve WRITE setCurve);
|
||||
Q_PROPERTY(bool debug MEMBER debug WRITE setDebug NOTIFY dirty);
|
||||
Q_PROPERTY(int curve MEMBER curve WRITE setCurve NOTIFY dirty);
|
||||
Q_PROPERTY(float exposure MEMBER exposure WRITE setExposure NOTIFY dirty);
|
||||
|
||||
public:
|
||||
ToneMappingConfig() : render::Job::Config(true) {}
|
||||
|
||||
void setDebug(bool newDebug) { debug = newDebug; emit dirty(); }
|
||||
void setCurve(int newCurve) { curve = std::max(0, std::min((int)TonemappingCurve::FILMIC, newCurve)); emit dirty(); }
|
||||
void setExposure(float newExposure) { exposure = newExposure; emit dirty(); }
|
||||
void setCurve(int newCurve) { curve = std::max((int)ToneCurve::None, std::min((int)ToneCurve::Filmic, newCurve)); emit dirty(); }
|
||||
|
||||
|
||||
float exposure{ 0.0f };
|
||||
int curve{ (int)ToneCurve::Gamma22 };
|
||||
bool debug { false };
|
||||
int curve { (int)TonemappingCurve::SRGB };
|
||||
float exposure { 0.0f };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
@ -49,17 +45,14 @@ signals:
|
|||
|
||||
class ToneMapAndResample {
|
||||
public:
|
||||
ToneMapAndResample(size_t depth);
|
||||
ToneMapAndResample();
|
||||
virtual ~ToneMapAndResample() {}
|
||||
|
||||
void setCurve(TonemappingCurve curve);
|
||||
void setExposure(float exposure);
|
||||
float getExposure() const { return _parametersBuffer.get<Parameters>()._exposure; }
|
||||
|
||||
void setToneCurve(ToneCurve curve);
|
||||
ToneCurve getToneCurve() const { return (ToneCurve)_parametersBuffer.get<Parameters>()._toneCurve; }
|
||||
|
||||
// Inputs: lightingFramebuffer, destinationFramebuffer
|
||||
using Input = render::VaryingSet2<gpu::FramebufferPointer, gpu::FramebufferPointer>;
|
||||
// Inputs: lightingFramebuffer, destinationFramebuffer, tonemappingFrame
|
||||
using Input = render::VaryingSet3<gpu::FramebufferPointer, gpu::FramebufferPointer, TonemappingStage::FramePointer>;
|
||||
using Output = gpu::FramebufferPointer;
|
||||
using Config = ToneMappingConfig;
|
||||
using JobModel = render::Job::ModelIO<ToneMapAndResample, Input, Output, Config>;
|
||||
|
@ -73,22 +66,19 @@ protected:
|
|||
|
||||
gpu::FramebufferPointer _destinationFrameBuffer;
|
||||
|
||||
float _factor { 2.0f };
|
||||
size_t _depth { 0 };
|
||||
|
||||
gpu::FramebufferPointer getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer);
|
||||
|
||||
private:
|
||||
gpu::PipelinePointer _blitLightBuffer;
|
||||
float _exposure { 0.0f };
|
||||
|
||||
bool _debug { false };
|
||||
TonemappingCurve _debugCurve { TonemappingCurve::SRGB };
|
||||
float _debugExposure { 0.0f };
|
||||
|
||||
// Class describing the uniform buffer with all the parameters common to the tone mapping shaders
|
||||
class Parameters {
|
||||
public:
|
||||
float _exposure = 0.0f;
|
||||
float _twoPowExposure = 1.0f;
|
||||
glm::vec2 spareA;
|
||||
int _toneCurve = (int)ToneCurve::Gamma22;
|
||||
glm::vec3 spareB;
|
||||
int _toneCurve = (int)TonemappingCurve::SRGB;
|
||||
|
||||
Parameters() {}
|
||||
};
|
||||
|
|
56
libraries/render-utils/src/TonemappingStage.cpp
Normal file
56
libraries/render-utils/src/TonemappingStage.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// TonemappingStage.cpp
|
||||
//
|
||||
// Created by HifiExperiments on 6/24/24
|
||||
// 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
|
||||
//
|
||||
#include "TonemappingStage.h"
|
||||
|
||||
#include <gpu/Context.h>
|
||||
|
||||
std::string TonemappingStage::_stageName { "TONEMAPPING_STAGE" };
|
||||
const TonemappingStage::Index TonemappingStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX };
|
||||
|
||||
TonemappingStage::Index TonemappingStage::findTonemapping(const TonemappingPointer& tonemapping) const {
|
||||
auto found = _tonemappingMap.find(tonemapping);
|
||||
if (found != _tonemappingMap.end()) {
|
||||
return INVALID_INDEX;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
}
|
||||
|
||||
TonemappingStage::Index TonemappingStage::addTonemapping(const TonemappingPointer& tonemapping) {
|
||||
auto found = _tonemappingMap.find(tonemapping);
|
||||
if (found == _tonemappingMap.end()) {
|
||||
auto tonemappingId = _tonemappings.newElement(tonemapping);
|
||||
// Avoid failing to allocate a tonemapping, just pass
|
||||
if (tonemappingId != INVALID_INDEX) {
|
||||
// Insert the tonemapping and its index in the reverse map
|
||||
_tonemappingMap.insert(TonemappingMap::value_type(tonemapping, tonemappingId));
|
||||
}
|
||||
return tonemappingId;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
}
|
||||
|
||||
TonemappingStage::TonemappingPointer TonemappingStage::removeTonemapping(Index index) {
|
||||
TonemappingPointer removed = _tonemappings.freeElement(index);
|
||||
if (removed) {
|
||||
_tonemappingMap.erase(removed);
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
TonemappingStageSetup::TonemappingStageSetup() {}
|
||||
|
||||
void TonemappingStageSetup::run(const render::RenderContextPointer& renderContext) {
|
||||
auto stage = renderContext->_scene->getStage(TonemappingStage::getName());
|
||||
if (!stage) {
|
||||
renderContext->_scene->resetStage(TonemappingStage::getName(), std::make_shared<TonemappingStage>());
|
||||
}
|
||||
}
|
84
libraries/render-utils/src/TonemappingStage.h
Normal file
84
libraries/render-utils/src/TonemappingStage.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// TonemappingStage.h
|
||||
//
|
||||
// Created by HifiExperiments on 6/24/24
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_render_utils_TonemappingStage_h
|
||||
#define hifi_render_utils_TonemappingStage_h
|
||||
|
||||
#include <graphics/Stage.h>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <render/IndexedContainer.h>
|
||||
#include <render/Stage.h>
|
||||
|
||||
#include <render/Forward.h>
|
||||
#include <render/DrawTask.h>
|
||||
#include <graphics/Tonemapping.h>
|
||||
|
||||
// Tonemapping stage to set up tonemapping-related rendering tasks
|
||||
class TonemappingStage : public render::Stage {
|
||||
public:
|
||||
static std::string _stageName;
|
||||
static const std::string& getName() { return _stageName; }
|
||||
|
||||
using Index = render::indexed_container::Index;
|
||||
static const Index INVALID_INDEX;
|
||||
static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; }
|
||||
|
||||
using TonemappingPointer = graphics::TonemappingPointer;
|
||||
using Tonemappings = render::indexed_container::IndexedPointerVector<graphics::Tonemapping>;
|
||||
using TonemappingMap = std::unordered_map<TonemappingPointer, Index>;
|
||||
|
||||
using TonemappingIndices = std::vector<Index>;
|
||||
|
||||
Index findTonemapping(const TonemappingPointer& tonemapping) const;
|
||||
Index addTonemapping(const TonemappingPointer& tonemapping);
|
||||
|
||||
TonemappingPointer removeTonemapping(Index index);
|
||||
|
||||
bool checkTonemappingId(Index index) const { return _tonemappings.checkIndex(index); }
|
||||
|
||||
Index getNumTonemappings() const { return _tonemappings.getNumElements(); }
|
||||
Index getNumFreeTonemappings() const { return _tonemappings.getNumFreeIndices(); }
|
||||
Index getNumAllocatedTonemappings() const { return _tonemappings.getNumAllocatedIndices(); }
|
||||
|
||||
TonemappingPointer getTonemapping(Index tonemappingId) const {
|
||||
return _tonemappings.get(tonemappingId);
|
||||
}
|
||||
|
||||
Tonemappings _tonemappings;
|
||||
TonemappingMap _tonemappingMap;
|
||||
|
||||
class Frame {
|
||||
public:
|
||||
Frame() {}
|
||||
|
||||
void clear() { _tonemappings.clear(); }
|
||||
|
||||
void pushTonemapping(TonemappingStage::Index index) { _tonemappings.emplace_back(index); }
|
||||
|
||||
TonemappingStage::TonemappingIndices _tonemappings;
|
||||
};
|
||||
using FramePointer = std::shared_ptr<Frame>;
|
||||
|
||||
Frame _currentFrame;
|
||||
};
|
||||
using TonemappingStagePointer = std::shared_ptr<TonemappingStage>;
|
||||
|
||||
class TonemappingStageSetup {
|
||||
public:
|
||||
using JobModel = render::Job::Model<TonemappingStageSetup>;
|
||||
|
||||
TonemappingStageSetup();
|
||||
void run(const render::RenderContextPointer& renderContext);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif
|
|
@ -15,6 +15,8 @@
|
|||
#include "BackgroundStage.h"
|
||||
#include "HazeStage.h"
|
||||
#include "BloomStage.h"
|
||||
#include "TonemappingStage.h"
|
||||
#include "AmbientOcclusionStage.h"
|
||||
#include <render/TransitionStage.h>
|
||||
#include <render/HighlightStage.h>
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
@ -24,6 +26,8 @@ void UpdateSceneTask::build(JobModel& task, const render::Varying& input, render
|
|||
task.addJob<BackgroundStageSetup>("BackgroundStageSetup");
|
||||
task.addJob<HazeStageSetup>("HazeStageSetup");
|
||||
task.addJob<BloomStageSetup>("BloomStageSetup");
|
||||
task.addJob<TonemappingStageSetup>("TonemappingStageSetup");
|
||||
task.addJob<AmbientOcclusionStageSetup>("AmbientOcclusionStageSetup");
|
||||
task.addJob<render::TransitionStageSetup>("TransitionStageSetup");
|
||||
task.addJob<render::HighlightStageSetup>("HighlightStageSetup");
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#include "BloomStage.h"
|
||||
#include "TonemappingStage.h"
|
||||
|
||||
namespace ru {
|
||||
using render_utils::slot::texture::Texture;
|
||||
|
@ -71,6 +72,14 @@ void SetupZones::run(const RenderContextPointer& context, const Input& input) {
|
|||
assert(bloomStage);
|
||||
bloomStage->_currentFrame.clear();
|
||||
|
||||
auto tonemappingStage = context->_scene->getStage<TonemappingStage>();
|
||||
assert(tonemappingStage);
|
||||
tonemappingStage->_currentFrame.clear();
|
||||
|
||||
auto ambientOcclusionStage = context->_scene->getStage<AmbientOcclusionStage>();
|
||||
assert(ambientOcclusionStage);
|
||||
ambientOcclusionStage->_currentFrame.clear();
|
||||
|
||||
// call render over the zones to grab their components in the correct order first...
|
||||
render::renderItems(context, input);
|
||||
|
||||
|
@ -80,6 +89,8 @@ void SetupZones::run(const RenderContextPointer& context, const Input& input) {
|
|||
backgroundStage->_currentFrame.pushBackground(0);
|
||||
hazeStage->_currentFrame.pushHaze(0);
|
||||
bloomStage->_currentFrame.pushBloom(INVALID_INDEX);
|
||||
tonemappingStage->_currentFrame.pushTonemapping(0);
|
||||
ambientOcclusionStage->_currentFrame.pushAmbientOcclusion(INVALID_INDEX);
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() {
|
||||
|
@ -105,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);
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
struct ToneMappingParams {
|
||||
vec4 _exp_2powExp_s0_s1;
|
||||
ivec4 _toneCurve_s0_s1_s2;
|
||||
float _2powExp;
|
||||
int _toneCurve;
|
||||
};
|
||||
|
||||
const float GAMMA_22 = 2.2;
|
||||
|
@ -31,17 +31,17 @@ LAYOUT(binding=RENDER_UTILS_BUFFER_TM_PARAMS) uniform toneMappingParamsBuffer {
|
|||
ToneMappingParams params;
|
||||
};
|
||||
float getTwoPowExposure() {
|
||||
return params._exp_2powExp_s0_s1.y;
|
||||
return params._2powExp;
|
||||
}
|
||||
int getToneCurve() {
|
||||
return params._toneCurve_s0_s1_s2.x;
|
||||
return params._toneCurve;
|
||||
}
|
||||
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_TM_COLOR) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
|
||||
void main(void) {
|
||||
<@if HIFI_USE_MIRRORED@>
|
||||
vec4 fragColorRaw = texture(colorMap, vec2(1.0 - varTexCoord0.x, varTexCoord0.y));
|
||||
|
|
24
libraries/shared/src/AmbientOcclusionTechnique.cpp
Normal file
24
libraries/shared/src/AmbientOcclusionTechnique.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Created by HifiExperiments on 6/23/24
|
||||
// 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
|
||||
//
|
||||
|
||||
#include "AmbientOcclusionTechnique.h"
|
||||
|
||||
const char* ambientOcclusionTechniqueNames[] = {
|
||||
"ssao",
|
||||
"hbao"
|
||||
};
|
||||
|
||||
static const size_t AO_TECHNIQUE_NAMES = (sizeof(ambientOcclusionTechniqueNames) / sizeof(ambientOcclusionTechniqueNames[0]));
|
||||
|
||||
QString AmbientOcclusionTechniqueHelpers::getNameForAmbientOcclusionTechnique(AmbientOcclusionTechnique technique) {
|
||||
if (((int)technique <= 0) || ((int)technique >= (int)AO_TECHNIQUE_NAMES)) {
|
||||
technique = (AmbientOcclusionTechnique)0;
|
||||
}
|
||||
|
||||
return ambientOcclusionTechniqueNames[(int)technique];
|
||||
}
|
38
libraries/shared/src/AmbientOcclusionTechnique.h
Normal file
38
libraries/shared/src/AmbientOcclusionTechnique.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// Created by HifiExperiments on 6/23/24
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_AmbientOcclusionTechnique_h
|
||||
#define hifi_AmbientOcclusionTechnique_h
|
||||
|
||||
#include "QString"
|
||||
|
||||
/*@jsdoc
|
||||
* <p>The technique used for calculating ambient occlusion. Different techniques have different tradeoffs.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>"ssao"</code></td><td>A basic screen-space AO effect.</td></tr>
|
||||
* <tr><td><code>"hbao"</code></td><td>A form of SSAO that uses the depth buffer for better AO detail, sometimes at the expense of performance.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {string} AmbientOcclusionTechnique
|
||||
*/
|
||||
|
||||
enum class AmbientOcclusionTechnique {
|
||||
SSAO = 0,
|
||||
HBAO,
|
||||
};
|
||||
|
||||
class AmbientOcclusionTechniqueHelpers {
|
||||
public:
|
||||
static QString getNameForAmbientOcclusionTechnique(AmbientOcclusionTechnique curve);
|
||||
};
|
||||
|
||||
#endif // hifi_AmbientOcclusionTechnique_h
|
26
libraries/shared/src/TonemappingCurve.cpp
Normal file
26
libraries/shared/src/TonemappingCurve.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Created by HifiExperiments on 6/23/24
|
||||
// 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
|
||||
//
|
||||
|
||||
#include "TonemappingCurve.h"
|
||||
|
||||
const char* tonemappingCurveNames[] = {
|
||||
"rgb",
|
||||
"srgb",
|
||||
"reinhard",
|
||||
"filmic"
|
||||
};
|
||||
|
||||
static const size_t TONEMAPPING_CURVE_NAMES = (sizeof(tonemappingCurveNames) / sizeof(tonemappingCurveNames[0]));
|
||||
|
||||
QString TonemappingCurveHelpers::getNameForTonemappingCurve(TonemappingCurve curve) {
|
||||
if (((int)curve <= 0) || ((int)curve >= (int)TONEMAPPING_CURVE_NAMES)) {
|
||||
curve = (TonemappingCurve)0;
|
||||
}
|
||||
|
||||
return tonemappingCurveNames[(int)curve];
|
||||
}
|
42
libraries/shared/src/TonemappingCurve.h
Normal file
42
libraries/shared/src/TonemappingCurve.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// Created by HifiExperiments on 6/23/24
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_TonemappingCurve_h
|
||||
#define hifi_TonemappingCurve_h
|
||||
|
||||
#include "QString"
|
||||
|
||||
/*@jsdoc
|
||||
* <p>The tonemapping curve applied to the final rendering.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>"rgb"</code></td><td>No tonemapping, colors are kept in RGB.</td></tr>
|
||||
* <tr><td><code>"srgb"</code></td><td>Colors are converted to sRGB.</td></tr>
|
||||
* <tr><td><code>"reinhard"</code></td><td>Reinhard tonemapping is applied.</td></tr>
|
||||
* <tr><td><code>"filmic"</code></td><td>Filmic tonemapping is applied.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {string} TonemappingCurve
|
||||
*/
|
||||
|
||||
enum class TonemappingCurve {
|
||||
RGB = 0,
|
||||
SRGB,
|
||||
REINHARD,
|
||||
FILMIC
|
||||
};
|
||||
|
||||
class TonemappingCurveHelpers {
|
||||
public:
|
||||
static QString getNameForTonemappingCurve(TonemappingCurve curve);
|
||||
};
|
||||
|
||||
#endif // hifi_TonemappingCurve_h
|
|
@ -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
|
||||
|
|
|
@ -14,15 +14,11 @@ import "../../lib/prop" as Prop
|
|||
|
||||
Column {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
Prop.PropScalar {
|
||||
label: "Exposure"
|
||||
anchors.right: parent.right
|
||||
Prop.PropBool {
|
||||
label: "Debug"
|
||||
object: Render.getConfig("RenderMainView.ToneMapping")
|
||||
property: "exposure"
|
||||
min: -4
|
||||
max: 4
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
property: "debug"
|
||||
}
|
||||
Prop.PropEnum {
|
||||
label: "Tone Curve"
|
||||
|
@ -35,6 +31,15 @@ Column {
|
|||
"Filmic",
|
||||
]
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
anchors.right: parent.right
|
||||
}
|
||||
Prop.PropScalar {
|
||||
label: "Exposure"
|
||||
object: Render.getConfig("RenderMainView.ToneMapping")
|
||||
property: "exposure"
|
||||
min: -4
|
||||
max: 4
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,6 +165,48 @@
|
|||
"bloom.bloomSize": {
|
||||
"tooltip": "The radius of bloom. The higher the value, the larger the bloom."
|
||||
},
|
||||
"tonemappingMode": {
|
||||
"tooltip": "Configures the tonemapping applied to the final render."
|
||||
},
|
||||
"tonemapping.curve": {
|
||||
"tooltip": "The tonemapping curve used."
|
||||
},
|
||||
"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."
|
||||
},
|
||||
|
|
|
@ -618,6 +618,124 @@ const GROUPS = [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "zone_tonemapping",
|
||||
label: "ZONE TONEMAPPING",
|
||||
properties: [
|
||||
{
|
||||
label: "Tonemapping",
|
||||
type: "dropdown",
|
||||
options: { inherit: "Inherit", disabled: "Off", enabled: "On" },
|
||||
propertyID: "tonemappingMode",
|
||||
},
|
||||
{
|
||||
label: "Curve",
|
||||
type: "dropdown",
|
||||
options: { rgb: "RGB", srgb: "sRGB", reinhard: "Reinhard", filmic: "Filmic" },
|
||||
propertyID: "tonemapping.curve",
|
||||
showPropertyRule: { "tonemappingMode": "enabled" },
|
||||
},
|
||||
{
|
||||
label: "Exposure",
|
||||
type: "number-draggable",
|
||||
min: -4.0,
|
||||
max: 4.0,
|
||||
step: 0.1,
|
||||
decimals: 1,
|
||||
propertyID: "tonemapping.exposure",
|
||||
showPropertyRule: { "tonemappingMode": "enabled" },
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "zone_ambient_occlusion",
|
||||
label: "ZONE AMBIENT OCCLUSION",
|
||||
properties: [
|
||||
{
|
||||
label: "Ambient Occlusion",
|
||||
type: "dropdown",
|
||||
options: { inherit: "Inherit", disabled: "Off", enabled: "On" },
|
||||
propertyID: "ambientOcclusionMode",
|
||||
},
|
||||
//{
|
||||
// label: "Technique",
|
||||
// type: "dropdown",
|
||||
// options: { ssao: "SSAO", hbao: "HBAO" },
|
||||
// propertyID: "ambientOcclusion.technique",
|
||||
// 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" },
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "zone_avatar_priority",
|
||||
label: "ZONE AVATAR PRIORITY",
|
||||
|
@ -1938,8 +2056,9 @@ const GROUPS_PER_TYPE = {
|
|||
None: [ 'base', 'spatial', 'behavior', 'scripts', 'collision', 'physics' ],
|
||||
Shape: [ 'base', 'shape', 'spatial', 'behavior', 'scripts', 'collision', 'physics' ],
|
||||
Text: [ 'base', 'text', 'spatial', 'behavior', 'scripts', 'collision', 'physics' ],
|
||||
Zone: [ 'base', 'zone', 'zone_key_light', 'zone_skybox', 'zone_ambient_light', 'zone_haze',
|
||||
'zone_bloom', 'zone_avatar_priority', 'zone_audio', 'spatial', 'behavior', 'scripts', 'physics' ],
|
||||
Zone: [ 'base', 'zone', 'zone_key_light', 'zone_skybox', 'zone_ambient_light', 'zone_haze',
|
||||
'zone_bloom', 'zone_tonemapping', 'zone_ambient_occlusion', 'zone_avatar_priority',
|
||||
'zone_audio', 'spatial', 'behavior', 'scripts', 'physics' ],
|
||||
Model: [ 'base', 'model', 'spatial', 'behavior', 'scripts', 'collision', 'physics' ],
|
||||
Image: [ 'base', 'image', 'spatial', 'behavior', 'scripts', 'collision', 'physics' ],
|
||||
Web: [ 'base', 'web', 'spatial', 'behavior', 'scripts', 'collision', 'physics' ],
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 785 B |
Binary file not shown.
After Width: | Height: | Size: 673 B |
Loading…
Reference in a new issue