1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
5#ifndef QSSG_RENDERER_H
6#define QSSG_RENDERER_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtQuick3DRuntimeRender/private/qssgrenderableobjects_p.h>
20#include <QtQuick3DRuntimeRender/private/qssgrendermesh_p.h>
21#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>
22#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterial_p.h>
23#include <QtQuick3DRuntimeRender/private/qssgrenderlayer_p.h>
24#include <QtQuick3DRuntimeRender/private/qssgrenderray_p.h>
25#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
26#include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h>
27#include <QtQuick3DRuntimeRender/private/qssgrenderclippingfrustum_p.h>
28#include <QtQuick3DRuntimeRender/private/qssgrendershaderkeys_p.h>
29#include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h>
30#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterialshadergenerator_p.h>
31#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
32#include <QtQuick3DRuntimeRender/private/qssgrenderpickresult_p.h>
33#include <QtQuick3DRuntimeRender/private/qssgshadermapkey_p.h>
34#include <QtQuick3DRuntimeRender/private/qssgrenderpass_p.h>
35
36#include <QtQuick3DUtils/private/qssgbounds3_p.h>
37#include <QtQuick3DUtils/private/qssgdataref_p.h>
38
39QT_BEGIN_NAMESPACE
40
41class QSSGRhiQuadRenderer;
42class QSSGRhiCubeRenderer;
43struct QSSGRenderItem2D;
44struct QSSGReflectionMapEntry;
45
46class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderer
47{
48 Q_DISABLE_COPY(QSSGRenderer)
49 using PickResultList = QVarLengthArray<QSSGRenderPickResult, 20>; // Lets assume most items are filtered out already
50public:
51 QSSGRenderer();
52 ~QSSGRenderer();
53
54 QSSGShaderDefaultMaterialKeyProperties &defaultMaterialShaderKeyProperties()
55 {
56 return m_defaultMaterialShaderKeyProperties;
57 }
58
59 void setRenderContextInterface(QSSGRenderContextInterface *ctx);
60
61 // Returns true if this layer or a sibling was dirty.
62 bool prepareLayerForRender(QSSGRenderLayer &inLayer);
63
64 void rhiPrepare(QSSGRenderLayer &inLayer);
65 void rhiRender(QSSGRenderLayer &inLayer);
66
67 void cleanupResources(QList<QSSGRenderGraphObject*> &resources);
68 void cleanupResources(QSet<QSSGRenderGraphObject*> &resources);
69
70 QSSGLayerRenderData *getOrCreateLayerRenderData(QSSGRenderLayer &layer);
71
72 // The QSSGRenderContextInterface calls these, clients should not.
73 void beginFrame(QSSGRenderLayer *layer);
74 void endFrame(QSSGRenderLayer *layer);
75
76 PickResultList syncPickAll(const QSSGRenderLayer &layer,
77 QSSGBufferManager &bufferManager,
78 const QSSGRenderRay &ray);
79
80 QSSGRenderPickResult syncPick(const QSSGRenderLayer &layer,
81 QSSGBufferManager &bufferManager,
82 const QSSGRenderRay &ray,
83 QSSGRenderNode *target = nullptr);
84
85 // Setting this true enables picking for all the models, regardless of
86 // the models pickable property.
87 bool isGlobalPickingEnabled() const;
88 void setGlobalPickingEnabled(bool isEnabled);
89
90 QSSGRhiQuadRenderer *rhiQuadRenderer();
91 QSSGRhiCubeRenderer *rhiCubeRenderer();
92
93 void beginLayerRender(QSSGLayerRenderData &inLayer);
94 void endLayerRender();
95 void addMaterialDirtyClear(QSSGRenderGraphObject *material);
96
97 static QSSGRhiShaderPipelinePtr generateRhiShaderPipelineImpl(QSSGSubsetRenderable &renderable, QSSGShaderLibraryManager &shaderLibraryManager,
98 QSSGShaderCache &shaderCache,
99 QSSGProgramGenerator &shaderProgramGenerator,
100 QSSGShaderDefaultMaterialKeyProperties &shaderKeyProperties,
101 const QSSGShaderFeatures &featureSet,
102 QByteArray &shaderString);
103
104 QSSGRhiShaderPipelinePtr getShaderPipelineForDefaultMaterial(QSSGSubsetRenderable &inRenderable,
105 const QSSGShaderFeatures &inFeatureSet);
106
107 QSSGLayerGlobalRenderProperties getLayerGlobalRenderProperties();
108
109 QSSGRenderContextInterface *contextInterface() const { return m_contextInterface; }
110
111 enum class LightmapUVRasterizationShaderMode {
112 Default,
113 Uv,
114 UvTangent
115 };
116
117 // shader implementations, RHI, implemented in qssgrendererimplshaders_rhi.cpp
118 QSSGRhiShaderPipelinePtr getRhiCubemapShadowBlurXShader();
119 QSSGRhiShaderPipelinePtr getRhiCubemapShadowBlurYShader();
120 QSSGRhiShaderPipelinePtr getRhiGridShader();
121 QSSGRhiShaderPipelinePtr getRhiOrthographicShadowBlurXShader();
122 QSSGRhiShaderPipelinePtr getRhiOrthographicShadowBlurYShader();
123 QSSGRhiShaderPipelinePtr getRhiSsaoShader();
124 QSSGRhiShaderPipelinePtr getRhiSkyBoxCubeShader();
125 QSSGRhiShaderPipelinePtr getRhiSkyBoxShader(QSSGRenderLayer::TonemapMode tonemapMode, bool isRGBE);
126 QSSGRhiShaderPipelinePtr getRhiSupersampleResolveShader();
127 QSSGRhiShaderPipelinePtr getRhiProgressiveAAShader();
128 QSSGRhiShaderPipelinePtr getRhiTexturedQuadShader();
129 QSSGRhiShaderPipelinePtr getRhiParticleShader(QSSGRenderParticles::FeatureLevel featureLevel);
130 QSSGRhiShaderPipelinePtr getRhiSimpleQuadShader();
131 QSSGRhiShaderPipelinePtr getRhiLightmapUVRasterizationShader(LightmapUVRasterizationShaderMode mode);
132 QSSGRhiShaderPipelinePtr getRhiLightmapDilateShader();
133 QSSGRhiShaderPipelinePtr getRhiDebugObjectShader();
134
135 static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode);
136
137protected:
138 static void getLayerHitObjectList(const QSSGRenderLayer &layer,
139 QSSGBufferManager &bufferManager,
140 const QSSGRenderRay &ray,
141 bool inPickEverything,
142 PickResultList &outIntersectionResult);
143 static void intersectRayWithSubsetRenderable(QSSGBufferManager &bufferManager,
144 const QSSGRenderRay &inRay,
145 const QSSGRenderNode &node,
146 PickResultList &outIntersectionResultList);
147 static void intersectRayWithItem2D(const QSSGRenderRay &inRay, const QSSGRenderItem2D &item2D, PickResultList &outIntersectionResultList);
148
149private:
150 friend class QSSGRenderContextInterface;
151 friend class QSSGLayerRenderData;
152
153 void releaseCachedResources();
154 QSSGRhiShaderPipelinePtr getBuiltinRhiShader(const QByteArray &name,
155 QSSGRhiShaderPipelinePtr &storage);
156 QSSGRhiShaderPipelinePtr generateRhiShaderPipeline(QSSGSubsetRenderable &inRenderable, const QSSGShaderFeatures &inFeatureSet);
157
158 QSSGRenderContextInterface *m_contextInterface = nullptr; // We're own by the context interface
159
160 // The shader refs are non-null if we have attempted to generate the
161 // shader. This does not mean we were successul, however.
162
163 // RHI
164 QSSGRhiShaderPipelinePtr m_cubemapShadowBlurXRhiShader;
165 QSSGRhiShaderPipelinePtr m_cubemapShadowBlurYRhiShader;
166 QSSGRhiShaderPipelinePtr m_gridShader;
167 QSSGRhiShaderPipelinePtr m_orthographicShadowBlurXRhiShader;
168 QSSGRhiShaderPipelinePtr m_orthographicShadowBlurYRhiShader;
169 QSSGRhiShaderPipelinePtr m_ssaoRhiShader;
170 QSSGRhiShaderPipelinePtr m_skyBoxRhiShader;
171 QSSGRhiShaderPipelinePtr m_skyBoxCubeRhiShader;
172 QSSGRhiShaderPipelinePtr m_supersampleResolveRhiShader;
173 QSSGRhiShaderPipelinePtr m_progressiveAARhiShader;
174 QSSGRhiShaderPipelinePtr m_texturedQuadRhiShader;
175 QSSGRhiShaderPipelinePtr m_simpleQuadRhiShader;
176 QSSGRhiShaderPipelinePtr m_lightmapUVRasterShader;
177 QSSGRhiShaderPipelinePtr m_lightmapUVRasterShader_uv;
178 QSSGRhiShaderPipelinePtr m_lightmapUVRasterShader_uv_tangent;
179 QSSGRhiShaderPipelinePtr m_lightmapDilateShader;
180 QSSGRhiShaderPipelinePtr m_debugObjectShader;
181
182 QSSGRhiShaderPipelinePtr m_particlesNoLightingSimpleRhiShader;
183 QSSGRhiShaderPipelinePtr m_particlesNoLightingMappedRhiShader;
184 QSSGRhiShaderPipelinePtr m_particlesNoLightingAnimatedRhiShader;
185 QSSGRhiShaderPipelinePtr m_particlesVLightingSimpleRhiShader;
186 QSSGRhiShaderPipelinePtr m_particlesVLightingMappedRhiShader;
187 QSSGRhiShaderPipelinePtr m_particlesVLightingAnimatedRhiShader;
188 QSSGRhiShaderPipelinePtr m_lineParticlesRhiShader;
189 QSSGRhiShaderPipelinePtr m_lineParticlesMappedRhiShader;
190 QSSGRhiShaderPipelinePtr m_lineParticlesAnimatedRhiShader;
191 QSSGRhiShaderPipelinePtr m_lineParticlesVLightRhiShader;
192 QSSGRhiShaderPipelinePtr m_lineParticlesMappedVLightRhiShader;
193 QSSGRhiShaderPipelinePtr m_lineParticlesAnimatedVLightRhiShader;
194
195 bool m_globalPickingEnabled = false;
196
197 // Temporary information stored only when rendering a particular layer.
198 QSSGLayerRenderData *m_currentLayer = nullptr;
199 QMatrix4x4 m_viewProjection;
200 QByteArray m_generatedShaderString;
201
202 QSSGShaderDefaultMaterialKeyProperties m_defaultMaterialShaderKeyProperties;
203
204 QSet<QSSGRenderGraphObject *> m_materialClearDirty;
205
206 QSSGRhiQuadRenderer *m_rhiQuadRenderer = nullptr;
207 QSSGRhiCubeRenderer *m_rhiCubeRenderer = nullptr;
208
209 QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> m_shaderMap;
210
211 // Skybox shader state
212 QSSGRenderLayer::TonemapMode m_skyboxTonemapMode = QSSGRenderLayer::TonemapMode::None;
213 bool m_isSkyboxRGBE = false;
214};
215
216namespace RenderHelpers
217{
218
219std::pair<QSSGBoxPoints, QSSGBoxPoints> calculateSortedObjectBounds(const QVector<QSSGRenderableObjectHandle> &sortedOpaqueObjects,
220 const QVector<QSSGRenderableObjectHandle> &sortedTransparentObjects);
221
222void rhiRenderShadowMap(QSSGRhiContext *rhiCtx, QSSGPassKey passKey,
223 QSSGRhiGraphicsPipelineState &ps,
224 QSSGRenderShadowMap &shadowMapManager,
225 const QSSGRenderCamera &camera,
226 const QSSGShaderLightList &globalLights,
227 const QVector<QSSGRenderableObjectHandle> &sortedOpaqueObjects,
228 QSSGRenderer &renderer,
229 const QSSGBoxPoints &castingObjectsBox,
230 const QSSGBoxPoints &receivingObjectsBox);
231
232void rhiRenderReflectionMap(QSSGRhiContext *rhiCtx,
233 QSSGPassKey passKey,
234 const QSSGLayerRenderData &inData, QSSGRhiGraphicsPipelineState *ps,
235 QSSGRenderReflectionMap &reflectionMapManager,
236 const QVector<QSSGRenderReflectionProbe *> &reflectionProbes,
237 const QVector<QSSGRenderableObjectHandle> &reflectionPassObjects,
238 QSSGRenderer &renderer);
239
240bool rhiPrepareDepthPass(QSSGRhiContext *rhiCtx, QSSGPassKey passKey,
241 const QSSGRhiGraphicsPipelineState &basePipelineState,
242 QRhiRenderPassDescriptor *rpDesc,
243 QSSGLayerRenderData &inData,
244 const QVector<QSSGRenderableObjectHandle> &sortedOpaqueObjects,
245 const QVector<QSSGRenderableObjectHandle> &sortedTransparentObjects,
246 int samples);
247
248void rhiRenderDepthPass(QSSGRhiContext *rhiCtx, const QSSGRhiGraphicsPipelineState &ps,
249 const QVector<QSSGRenderableObjectHandle> &sortedOpaqueObjects,
250 const QVector<QSSGRenderableObjectHandle> &sortedTransparentObjects,
251 bool *needsSetViewport);
252
253bool rhiPrepareAoTexture(QSSGRhiContext *rhiCtx, const QSize &size, QSSGRhiRenderableTexture *renderableTex);
254
255void rhiRenderAoTexture(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, QSSGRenderer &renderer, QSSGRhiShaderPipeline &shaderPipeline,
256 QSSGRhiGraphicsPipelineState &ps, const SSAOMapPass::AmbientOcclusion &ao, const QSSGRhiRenderableTexture &rhiAoTexture, const QSSGRhiRenderableTexture &rhiDepthTexture,
257 const QSSGRenderCamera &camera);
258
259bool rhiPrepareScreenTexture(QSSGRhiContext *rhiCtx, const QSize &size, bool wantsMips, QSSGRhiRenderableTexture *renderableTex);
260
261void rhiPrepareGrid(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, QSSGRenderLayer &layer,
262 QSSGRenderCamera &inCamera, QSSGRenderer &renderer);
263
264
265void rhiPrepareSkyBox(QSSGRhiContext *rhiCtx, QSSGPassKey passKey,
266 QSSGRenderLayer &layer,
267 QSSGRenderCamera &inCamera,
268 QSSGRenderer &renderer);
269
270void rhiPrepareSkyBoxForReflectionMap(QSSGRhiContext *rhiCtx, QSSGPassKey passKey,
271 QSSGRenderLayer &layer,
272 QSSGRenderCamera &inCamera,
273 QSSGRenderer &renderer,
274 QSSGReflectionMapEntry *entry,
275 QSSGRenderTextureCubeFace cubeFace);
276
277Q_QUICK3DRUNTIMERENDER_EXPORT void rhiPrepareRenderable(QSSGRhiContext *rhiCtx, QSSGPassKey passKey,
278 const QSSGLayerRenderData &inData,
279 QSSGRenderableObject &inObject,
280 QRhiRenderPassDescriptor *renderPassDescriptor,
281 QSSGRhiGraphicsPipelineState *ps,
282 QSSGShaderFeatures featureSet,
283 int samples,
284 QSSGRenderCamera *inCamera = nullptr,
285 QMatrix4x4 *alteredModelViewProjection = nullptr,
286 QSSGRenderTextureCubeFace cubeFace = QSSGRenderTextureCubeFaceNone,
287 QSSGReflectionMapEntry *entry = nullptr);
288
289Q_QUICK3DRUNTIMERENDER_EXPORT void rhiRenderRenderable(QSSGRhiContext *rhiCtx,
290 const QSSGRhiGraphicsPipelineState &state,
291 QSSGRenderableObject &object,
292 bool *needsSetViewport,
293 QSSGRenderTextureCubeFace cubeFace = QSSGRenderTextureCubeFaceNone);
294
295bool rhiPrepareDepthTexture(QSSGRhiContext *rhiCtx, const QSize &size, QSSGRhiRenderableTexture *renderableTex);
296
297inline QRect correctViewportCoordinates(const QRectF &layerViewport, const QRect &deviceRect)
298{
299 const int y = deviceRect.bottom() - layerViewport.bottom() + 1;
300 return QRect(layerViewport.x(), y, layerViewport.width(), layerViewport.height());
301}
302}
303
304QT_END_NAMESPACE
305
306#endif
307

source code of qtquick3d/src/runtimerender/rendererimpl/qssgrenderer_p.h