Revision control

++ // Copyright (C) 2008-2012 NVIDIA Corporation.
++ // Copyright (C) 2019 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++
++ #ifndef QSSG_RENDER_LAYER_H
++ #define QSSG_RENDER_LAYER_H
++
++ //
++ // W A R N I N G
++ // -------------
++ //
++ // This file is not part of the Qt API. It exists purely as an
++ // implementation detail. This header file may change from version to
++ // version without notice, or even be removed.
++ //
++ // We mean it.
++ //
++
++ #include <QtQuick3DRuntimeRender/private/qssgrendernode_p.h>
++ #include <QtCore/qvarlengtharray.h>
++ #include <QtCore/qlist.h>
++ #include <QMutex>
++ #include <ssg/qssglightmapper.h>
++
++ QT_BEGIN_NAMESPACE
++ class QSSGRenderContextInterface;
++ struct QSSGRenderPresentation;
++ struct QSSGRenderEffect;
++ struct QSSGRenderSkyMaterial;
++ struct QSSGRenderImage;
++ class QSSGLayerRenderData;
++ struct QSSGRenderResourceLoader;
++
++ class QQuick3DObject;
++ class QSSGRenderExtension;
++
++ class QRhiShaderResourceBindings;
++
++ // A layer is a special node. It *always* presents its global transform
++ // to children as the identity. It also can optionally have a width or height
++ // different than the overlying context. You can think of layers as the transformation
++ // between a 3d scene graph and a 2D texture.
++ struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderLayer : public QSSGRenderNode
++ {
++ enum class AAMode : quint8
++ {
++ NoAA = 0,
++ SSAA,
++ MSAA,
++ ProgressiveAA
++ };
++
++ enum class TAAMode : quint8
++ {
++ Off = 0,
++ Default,
++ MotionVector
++ };
++
++ enum class AAQuality : quint8
++ {
++ Normal = 2,
++ High = 4,
++ VeryHigh = 8
++ };
++
++ enum class HorizontalField : quint8
++ {
++ LeftWidth = 0,
++ LeftRight,
++ WidthRight
++ };
++
++ enum class VerticalField : quint8
++ {
++ TopHeight = 0,
++ TopBottom,
++ HeightBottom
++ };
++
++ enum class UnitType : quint8
++ {
++ Percent = 0,
++ Pixels
++ };
++
++ enum class Background : quint8
++ {
++ Transparent = 0,
++ Unspecified,
++ Color,
++ SkyBox,
++ SkyBoxCubeMap,
++ SkyMaterial
++ };
++
++ enum class TonemapMode : quint8
++ {
++ None = 0, // Bypass mode
++ Linear,
++ Aces,
++ HejlDawson,
++ Filmic,
++ Custom
++ };
++ static size_t constexpr TonemapModeCount = 6;
++
++ enum class LayerFlag
++ {
++ EnableDepthTest = 0x1,
++ EnableDepthPrePass = 0x2, ///< True when we render a depth pass before
++ RenderToTarget = 0x3 ///< Does this layer render to the normal render target,
++ };
++ Q_DECLARE_FLAGS(LayerFlags, LayerFlag)
++
++ enum class MaterialDebugMode : quint8
++ {
++ None = 0, // Bypass
++ BaseColor = 1,
++ Roughness,
++ Metalness,
++ Diffuse,
++ Specular,
++ ShadowOcclusion,
++ Emission,
++ AmbientOcclusion,
++ Normal,
++ Tangent,
++ Binormal,
++ F0
++ };
++
++ enum class OITMethod : quint8
++ {
++ None = 0,
++ WeightedBlended,
++ LinkedList
++ };
++
++ enum class RenderOverrides : quint8
++ {
++ None = 0,
++ DisableInternalPasses = 0x1,
++ };
++ using RenderOverridesT = std::underlying_type_t<RenderOverrides>;
++
++ enum class DirtyFlag : quint8
++ {
++ TreeDirty = 0x1,
++ VisibilityDirty = 0x2 // layer's viewport transitioned from hidden to visible
++ };
++ using FlagT = std::underlying_type_t<DirtyFlag>;
++
++ static constexpr DirtyFlag DirtyMask { std::numeric_limits<FlagT>::max() };
++
++ [[nodiscard]] bool isDirty(DirtyFlag dirtyFlag = DirtyMask) const
++ {
++ return ((m_layerDirtyFlags & FlagT(dirtyFlag)) != 0)
++ || ((dirtyFlag == DirtyMask) && QSSGRenderNode::isDirty());
++ }
++ void markDirty(DirtyFlag dirtyFlag);
++ void clearDirty(DirtyFlag dirtyFlag);
++
++ void ref(QSSGRenderRoot *inRootNode)
++ {
++ rootNode = inRootNode;
++ rootNodeRef = &rootNode;
++ }
++
++ QSSGRenderRoot *rootNode = nullptr;
++
++ QSSGRenderLayerHandle lh;
++
++ // First effect in a list of effects.
++ QSSGRenderEffect *firstEffect;
++ QSSGLayerRenderData *renderData = nullptr;
++ enum class RenderExtensionStage { TextureProviders, Underlay, Overlay, Count };
++ QList<QSSGRenderExtension *> renderExtensions[size_t(RenderExtensionStage::Count)];
++
++ QSSGRenderLayer::AAMode antialiasingMode;
++ QSSGRenderLayer::AAQuality antialiasingQuality;
++ QVector4D currentAndLastJitter;
++
++ QSSGRenderLayer::Background background;
++ QVector3D clearColor;
++
++ FlagT m_layerDirtyFlags = FlagT(DirtyFlag::TreeDirty);
++ quint8 viewCount = 1;
++
++ // Ambient occlusion
++ float aoStrength = 0.0f;
++ float aoDistance = 5.0f;
++ float aoSoftness = 50.0f;
++ float aoBias = 0.0f;
++ qint32 aoSamplerate = 2;
++ bool aoDither = false;
++ bool aoEnabled = false;
++
++ constexpr bool ssaoEnabled() const { return aoEnabled && (aoStrength > 0.0f && aoDistance > 0.0f); }
++
++ // IBL
++ QSSGRenderImage *lightProbe { nullptr };
++ struct LightProbeSettings {
++ float probeExposure { 1.0f };
++ float probeHorizon { -1.0f };
++ QMatrix3x3 probeOrientation;
++ QVector3D probeOrientationAngles;
++ } lightProbeSettings;
++
++ QSSGRenderSkyMaterial *skyMaterial = nullptr;
++
++ QSSGRenderImage *skyBoxCubeMap = nullptr;
++
++ TAAMode temporalAAMode { TAAMode::Off };
++ float temporalAAStrength;
++ float ssaaMultiplier;
++ bool specularAAEnabled;
++ OITMethod oitMethod;
++ bool oitMethodDirty;
++ int oitNodeCount;
++
++ //TODO: move render state somewhere more suitable
++ bool temporalAAIsActive;
++ bool progressiveAAIsActive;
++ uint tempAAPassIndex;
++ uint progAAPassIndex;
++
++ RenderOverridesT renderOverrides { RenderOverridesT(RenderOverrides::None) };
++
++ // The camera explicitly set on the view by the user. (backend node can be null)
++ QVarLengthArray<QSSGRenderCamera *, 2> explicitCameras;
++ // The camera used for rendering, multiple ones with multiview.
++ QVarLengthArray<QSSGRenderCamera *, 2> renderedCameras;
++ QMutex renderedCamerasMutex;
++
++ // Tonemapping
++ TonemapMode tonemapMode;
++
++ LayerFlags layerFlags { LayerFlag::RenderToTarget,
++ LayerFlag::EnableDepthTest,
++ LayerFlag::EnableDepthPrePass };
++
++ // references to objects owned by the QSSGRhiContext
++ QRhiShaderResourceBindings *skyBoxSrb = nullptr;
++ QVarLengthArray<QRhiShaderResourceBindings *, 4> item2DSrbs;
++ bool skyBoxIsRgbe8 = false;
++ bool skyBoxIsSrgb = false;
++
++ // Skybox
++ float skyboxBlurAmount = 0.0f;
++
++ // Grid
++ bool gridEnabled = false;
++ float gridScale = 1.0f;
++ quint32 gridFlags = 0;
++ QRhiShaderResourceBindings *gridSrb = nullptr;
++
++ // Scissor
++ QRect scissorRect;
++
++ // Fog
++ struct FogOptions {
++ bool enabled = false;
++ QVector3D color = QVector3D(0.5f, 0.6f, 0.7f);
++ float density = 1.0f;
++ bool depthEnabled = false;
++ float depthBegin = 10.0f;
++ float depthEnd = 1000.0f;
++ float depthCurve = 1.0f;
++ bool heightEnabled = false;
++ float heightMin = 10.0f;
++ float heightMax = 0.0f;
++ float heightCurve = 1.0f;
++ bool transmitEnabled = false;
++ float transmitCurve = 1.0f;
++ } fog;
++
++ QVector<QSSGRenderGraphObject *> resourceLoaders;
++
++ MaterialDebugMode debugMode = MaterialDebugMode::None;
++
++ bool wireframeMode = false;
++ bool drawDirectionalLightShadowBoxes = false;
++ bool drawPointLightShadowBoxes = false;
++ bool drawShadowCastingBounds = false;
++ bool drawShadowReceivingBounds = false;
++ bool drawCascades = false;
++ bool drawSceneCascadeIntersection = false;
++ bool disableShadowCameraUpdate = false;
++ bool drawCulledObjects = false;
++
++ // Would ideally be in QSSGLayerRenderData but it is created too late
++ // so needs to be set here.
++ QString lightmapSource;
++
++ QSSGRenderLayer();
++ ~QSSGRenderLayer();
++
++ void setProbeOrientation(const QVector3D &angles);
++
++ void addEffect(QSSGRenderEffect &inEffect);
++ bool hasEffect(QSSGRenderEffect *inEffect) const;
++
++ QSSGRenderNode *importSceneNode = nullptr;
++
++ // Special function(s) for importScene
++ void setImportScene(QSSGRenderNode &rootNode);
++ void removeImportScene(QSSGRenderNode &importedNode);
++
++ [[nodiscard]] bool isMsaaEnabled() const { return antialiasingMode == AAMode::MSAA; }
++ [[nodiscard]] bool isSsaaEnabled() const { return antialiasingMode == AAMode::SSAA; }
++ // NOTE: Progressive AA is not enabled when temporalAA mode is MotionVector.
++ [[nodiscard]] bool isProgressiveAAEnabled() const { return antialiasingMode == AAMode::ProgressiveAA && temporalAAMode != TAAMode::MotionVector; }
++ // NOTE: Temporal AA is not enabled when MSAA is enabled.
++ [[nodiscard]] bool isTemporalAAEnabled() const { return (temporalAAMode != TAAMode::Off) && !isMsaaEnabled(); }
++
++ static constexpr float ssaaMultiplierForQuality(QSSGRenderLayer::AAQuality quality)
++ {
++ switch (quality) {
++ case QSSGRenderLayer::AAQuality::Normal:
++ return 1.2f;
++ case QSSGRenderLayer::AAQuality::High:
++ return 1.5f;
++ case QSSGRenderLayer::AAQuality::VeryHigh:
++ return 2.0f;
++ }
++
++ return 1.5f; // QSSGRenderLayer::AAQuality::High
++ }
++ };
++ QT_END_NAMESPACE
++
++ #endif