From 692c776be50fd151c91831a9f7096b1b63a3f99a Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 2 Jul 2019 15:18:28 -0700 Subject: [PATCH 1/4] expose shadow bias and max distance wip --- .../src/RenderableZoneEntityItem.cpp | 2 + .../entities/src/EntityItemProperties.cpp | 2 + libraries/entities/src/EntityPropertyFlags.h | 60 ++++++++++--------- .../entities/src/KeyLightPropertyGroup.cpp | 44 ++++++++++++-- .../entities/src/KeyLightPropertyGroup.h | 8 +++ libraries/networking/src/udt/PacketHeaders.h | 1 + .../system/assets/data/createAppTooltips.json | 8 ++- .../system/html/js/entityProperties.js | 20 +++++++ .../create/assets/data/createAppTooltips.json | 8 ++- .../html/js/entityProperties.js | 20 +++++++ 10 files changed, 139 insertions(+), 34 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index e4300cca76..266acf6188 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -317,6 +317,8 @@ void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity sunLight->setIntensity(_keyLightProperties.getIntensity()); sunLight->setDirection(_lastRotation * _keyLightProperties.getDirection()); sunLight->setCastShadows(_keyLightProperties.getCastShadows()); + sunLight->setShadowsBiasScale(_keyLightProperties.getShadowBias()); + sunLight->setShadowsMaxDistance(_keyLightProperties.getShadowMaxDistance()); } void ZoneEntityRenderer::updateAmbientLightFromEntity(const TypedEntityPointer& entity) { diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 064fe2e3b1..6e0b843b8f 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -2746,6 +2746,8 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLight, keyLight, Intensity, intensity); ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLight, keylight, Direction, direction); ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_CAST_SHADOW, KeyLight, keyLight, CastShadows, castShadows); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_KEYLIGHT_SHADOW_BIAS, KeyLight, keyLight, ShadowBias, shadowBias, 0.0f, 1.0f); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, KeyLight, keyLight, ShadowMaxDistance, shadowMaxDistance, 0.0f, 500.0f); } { // Ambient light ADD_GROUP_PROPERTY_TO_MAP(PROP_AMBIENT_LIGHT_INTENSITY, AmbientLight, ambientLight, Intensity, intensity); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index e86cccb997..b751dbfaec 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -159,6 +159,8 @@ enum EntityPropertyList { PROP_DERIVED_29, PROP_DERIVED_30, PROP_DERIVED_31, + PROP_DERIVED_32, + PROP_DERIVED_33, PROP_AFTER_LAST_ITEM, @@ -248,39 +250,41 @@ enum EntityPropertyList { 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, // Ambient light - PROP_AMBIENT_LIGHT_INTENSITY = PROP_DERIVED_4, - PROP_AMBIENT_LIGHT_URL = PROP_DERIVED_5, + PROP_AMBIENT_LIGHT_INTENSITY = PROP_DERIVED_6, + PROP_AMBIENT_LIGHT_URL = PROP_DERIVED_7, // Skybox - PROP_SKYBOX_COLOR = PROP_DERIVED_6, - PROP_SKYBOX_URL = PROP_DERIVED_7, + PROP_SKYBOX_COLOR = PROP_DERIVED_8, + PROP_SKYBOX_URL = PROP_DERIVED_9, // Haze - PROP_HAZE_RANGE = PROP_DERIVED_8, - PROP_HAZE_COLOR = PROP_DERIVED_9, - PROP_HAZE_GLARE_COLOR = PROP_DERIVED_10, - PROP_HAZE_ENABLE_GLARE = PROP_DERIVED_11, - PROP_HAZE_GLARE_ANGLE = PROP_DERIVED_12, - PROP_HAZE_ALTITUDE_EFFECT = PROP_DERIVED_13, - PROP_HAZE_CEILING = PROP_DERIVED_14, - PROP_HAZE_BASE_REF = PROP_DERIVED_15, - PROP_HAZE_BACKGROUND_BLEND = PROP_DERIVED_16, - PROP_HAZE_ATTENUATE_KEYLIGHT = PROP_DERIVED_17, - PROP_HAZE_KEYLIGHT_RANGE = PROP_DERIVED_18, - PROP_HAZE_KEYLIGHT_ALTITUDE = PROP_DERIVED_19, + PROP_HAZE_RANGE = PROP_DERIVED_10, + PROP_HAZE_COLOR = PROP_DERIVED_11, + PROP_HAZE_GLARE_COLOR = PROP_DERIVED_12, + PROP_HAZE_ENABLE_GLARE = PROP_DERIVED_13, + PROP_HAZE_GLARE_ANGLE = PROP_DERIVED_14, + PROP_HAZE_ALTITUDE_EFFECT = PROP_DERIVED_15, + PROP_HAZE_CEILING = PROP_DERIVED_16, + PROP_HAZE_BASE_REF = PROP_DERIVED_17, + PROP_HAZE_BACKGROUND_BLEND = PROP_DERIVED_18, + PROP_HAZE_ATTENUATE_KEYLIGHT = PROP_DERIVED_19, + PROP_HAZE_KEYLIGHT_RANGE = PROP_DERIVED_20, + PROP_HAZE_KEYLIGHT_ALTITUDE = PROP_DERIVED_21, // Bloom - PROP_BLOOM_INTENSITY = PROP_DERIVED_20, - PROP_BLOOM_THRESHOLD = PROP_DERIVED_21, - PROP_BLOOM_SIZE = PROP_DERIVED_22, - PROP_FLYING_ALLOWED = PROP_DERIVED_23, - PROP_GHOSTING_ALLOWED = PROP_DERIVED_24, - PROP_FILTER_URL = PROP_DERIVED_25, - PROP_KEY_LIGHT_MODE = PROP_DERIVED_26, - PROP_AMBIENT_LIGHT_MODE = PROP_DERIVED_27, - PROP_SKYBOX_MODE = PROP_DERIVED_28, - PROP_HAZE_MODE = PROP_DERIVED_29, - PROP_BLOOM_MODE = PROP_DERIVED_30, + PROP_BLOOM_INTENSITY = PROP_DERIVED_22, + PROP_BLOOM_THRESHOLD = PROP_DERIVED_23, + PROP_BLOOM_SIZE = PROP_DERIVED_24, + PROP_FLYING_ALLOWED = PROP_DERIVED_25, + PROP_GHOSTING_ALLOWED = PROP_DERIVED_26, + PROP_FILTER_URL = PROP_DERIVED_27, + PROP_KEY_LIGHT_MODE = PROP_DERIVED_28, + PROP_AMBIENT_LIGHT_MODE = PROP_DERIVED_29, + PROP_SKYBOX_MODE = PROP_DERIVED_30, + PROP_HAZE_MODE = PROP_DERIVED_31, + PROP_BLOOM_MODE = PROP_DERIVED_32, // Avatar priority - PROP_AVATAR_PRIORITY = PROP_DERIVED_31, + PROP_AVATAR_PRIORITY = PROP_DERIVED_33, // Polyvox PROP_VOXEL_VOLUME_SIZE = PROP_DERIVED_0, diff --git a/libraries/entities/src/KeyLightPropertyGroup.cpp b/libraries/entities/src/KeyLightPropertyGroup.cpp index f0ad2965ce..b70e94504d 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.cpp +++ b/libraries/entities/src/KeyLightPropertyGroup.cpp @@ -22,6 +22,8 @@ const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY = 1.0f; const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY = 0.5f; const glm::vec3 KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION = { 0.0f, -1.0f, 0.0f }; const bool KeyLightPropertyGroup::DEFAULT_KEYLIGHT_CAST_SHADOWS { false }; +const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_SHADOW_BIAS { 0.5f }; +const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_SHADOW_MAX_DISTANCE { 40.0f }; void KeyLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { @@ -30,6 +32,8 @@ void KeyLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desired COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_INTENSITY, KeyLight, keyLight, Intensity, intensity); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_DIRECTION, KeyLight, keyLight, Direction, direction); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_CAST_SHADOW, KeyLight, keyLight, CastShadows, castShadows); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_SHADOW_BIAS, KeyLight, keyLight, ShadowBias, shadowBias); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, KeyLight, keyLight, ShadowMaxDistance, shadowMaxDistance); } void KeyLightPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { @@ -37,6 +41,8 @@ void KeyLightPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, intensity, float, setIntensity); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, direction, vec3, setDirection); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, castShadows, bool, setCastShadows); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, shadowBias, float, setShadowBias); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, shadowMaxDistance, float, setShadowMaxDistance); // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightColor, u8vec3Color, setColor, getColor); @@ -50,14 +56,18 @@ void KeyLightPropertyGroup::merge(const KeyLightPropertyGroup& other) { COPY_PROPERTY_IF_CHANGED(intensity); COPY_PROPERTY_IF_CHANGED(direction); COPY_PROPERTY_IF_CHANGED(castShadows); + COPY_PROPERTY_IF_CHANGED(shadowBias); + COPY_PROPERTY_IF_CHANGED(shadowMaxDistance); } void KeyLightPropertyGroup::debugDump() const { qCDebug(entities) << " KeyLightPropertyGroup: ---------------------------------------------"; - qCDebug(entities) << " color:" << getColor(); // << "," << getColor()[1] << "," << getColor()[2]; - qCDebug(entities) << " intensity:" << getIntensity(); - qCDebug(entities) << " direction:" << getDirection(); - qCDebug(entities) << " castShadows:" << getCastShadows(); + qCDebug(entities) << " color:" << getColor(); + qCDebug(entities) << " intensity:" << getIntensity(); + qCDebug(entities) << " direction:" << getDirection(); + qCDebug(entities) << " castShadows:" << getCastShadows(); + qCDebug(entities) << " shadowBias:" << getShadowBias(); + qCDebug(entities) << " shadowMaxDistance:" << getShadowMaxDistance(); } void KeyLightPropertyGroup::listChangedProperties(QList& out) { @@ -73,6 +83,12 @@ void KeyLightPropertyGroup::listChangedProperties(QList& out) { if (castShadowsChanged()) { out << "keyLight-castShadows"; } + if (shadowBiasChanged()) { + out << "keyLight-shadowBias"; + } + if (shadowMaxDistanceChanged()) { + out << "keyLight-shadowMaxDistance"; + } } bool KeyLightPropertyGroup::appendToEditPacket(OctreePacketData* packetData, @@ -88,6 +104,8 @@ bool KeyLightPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, getIntensity()); APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, getDirection()); APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, getCastShadows()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_SHADOW_BIAS, getShadowBias()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, getShadowMaxDistance()); return true; } @@ -103,11 +121,15 @@ bool KeyLightPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFl READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, bool, setCastShadows); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_SHADOW_BIAS, float, setShadowBias); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, float, setShadowMaxDistance); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_COLOR, Color); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_INTENSITY, Intensity); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_DIRECTION, Direction); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_CAST_SHADOW, CastShadows); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_SHADOW_BIAS, ShadowBias); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, ShadowMaxDistance); processedBytes += bytesRead; @@ -121,6 +143,8 @@ void KeyLightPropertyGroup::markAllChanged() { _intensityChanged = true; _directionChanged = true; _castShadowsChanged = true; + _shadowBiasChanged = true; + _shadowMaxDistanceChanged = true; } EntityPropertyFlags KeyLightPropertyGroup::getChangedProperties() const { @@ -130,6 +154,8 @@ EntityPropertyFlags KeyLightPropertyGroup::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_INTENSITY, intensity); CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_DIRECTION, direction); CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_CAST_SHADOW, castShadows); + CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_SHADOW_BIAS, shadowBias); + CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, shadowMaxDistance); return changedProperties; } @@ -139,6 +165,8 @@ void KeyLightPropertyGroup::getProperties(EntityItemProperties& properties) cons COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Intensity, getIntensity); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Direction, getDirection); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, CastShadows, getCastShadows); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, ShadowBias, getShadowBias); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, ShadowMaxDistance, getShadowMaxDistance); } bool KeyLightPropertyGroup::setProperties(const EntityItemProperties& properties) { @@ -148,6 +176,8 @@ bool KeyLightPropertyGroup::setProperties(const EntityItemProperties& properties SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Intensity, intensity, setIntensity); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Direction, direction, setDirection); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, CastShadows, castShadows, setCastShadows); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, ShadowBias, shadowBias, setShadowBias); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, ShadowMaxDistance, shadowMaxDistance, setShadowMaxDistance); return somethingChanged; } @@ -159,6 +189,8 @@ EntityPropertyFlags KeyLightPropertyGroup::getEntityProperties(EncodeBitstreamPa requestedProperties += PROP_KEYLIGHT_INTENSITY; requestedProperties += PROP_KEYLIGHT_DIRECTION; requestedProperties += PROP_KEYLIGHT_CAST_SHADOW; + requestedProperties += PROP_KEYLIGHT_SHADOW_BIAS; + requestedProperties += PROP_KEYLIGHT_SHADOW_MAX_DISTANCE; return requestedProperties; } @@ -177,6 +209,8 @@ void KeyLightPropertyGroup::appendSubclassData(OctreePacketData* packetData, Enc APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, getIntensity()); APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, getDirection()); APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, getCastShadows()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_SHADOW_BIAS, getShadowBias()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, getShadowMaxDistance()); } int KeyLightPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, @@ -191,6 +225,8 @@ int KeyLightPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, bool, setCastShadows); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_SHADOW_BIAS, float, setShadowBias); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, float, setShadowMaxDistance); return bytesRead; } diff --git a/libraries/entities/src/KeyLightPropertyGroup.h b/libraries/entities/src/KeyLightPropertyGroup.h index d46f5ce9b5..15e83ba5b1 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.h +++ b/libraries/entities/src/KeyLightPropertyGroup.h @@ -37,6 +37,10 @@ class ReadBitstreamToTreeParams; * are cast by avatars, plus {@link Entities.EntityProperties-Model|Model} and * {@link Entities.EntityProperties-Shape|Shape} entities that have their * {@link Entities.EntityProperties|canCastShadow} property set to true. + * @property {number} shadowBias=0.5 - The bias of the shadows cast by the light. Use this to fine-tune your shadows to your scene + * to prevent shadow acne and peter panning. In the range 0.01.0. + * @property {number} shadowMaxDistance=40.0 - The max distance from your view at which shadows will be computed. Higher values will + * cover more of your scene, but with less precision. In the range 0.0500.0. */ class KeyLightPropertyGroup : public PropertyGroup { public: @@ -90,11 +94,15 @@ public: static const float DEFAULT_KEYLIGHT_AMBIENT_INTENSITY; static const glm::vec3 DEFAULT_KEYLIGHT_DIRECTION; static const bool DEFAULT_KEYLIGHT_CAST_SHADOWS; + static const float DEFAULT_KEYLIGHT_SHADOW_BIAS; + static const float DEFAULT_KEYLIGHT_SHADOW_MAX_DISTANCE; DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, Color, color, glm::u8vec3, DEFAULT_KEYLIGHT_COLOR); DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, Intensity, intensity, float, DEFAULT_KEYLIGHT_INTENSITY); DEFINE_PROPERTY_REF(PROP_KEYLIGHT_DIRECTION, Direction, direction, glm::vec3, DEFAULT_KEYLIGHT_DIRECTION); DEFINE_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, CastShadows, castShadows, bool, DEFAULT_KEYLIGHT_CAST_SHADOWS); + DEFINE_PROPERTY(PROP_KEYLIGHT_SHADOW_BIAS, ShadowBias, shadowBias, float, DEFAULT_KEYLIGHT_SHADOW_BIAS); + DEFINE_PROPERTY(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, ShadowMaxDistance, shadowMaxDistance, float, DEFAULT_KEYLIGHT_SHADOW_MAX_DISTANCE); }; #endif // hifi_KeyLightPropertyGroup_h diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 6230b8b11e..9e4f7cf808 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -271,6 +271,7 @@ enum class EntityVersion : PacketVersion { ParticleShapeType, ParticleShapeTypeDeadlockFix, PrivateUserData, + ShadowBiasAndDistance, // Add new versions above here NUM_PACKET_TYPE, diff --git a/scripts/simplifiedUI/system/assets/data/createAppTooltips.json b/scripts/simplifiedUI/system/assets/data/createAppTooltips.json index b59797fca7..f22552b462 100644 --- a/scripts/simplifiedUI/system/assets/data/createAppTooltips.json +++ b/scripts/simplifiedUI/system/assets/data/createAppTooltips.json @@ -74,6 +74,12 @@ "keyLight.castShadows": { "tooltip": "If enabled, shadows are cast. The entity or avatar casting the shadow must also have Cast Shadows enabled." }, + "keyLight.shadowBias": { + "tooltip": "The bias of the shadows cast by the light. Use this to fine-tune your shadows to your scene to prevent shadow acne and peter panning." + }, + "keyLight.shadowMaxDistance": { + "tooltip": "The max distance from your view at which shadows will be computed." + }, "skyboxMode": { "tooltip": "Configures the skybox in the zone. The skybox is a cube map image." }, @@ -135,7 +141,7 @@ "tooltip": "The radius of bloom. The higher the value, the larger the bloom." }, "avatarPriority": { - "tooltip": "Alter Avatars' update priorities." + "tooltip": "Alter Avatars' update priorities." }, "modelURL": { "tooltip": "A mesh model from an FBX or OBJ file." diff --git a/scripts/simplifiedUI/system/html/js/entityProperties.js b/scripts/simplifiedUI/system/html/js/entityProperties.js index e64543d41f..c04d42c606 100644 --- a/scripts/simplifiedUI/system/html/js/entityProperties.js +++ b/scripts/simplifiedUI/system/html/js/entityProperties.js @@ -300,6 +300,26 @@ const GROUPS = [ propertyID: "keyLight.castShadows", showPropertyRule: { "keyLightMode": "enabled" }, }, + { + label: "Shadow Bias", + type: "number-draggable", + min: 0, + max: 1, + step: 0.01, + decimals: 2, + propertyID: "keyLight.shadowBias", + showPropertyRule: { "keyLightMode": "enabled" }, + }, + { + label: "Shadow Max Distance", + type: "number-draggable", + min: 0, + max: 500, + step: 0.1, + decimals: 2, + propertyID: "keyLight.shadowMaxDistance", + showPropertyRule: { "keyLightMode": "enabled" }, + }, { label: "Skybox", type: "dropdown", diff --git a/scripts/system/create/assets/data/createAppTooltips.json b/scripts/system/create/assets/data/createAppTooltips.json index b59797fca7..f22552b462 100644 --- a/scripts/system/create/assets/data/createAppTooltips.json +++ b/scripts/system/create/assets/data/createAppTooltips.json @@ -74,6 +74,12 @@ "keyLight.castShadows": { "tooltip": "If enabled, shadows are cast. The entity or avatar casting the shadow must also have Cast Shadows enabled." }, + "keyLight.shadowBias": { + "tooltip": "The bias of the shadows cast by the light. Use this to fine-tune your shadows to your scene to prevent shadow acne and peter panning." + }, + "keyLight.shadowMaxDistance": { + "tooltip": "The max distance from your view at which shadows will be computed." + }, "skyboxMode": { "tooltip": "Configures the skybox in the zone. The skybox is a cube map image." }, @@ -135,7 +141,7 @@ "tooltip": "The radius of bloom. The higher the value, the larger the bloom." }, "avatarPriority": { - "tooltip": "Alter Avatars' update priorities." + "tooltip": "Alter Avatars' update priorities." }, "modelURL": { "tooltip": "A mesh model from an FBX or OBJ file." diff --git a/scripts/system/create/entityProperties/html/js/entityProperties.js b/scripts/system/create/entityProperties/html/js/entityProperties.js index e64543d41f..c04d42c606 100644 --- a/scripts/system/create/entityProperties/html/js/entityProperties.js +++ b/scripts/system/create/entityProperties/html/js/entityProperties.js @@ -300,6 +300,26 @@ const GROUPS = [ propertyID: "keyLight.castShadows", showPropertyRule: { "keyLightMode": "enabled" }, }, + { + label: "Shadow Bias", + type: "number-draggable", + min: 0, + max: 1, + step: 0.01, + decimals: 2, + propertyID: "keyLight.shadowBias", + showPropertyRule: { "keyLightMode": "enabled" }, + }, + { + label: "Shadow Max Distance", + type: "number-draggable", + min: 0, + max: 500, + step: 0.1, + decimals: 2, + propertyID: "keyLight.shadowMaxDistance", + showPropertyRule: { "keyLightMode": "enabled" }, + }, { label: "Skybox", type: "dropdown", From 72f52b069e6e6b70dd84fb7b3366cc01c87c2cf8 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 3 Jul 2019 16:21:47 -0700 Subject: [PATCH 2/4] cleanup, fix shadow qml --- .../src/RenderableZoneEntityItem.cpp | 2 +- .../entities/src/EntityItemProperties.cpp | 2 +- .../entities/src/KeyLightPropertyGroup.h | 2 +- libraries/graphics/src/graphics/Light.cpp | 16 +-- libraries/graphics/src/graphics/Light.h | 12 +- .../render-utils/src/RenderShadowTask.cpp | 123 +++++++----------- libraries/render-utils/src/RenderShadowTask.h | 78 +++++------ scripts/developer/utilities/render/shadow.qml | 16 +-- .../system/html/js/entityProperties.js | 2 +- .../html/js/entityProperties.js | 2 +- 10 files changed, 101 insertions(+), 154 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 266acf6188..bbb8c67ad1 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -317,7 +317,7 @@ void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity sunLight->setIntensity(_keyLightProperties.getIntensity()); sunLight->setDirection(_lastRotation * _keyLightProperties.getDirection()); sunLight->setCastShadows(_keyLightProperties.getCastShadows()); - sunLight->setShadowsBiasScale(_keyLightProperties.getShadowBias()); + sunLight->setShadowBias(_keyLightProperties.getShadowBias()); sunLight->setShadowsMaxDistance(_keyLightProperties.getShadowMaxDistance()); } diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 019556b7f0..980cd31652 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -2754,7 +2754,7 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLight, keylight, Direction, direction); ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_CAST_SHADOW, KeyLight, keyLight, CastShadows, castShadows); ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_KEYLIGHT_SHADOW_BIAS, KeyLight, keyLight, ShadowBias, shadowBias, 0.0f, 1.0f); - ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, KeyLight, keyLight, ShadowMaxDistance, shadowMaxDistance, 0.0f, 500.0f); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, KeyLight, keyLight, ShadowMaxDistance, shadowMaxDistance, 1.0f, 250.0f); } { // Ambient light ADD_GROUP_PROPERTY_TO_MAP(PROP_AMBIENT_LIGHT_INTENSITY, AmbientLight, ambientLight, Intensity, intensity); diff --git a/libraries/entities/src/KeyLightPropertyGroup.h b/libraries/entities/src/KeyLightPropertyGroup.h index 15e83ba5b1..facbf88f3c 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.h +++ b/libraries/entities/src/KeyLightPropertyGroup.h @@ -40,7 +40,7 @@ class ReadBitstreamToTreeParams; * @property {number} shadowBias=0.5 - The bias of the shadows cast by the light. Use this to fine-tune your shadows to your scene * to prevent shadow acne and peter panning. In the range 0.01.0. * @property {number} shadowMaxDistance=40.0 - The max distance from your view at which shadows will be computed. Higher values will - * cover more of your scene, but with less precision. In the range 0.0500.0. + * cover more of your scene, but with less precision. In the range 1.0250.0. */ class KeyLightPropertyGroup : public PropertyGroup { public: diff --git a/libraries/graphics/src/graphics/Light.cpp b/libraries/graphics/src/graphics/Light.cpp index a5d03beda1..fb14783b4e 100755 --- a/libraries/graphics/src/graphics/Light.cpp +++ b/libraries/graphics/src/graphics/Light.cpp @@ -81,20 +81,12 @@ float Light::getShadowsMaxDistance() const { return _shadowsMaxDistance; } -void Light::setShadowsBiasScale(const float scale) { - _shadowsBiasScale = std::max(0.0f, scale); +void Light::setShadowBias(float bias) { + _shadowBias = bias; } -float Light::getShadowsBiasScale() const { - return _shadowsBiasScale; -} - -void Light::setBiasInput(float bias) { - _biasInput = bias; -} - -float Light::getBiasInput() const { - return _biasInput; +float Light::getShadowBias() const { + return _shadowBias; } void Light::setColor(const Color& color) { diff --git a/libraries/graphics/src/graphics/Light.h b/libraries/graphics/src/graphics/Light.h index 9b431b3e26..37670176cc 100755 --- a/libraries/graphics/src/graphics/Light.h +++ b/libraries/graphics/src/graphics/Light.h @@ -109,11 +109,8 @@ public: void setShadowsMaxDistance(const float maxDistance); float getShadowsMaxDistance() const; - void setShadowsBiasScale(const float scale); - float getShadowsBiasScale() const; - - void setBiasInput(float bias); - float getBiasInput() const; + void setShadowBias(float bias); + float getShadowBias() const; void setOrientation(const Quat& orientation); const glm::quat& getOrientation() const { return _transform.getRotation(); } @@ -201,9 +198,8 @@ protected: Type _type { SUN }; float _spotCos { -1.0f }; // stored here to be able to reset the spot angle when turning the type spot on/off - float _shadowsMaxDistance{ 40.0f }; - float _shadowsBiasScale{ 1.0f }; - float _biasInput{ 0.5f }; // 0.23f will roughly give the default constant and slope values + float _shadowsMaxDistance { 40.0f }; + float _shadowBias { 0.5f }; // 0.23f will roughly give the default constant and slope values bool _castShadows{ false }; void updateLightRadius(); diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index f54b2e563e..802dc633bf 100755 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -33,7 +33,6 @@ // but are readjusted afterwards #define SHADOW_FRUSTUM_NEAR 1.0f #define SHADOW_FRUSTUM_FAR 500.0f -static const unsigned int SHADOW_CASCADE_COUNT{ 4 }; using namespace render; @@ -316,76 +315,42 @@ RenderShadowSetup::RenderShadowSetup() : _shadowFrameCache = std::make_shared(); } -void RenderShadowSetup::configure(const Config& configuration) { - distanceTriggeredByConfig = _globalMaxDistance != configuration.globalMaxDistance; - biasTriggeredByConfig = _biasInput != configuration.biasInput; - - // go back to using the config's default bias values if a change to any of those is triggered - if (constant0 != configuration.constantBias0 || slope0 != configuration.slopeBias0 || - constant1 != configuration.constantBias1 || slope1 != configuration.slopeBias1 || - constant2 != configuration.constantBias2 || slope2 != configuration.slopeBias2 || - constant3 != configuration.constantBias3 || slope3 != configuration.slopeBias3) { - constant0 = configuration.constantBias0; - slope0 = configuration.slopeBias0; - constant1 = configuration.constantBias1; - slope1 = configuration.slopeBias1; - constant2 = configuration.constantBias2; - slope2 = configuration.slopeBias2; - constant3 = configuration.constantBias3; - slope3 = configuration.slopeBias3; - changeInDefaultConfigValues = true; - distanceTriggeredByConfig = false; - biasTriggeredByConfig = false; - - setConstantBias(0, constant0); - setSlopeBias(0, slope0); - - #if SHADOW_CASCADE_MAX_COUNT > 1 - setConstantBias(1, constant1); - setConstantBias(2, constant2); - setConstantBias(3, constant3); - - setSlopeBias(1, slope1); - setSlopeBias(2, slope2); - setSlopeBias(3, slope3); - #endif - } - - // modify bias using single input and work in calculateBias() - if (distanceTriggeredByConfig) { - changeInDefaultConfigValues = false; - _globalMaxDistance = configuration.globalMaxDistance; - calculateBiases(); - } - if (biasTriggeredByConfig) { - changeInDefaultConfigValues = false; - _biasInput = configuration.biasInput; - calculateBiases(); - } +void RenderShadowSetup::configure(const Config& config) { + constantBias0 = config.constantBias0; + constantBias1 = config.constantBias1; + constantBias2 = config.constantBias2; + constantBias3 = config.constantBias3; + slopeBias0 = config.slopeBias0; + slopeBias1 = config.slopeBias1; + slopeBias2 = config.slopeBias2; + slopeBias3 = config.slopeBias3; + biasInput = config.biasInput; + maxDistance = config.maxDistance; } -void RenderShadowSetup::calculateBiases() { +void RenderShadowSetup::calculateBiases(float biasInput) { // slope scaling values derived from ratio between original constantBias and slopeBias pairs - const std::array SLOPE_SCALES = {{ 2.7f, 3.0f, 3.7f, 3.5f }}; + const std::array SLOPE_SCALES = {{ 2.7f, 3.0f, 3.7f, 3.5f }}; const float CONVERT_BIAS = 100.0f; const float MIN_SCALE_DIVISOR = 0.5f; // the bias is relative to resolution // to remain consistent with the constant and slope bias values, the biasInput // value is in the 0.0 - 1.0 range but needs to be scaled up for further calculations + // TODO: expose variable resolution + int resolution = LightStage::Shadow::MAP_SIZE; + const int DEFAULT_RESOLUTION = LightStage::Shadow::MAP_SIZE; float inverseResolution = 1.0f / (float)resolution; int resolutionScale = DEFAULT_RESOLUTION * inverseResolution; - float convertedBias = _biasInput * (CONVERT_BIAS / resolutionScale); - std::array localConstants; - std::array localSlopes; + float convertedBias = biasInput * (CONVERT_BIAS / resolutionScale); float scaleFactor = 1.0f; for (int i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { - scaleFactor = convertedBias * (cacasdeDistances[0] / glm::max(MIN_SCALE_DIVISOR, cacasdeDistances[i + 4])) * inverseResolution; - localConstants[i] = cacasdeDistances[i] * scaleFactor; - localSlopes[i] = cacasdeDistances[i] * scaleFactor * SLOPE_SCALES[i]; - setConstantBias(i, localConstants[i]); - setSlopeBias(i, localSlopes[i]); + scaleFactor = convertedBias * (cacasdeDistances[0] / glm::max(MIN_SCALE_DIVISOR, cacasdeDistances[i + SHADOW_CASCADE_MAX_COUNT])) * inverseResolution; + float constantBias = cacasdeDistances[i] * scaleFactor; + float slopeBias = cacasdeDistances[i] * scaleFactor * SLOPE_SCALES[i]; + setConstantBias(i, constantBias); + setSlopeBias(i, slopeBias); } } @@ -425,43 +390,47 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c output.edit2() = _cameraFrustum; if (!_globalShadowObject) { - _globalShadowObject = std::make_shared(currentKeyLight, SHADOW_CASCADE_COUNT); + _globalShadowObject = std::make_shared(currentKeyLight, SHADOW_CASCADE_MAX_COUNT); } - resolution = _globalShadowObject->MAP_SIZE; _globalShadowObject->setLight(currentKeyLight); _globalShadowObject->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); - // if the max distance isn't altered externally, grab the value from the light - if (!distanceTriggeredByConfig && !biasTriggeredByConfig) { - _globalMaxDistance = currentKeyLight->getShadowsMaxDistance(); - } - _globalShadowObject->setMaxDistance(_globalMaxDistance); - - auto& firstCascade = _globalShadowObject->getCascade(0); - auto& firstCascadeFrustum = firstCascade.getFrustum(); - unsigned int cascadeIndex; - for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { + // Update our biases and maxDistance from the light or config + _globalShadowObject->setMaxDistance(maxDistance > 0.0f ? maxDistance : currentKeyLight->getShadowsMaxDistance()); + + for (unsigned int cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { cacasdeDistances[cascadeIndex] = _globalShadowObject->getCascade(cascadeIndex).getMaxDistance(); - cacasdeDistances[cascadeIndex + 4] = _globalShadowObject->getCascade(cascadeIndex).getMinDistance(); + cacasdeDistances[cascadeIndex + SHADOW_CASCADE_MAX_COUNT] = _globalShadowObject->getCascade(cascadeIndex).getMinDistance(); } - if (!biasTriggeredByConfig && !distanceTriggeredByConfig && !changeInDefaultConfigValues) { - setBiasInput(currentKeyLight->getBiasInput()); - calculateBiases(); + calculateBiases(biasInput > 0.0f ? biasInput : currentKeyLight->getShadowBias()); + + std::array constantBiases = { constantBias0, constantBias1, constantBias2, constantBias3 }; + std::array slopeBiases = { slopeBias0, slopeBias1, slopeBias2, slopeBias3 }; + for (unsigned int cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { + float constantBias = constantBiases[cascadeIndex]; + if (constantBias > 0.0f) { + setConstantBias(cascadeIndex, constantBias); + } + float slopeBias = slopeBiases[cascadeIndex]; + if (slopeBias > 0.0f) { + setSlopeBias(cascadeIndex, slopeBias); + } } // Adjust each cascade frustum - const auto biasScale = currentKeyLight->getShadowsBiasScale(); - for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { + for (unsigned int cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { auto& bias = _bias[cascadeIndex]; _globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR, - bias._constant, bias._slope * biasScale); + bias._constant, bias._slope); } _shadowFrameCache->pushShadow(_globalShadowObject); // Now adjust coarse frustum bounds + auto& firstCascade = _globalShadowObject->getCascade(0); + auto& firstCascadeFrustum = firstCascade.getFrustum(); auto frustumPosition = firstCascadeFrustum->getPosition(); auto farTopLeft = firstCascadeFrustum->getFarTopLeft() - frustumPosition; auto farBottomRight = firstCascadeFrustum->getFarBottomRight() - frustumPosition; @@ -473,7 +442,7 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c auto near = firstCascadeFrustum->getNearClip(); auto far = firstCascadeFrustum->getFarClip(); - for (cascadeIndex = 1; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { + for (unsigned int cascadeIndex = 1; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { auto& cascadeFrustum = _globalShadowObject->getCascade(cascadeIndex).getFrustum(); farTopLeft = cascadeFrustum->getFarTopLeft() - frustumPosition; diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index ceca28cec8..23047ee179 100755 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -75,34 +75,31 @@ public: CullFunctor _cullFunctor; }; -const float DEFAULT_BIAS_INPUT = 0.5f; -const float DEFAULT_MAX_DISTANCE = 40.0f; - class RenderShadowSetupConfig : public render::Job::Config { Q_OBJECT - Q_PROPERTY(float constantBias0 MEMBER constantBias0 NOTIFY dirty) - Q_PROPERTY(float constantBias1 MEMBER constantBias1 NOTIFY dirty) - Q_PROPERTY(float constantBias2 MEMBER constantBias2 NOTIFY dirty) - Q_PROPERTY(float constantBias3 MEMBER constantBias3 NOTIFY dirty) - Q_PROPERTY(float slopeBias0 MEMBER slopeBias0 NOTIFY dirty) - Q_PROPERTY(float slopeBias1 MEMBER slopeBias1 NOTIFY dirty) - Q_PROPERTY(float slopeBias2 MEMBER slopeBias2 NOTIFY dirty) - Q_PROPERTY(float slopeBias3 MEMBER slopeBias3 NOTIFY dirty) - Q_PROPERTY(float biasInput MEMBER biasInput NOTIFY dirty) - Q_PROPERTY(float globalMaxDistance MEMBER globalMaxDistance NOTIFY dirty) + Q_PROPERTY(float constantBias0 MEMBER constantBias0 NOTIFY dirty) + Q_PROPERTY(float constantBias1 MEMBER constantBias1 NOTIFY dirty) + Q_PROPERTY(float constantBias2 MEMBER constantBias2 NOTIFY dirty) + Q_PROPERTY(float constantBias3 MEMBER constantBias3 NOTIFY dirty) + Q_PROPERTY(float slopeBias0 MEMBER slopeBias0 NOTIFY dirty) + Q_PROPERTY(float slopeBias1 MEMBER slopeBias1 NOTIFY dirty) + Q_PROPERTY(float slopeBias2 MEMBER slopeBias2 NOTIFY dirty) + Q_PROPERTY(float slopeBias3 MEMBER slopeBias3 NOTIFY dirty) + Q_PROPERTY(float biasInput MEMBER biasInput NOTIFY dirty) + Q_PROPERTY(float maxDistance MEMBER maxDistance NOTIFY dirty) public: - float biasInput{ DEFAULT_BIAS_INPUT }; - float globalMaxDistance{ DEFAULT_MAX_DISTANCE }; - - float constantBias0{ 0.15f }; - float constantBias1{ 0.15f }; - float constantBias2{ 0.175f }; - float constantBias3{ 0.2f }; - float slopeBias0{ 0.4f }; - float slopeBias1{ 0.45f }; - float slopeBias2{ 0.65f }; - float slopeBias3{ 0.7f }; + // Set to > 0 to experiment with these values + float constantBias0 { 0.0f }; + float constantBias1 { 0.0f }; + float constantBias2 { 0.0f }; + float constantBias3 { 0.0f }; + float slopeBias0 { 0.0f }; + float slopeBias1 { 0.0f }; + float slopeBias2 { 0.0f }; + float slopeBias3 { 0.0f }; + float biasInput { 0.0f }; + float maxDistance { 0.0f }; signals: void dirty(); @@ -116,7 +113,7 @@ public: using JobModel = render::Job::ModelIO; RenderShadowSetup(); - void configure(const Config& configuration); + void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output); private: @@ -130,29 +127,22 @@ private: LightStage::ShadowFrame::Object _globalShadowObject; LightStage::ShadowFramePointer _shadowFrameCache; - const int DEFAULT_RESOLUTION = 1024; - float _biasInput{ DEFAULT_BIAS_INPUT }; - float _globalMaxDistance{ DEFAULT_MAX_DISTANCE }; - int resolution{ DEFAULT_RESOLUTION }; - - // initialize with values from RenderShadowSetupConfig - float constant0{ 0.15f }; - float constant1{ 0.15f }; - float constant2{ 0.175f }; - float constant3{ 0.2f }; - float slope0{ 0.4f }; - float slope1{ 0.45f }; - float slope2{ 0.65f }; - float slope3{ 0.7f }; - bool changeInDefaultConfigValues{ false }; - bool distanceTriggeredByConfig{ false }; - bool biasTriggeredByConfig{ false }; + // Values from config + float constantBias0; + float constantBias1; + float constantBias2; + float constantBias3; + float slopeBias0; + float slopeBias1; + float slopeBias2; + float slopeBias3; + float biasInput; + float maxDistance; std::array cacasdeDistances; // 4 max then 4 min distances void setConstantBias(int cascadeIndex, float value); void setSlopeBias(int cascadeIndex, float value); - void setBiasInput(float input) { _biasInput = input; } - void calculateBiases(); + void calculateBiases(float biasInput); }; class RenderShadowCascadeSetup { diff --git a/scripts/developer/utilities/render/shadow.qml b/scripts/developer/utilities/render/shadow.qml index 427b52c659..ff50bf297c 100755 --- a/scripts/developer/utilities/render/shadow.qml +++ b/scripts/developer/utilities/render/shadow.qml @@ -117,17 +117,17 @@ Rectangle { max: 1.0 min: 0.0 height: 38 - width:250 + width: 250 } ConfigSlider { label: qsTr("Shadow Max Distance") integral: false config: shadowConfig - property: "globalMaxDistance" - max: 100.0 - min: 1.0 + property: "maxDistance" + max: 250.0 + min: 0.0 height: 38 - width:250 + width: 250 } Repeater { model: [ @@ -156,17 +156,17 @@ Rectangle { integral: false config: shadowConfig property: "constantBias"+modelData - max: 1.0 + max: 3.0 min: 0.0 height: 38 - width:250 + width: 250 } ConfigSlider { label: qsTr("Slope bias") integral: false config: shadowConfig property: "slopeBias"+modelData - max: 1.0 + max: 3.0 min: 0.0 height: 38 width: 250 diff --git a/scripts/simplifiedUI/system/html/js/entityProperties.js b/scripts/simplifiedUI/system/html/js/entityProperties.js index f7c440948f..76264429ac 100644 --- a/scripts/simplifiedUI/system/html/js/entityProperties.js +++ b/scripts/simplifiedUI/system/html/js/entityProperties.js @@ -319,7 +319,7 @@ const GROUPS = [ label: "Shadow Max Distance", type: "number-draggable", min: 0, - max: 500, + max: 250, step: 0.1, decimals: 2, propertyID: "keyLight.shadowMaxDistance", diff --git a/scripts/system/create/entityProperties/html/js/entityProperties.js b/scripts/system/create/entityProperties/html/js/entityProperties.js index f7c440948f..76264429ac 100644 --- a/scripts/system/create/entityProperties/html/js/entityProperties.js +++ b/scripts/system/create/entityProperties/html/js/entityProperties.js @@ -319,7 +319,7 @@ const GROUPS = [ label: "Shadow Max Distance", type: "number-draggable", min: 0, - max: 500, + max: 250, step: 0.1, decimals: 2, propertyID: "keyLight.shadowMaxDistance", From 732a7b0a89a2bcd52778eab0666bfe31f9fc2904 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Wed, 3 Jul 2019 22:43:35 -0700 Subject: [PATCH 3/4] fix build error --- libraries/render-utils/src/RenderShadowTask.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 802dc633bf..484064f73d 100755 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -405,8 +405,8 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c calculateBiases(biasInput > 0.0f ? biasInput : currentKeyLight->getShadowBias()); - std::array constantBiases = { constantBias0, constantBias1, constantBias2, constantBias3 }; - std::array slopeBiases = { slopeBias0, slopeBias1, slopeBias2, slopeBias3 }; + std::array constantBiases = {{ constantBias0, constantBias1, constantBias2, constantBias3 }}; + std::array slopeBiases = {{ slopeBias0, slopeBias1, slopeBias2, slopeBias3 }}; for (unsigned int cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { float constantBias = constantBiases[cascadeIndex]; if (constantBias > 0.0f) { From 8fd2251612f6747a212af072e01c4194c0823b82 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 9 Jul 2019 12:52:02 -0700 Subject: [PATCH 4/4] mostly working equation? --- libraries/graphics/src/graphics/Light.h | 2 +- libraries/render-utils/src/LightStage.cpp | 12 +++-- libraries/render-utils/src/LightStage.h | 3 +- .../render-utils/src/RenderShadowTask.cpp | 47 +++++++------------ libraries/render-utils/src/RenderShadowTask.h | 1 - .../src/directional_skybox_light_shadow.slf | 1 - scripts/developer/utilities/render/shadow.qml | 4 +- 7 files changed, 32 insertions(+), 38 deletions(-) diff --git a/libraries/graphics/src/graphics/Light.h b/libraries/graphics/src/graphics/Light.h index 37670176cc..81a6fddbd3 100755 --- a/libraries/graphics/src/graphics/Light.h +++ b/libraries/graphics/src/graphics/Light.h @@ -199,7 +199,7 @@ protected: float _spotCos { -1.0f }; // stored here to be able to reset the spot angle when turning the type spot on/off float _shadowsMaxDistance { 40.0f }; - float _shadowBias { 0.5f }; // 0.23f will roughly give the default constant and slope values + float _shadowBias { 0.5f }; bool _castShadows{ false }; void updateLightRadius(); diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index 524deaaad2..ccdf45cedc 100755 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -16,7 +16,8 @@ #include "ViewFrustum.h" std::string LightStage::_stageName { "LIGHT_STAGE"}; -const glm::mat4 LightStage::Shadow::_biasMatrix{ +// 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, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, @@ -249,7 +250,7 @@ void LightStage::Shadow::setKeylightFrustum(const ViewFrustum& viewFrustum, } void LightStage::Shadow::setKeylightCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& viewFrustum, - float nearDepth, float farDepth, float fixedBias, float slopeBias) { + float nearDepth, float farDepth) { assert(nearDepth < farDepth); assert(cascadeIndex < _cascades.size()); @@ -300,7 +301,12 @@ void LightStage::Shadow::setKeylightCascadeFrustum(unsigned int cascadeIndex, co auto& schema = _schemaBuffer.edit(); auto& schemaCascade = schema.cascades[cascadeIndex]; schemaCascade.reprojection = _biasMatrix * ortho * shadowViewInverse.getMatrix(); - schemaCascade.fixedBias = fixedBias; +} + +void LightStage::Shadow::setKeylightCascadeBias(unsigned int cascadeIndex, float constantBias, float slopeBias) { + auto& schema = _schemaBuffer.edit(); + auto& schemaCascade = schema.cascades[cascadeIndex]; + schemaCascade.fixedBias = constantBias; schemaCascade.slopeBias = slopeBias; } diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index 4da66843cc..36e62c614f 100755 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -81,7 +81,8 @@ public: void setKeylightFrustum(const ViewFrustum& viewFrustum, float nearDepth = 1.0f, float farDepth = 1000.0f); void setKeylightCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& viewFrustum, - float nearDepth = 1.0f, float farDepth = 1000.0f, float fixedBias = 0.005f, float slopeBias = 0.005f); + float nearDepth = 1.0f, float farDepth = 1000.0f); + void setKeylightCascadeBias(unsigned int cascadeIndex, float constantBias, float slopeBias); void setCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& shadowFrustum); const UniformBufferView& getBuffer() const { return _schemaBuffer; } diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 484064f73d..0d0b776074 100755 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -329,37 +329,31 @@ void RenderShadowSetup::configure(const Config& config) { } void RenderShadowSetup::calculateBiases(float biasInput) { - // slope scaling values derived from ratio between original constantBias and slopeBias pairs - const std::array SLOPE_SCALES = {{ 2.7f, 3.0f, 3.7f, 3.5f }}; - const float CONVERT_BIAS = 100.0f; - const float MIN_SCALE_DIVISOR = 0.5f; - - // the bias is relative to resolution - // to remain consistent with the constant and slope bias values, the biasInput - // value is in the 0.0 - 1.0 range but needs to be scaled up for further calculations - // TODO: expose variable resolution - int resolution = LightStage::Shadow::MAP_SIZE; - const int DEFAULT_RESOLUTION = LightStage::Shadow::MAP_SIZE; - float inverseResolution = 1.0f / (float)resolution; - int resolutionScale = DEFAULT_RESOLUTION * inverseResolution; - float convertedBias = biasInput * (CONVERT_BIAS / resolutionScale); - float scaleFactor = 1.0f; + const std::array CONSTANT_CASCADE_SCALE = {{ 0.01f, 0.01f, 0.015f, 0.02f }}; + const float SLOPE_BIAS_SCALE = 0.005f; for (int i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { - scaleFactor = convertedBias * (cacasdeDistances[0] / glm::max(MIN_SCALE_DIVISOR, cacasdeDistances[i + SHADOW_CASCADE_MAX_COUNT])) * inverseResolution; - float constantBias = cacasdeDistances[i] * scaleFactor; - float slopeBias = cacasdeDistances[i] * scaleFactor * SLOPE_SCALES[i]; + auto& cascade = _globalShadowObject->getCascade(i); + + // Constant bias is dependent on the depth precision + float cascadeDepth = cascade.getMaxDistance() - cascade.getMinDistance(); + float constantBias = CONSTANT_CASCADE_SCALE[i] * biasInput / cascadeDepth; setConstantBias(i, constantBias); - setSlopeBias(i, slopeBias); + + // Slope bias is dependent on the texel size + float cascadeWidth = cascade.getFrustum()->getWidth(); + float cascadeHeight = cascade.getFrustum()->getHeight(); + float cascadeTexelMaxDim = glm::max(cascadeWidth, cascadeHeight) / LightStage::Shadow::MAP_SIZE; // TODO: variable cascade resolution + setSlopeBias(i, cascadeTexelMaxDim * constantBias / SLOPE_BIAS_SCALE); } } void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) { - _bias[cascadeIndex]._constant = value * value * value * 0.004f; + _bias[cascadeIndex]._constant = value; } void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) { - _bias[cascadeIndex]._slope = value * value * value * 0.001f; + _bias[cascadeIndex]._slope = value; } void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, const Input& input, Output& output) { @@ -398,9 +392,9 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c // Update our biases and maxDistance from the light or config _globalShadowObject->setMaxDistance(maxDistance > 0.0f ? maxDistance : currentKeyLight->getShadowsMaxDistance()); + // Adjust each cascade frustum for (unsigned int cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { - cacasdeDistances[cascadeIndex] = _globalShadowObject->getCascade(cascadeIndex).getMaxDistance(); - cacasdeDistances[cascadeIndex + SHADOW_CASCADE_MAX_COUNT] = _globalShadowObject->getCascade(cascadeIndex).getMinDistance(); + _globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); } calculateBiases(biasInput > 0.0f ? biasInput : currentKeyLight->getShadowBias()); @@ -416,14 +410,9 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c if (slopeBias > 0.0f) { setSlopeBias(cascadeIndex, slopeBias); } - } - // Adjust each cascade frustum - for (unsigned int cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { auto& bias = _bias[cascadeIndex]; - _globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(), - SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR, - bias._constant, bias._slope); + _globalShadowObject->setKeylightCascadeBias(cascadeIndex, bias._constant, bias._slope); } _shadowFrameCache->pushShadow(_globalShadowObject); diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 23047ee179..98b5ac1e10 100755 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -138,7 +138,6 @@ private: float slopeBias3; float biasInput; float maxDistance; - std::array cacasdeDistances; // 4 max then 4 min distances void setConstantBias(int cascadeIndex, float value); void setSlopeBias(int cascadeIndex, float value); diff --git a/libraries/render-utils/src/directional_skybox_light_shadow.slf b/libraries/render-utils/src/directional_skybox_light_shadow.slf index 8716d60d54..48d59fa364 100644 --- a/libraries/render-utils/src/directional_skybox_light_shadow.slf +++ b/libraries/render-utils/src/directional_skybox_light_shadow.slf @@ -35,7 +35,6 @@ void main(void) { vec3 worldLightDirection = getLightDirection(shadowLight); float shadowAttenuation = evalShadowAttenuation(worldLightDirection, worldPos, -viewPos.z, frag.normal); - // Light mapped or not ? if (frag.mode == FRAG_MODE_UNLIT || frag.mode == FRAG_MODE_LIGHTMAPPED) { discard; } else { diff --git a/scripts/developer/utilities/render/shadow.qml b/scripts/developer/utilities/render/shadow.qml index ff50bf297c..6af0b21d1b 100755 --- a/scripts/developer/utilities/render/shadow.qml +++ b/scripts/developer/utilities/render/shadow.qml @@ -156,7 +156,7 @@ Rectangle { integral: false config: shadowConfig property: "constantBias"+modelData - max: 3.0 + max: 1.0 min: 0.0 height: 38 width: 250 @@ -166,7 +166,7 @@ Rectangle { integral: false config: shadowConfig property: "slopeBias"+modelData - max: 3.0 + max: 1.0 min: 0.0 height: 38 width: 250