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",