Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquick3drenderoutputprovider.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
7
8#include "private/qquick3dobject_p.h"
9
10#include <QtQuick3DRuntimeRender/private/qssglayerrenderdata_p.h>
11
12#include <ssg/qssgrenderextensions.h>
13#include <ssg/qssgrenderhelpers.h>
14#include <ssg/qssgrendercontextcore.h>
15#include <ssg/qssgrhicontext.h>
16#include <ssg/qquick3dextensionhelpers.h>
17
19
45
47 : m_ext(ext)
48{
49
50}
51
56
58{
59 // Update the extension ID.
60 // NOTE: This needs to be done on each call, the extension object may have changed.
61 // If the extension is destroyed (m_ext == nullptr), we cannot proceed and should return false!
62 m_extensionId = m_ext ? QQuick3DExtensionHelpers::getExtensionId(*m_ext) : QSSGExtensionId::Invalid;
63 if (QQuick3DExtensionHelpers::isNull(m_extensionId))
64 return false;
65
66 const bool wasDirty = m_isDirty;
67
68 switch (m_sourceType) {
70 // Nothing to do
71 m_isDirty = false;
72 break;
74 {
75 // Make sure we schedule the pass to run this frame
76 data.scheduleRenderResults(QSSGFrameData::RenderResults(m_builtInPass));
77
78 // Check if a texture exists for the result already
79 QSSGFrameData::Result extResult = data.getRenderResult(m_builtInPass);
80 if (extResult.texture) {
81 QSSGRenderExtensionHelpers::registerRenderResult(data, m_extensionId, extResult.texture);
82 m_isDirty = false;
83
84 }
85 // No "else" in this case since its likely the texture for the pass doesn't exist yet, try again in prepareRender.
86 }
87 break;
89 {
90 if (userPassId != QSSGResourceId::Invalid) {
91 // Make sure we schedule the pass to run this frame
92 data.scheduleRenderResults(userPassId);
93
94 // Check if a texture exists for the result already
95 QSSGFrameData::Result extResult = data.getRenderResult(userPassId, attachmentSelector);
96 if (extResult.texture) {
97 // Associate the texture with this extension and expose it so it can be used.
98 QSSGRenderExtensionHelpers::registerRenderResult(data, m_extensionId, extResult.texture);
99 m_isDirty = false;
100
101 }
102 }
103 // No "else" in this case since its likely the texture for the pass doesn't exist yet, try again in prepareRender.
104 }
105 break;
106 }
107
108 return wasDirty;
109}
110
112{
113 // If no id is set prepareData() should return false and this should not be called!
114 Q_ASSERT(!QQuick3DExtensionHelpers::isNull(m_extensionId));
115
116 QSSGFrameData::Result extResult;
118 extResult = data.getRenderResult(m_builtInPass);
119 else if (m_sourceType == SourceType::UserPass && userPassId != QSSGResourceId::Invalid)
120 extResult = data.getRenderResult(userPassId, attachmentSelector);
121
122 if (userPassId != QSSGResourceId::Invalid) {
123 if (extResult.texture) {
124 QSSGRenderExtensionHelpers::registerRenderResult(data, m_extensionId, extResult.texture);
125 m_isDirty = false;
126 }
127 }
128}
129
131{
132 // Nothing to render
133}
134
136{
137 // Nothing to reset
138}
139
140
141/*!
142 \qmltype RenderOutputProvider
143 \nativetype QQuick3DRenderOutputProvider
144 \inqmlmodule QtQuick3D.Helpers
145 \inherits TextureProviderExtension
146 \since 6.11
147 \brief Used as a bridge to access textures provided in passes.
148
149 This type is used to provide textures that are generated by passes in the rendering pipeline.
150
151 Some example of when this is useful is when you want to access the depth texture generated by the ZPrePass,
152 or the ambient occlusion texture generated by the SSAO pass. This type can be used to access these generated
153 textures and use them in materials or effects.
154
155 \qml
156 Texture {
157 textureProvider: RenderOutputProvider {
158 // Specify the pass buffer texture you want to access
159 textureSource: RenderOutputProvider.DepthTexture
160 }
161 }
162 \endqml
163
164 \sa QQuick3DTextureProviderExtension, QSSGRenderExtension
165*/
166
167QQuick3DRenderOutputProvider::QQuick3DRenderOutputProvider(QQuick3DObject *parent)
168 : QQuick3DTextureProviderExtension(parent)
169{
170 update();
171}
172
173QSSGRenderGraphObject *QQuick3DRenderOutputProvider::updateSpatialNode(QSSGRenderGraphObject *node)
174{
175 // Create new node if needed
176 if (!node)
177 node = new QSSGRenderOutputProviderExtension(this);
178
179 QQuick3DTextureProviderExtension::updateSpatialNode(node);
180
181 QSSGRenderOutputProviderExtension *providerNode = static_cast<QSSGRenderOutputProviderExtension *>(node);
182
183 providerNode->m_isDirty = (m_dirtyAttributes != 0);
184
185 if (m_dirtyAttributes & TextureSourceDirty) {
186 switch (m_textureSource) {
187 case QQuick3DRenderOutputProvider::TextureSource::None:
188 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::None;
189 // m_builtInPass is not used in this case
190 break;
191 case QQuick3DRenderOutputProvider::TextureSource::UserPassTexture:
192 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::UserPass;
193 break;
194 case QQuick3DRenderOutputProvider::TextureSource::AoTexture:
195 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
196 providerNode->m_builtInPass = QSSGFrameData::RenderResult::AoTexture;
197 break;
198 case QQuick3DRenderOutputProvider::TextureSource::DepthTexture:
199 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
200 providerNode->m_builtInPass = QSSGFrameData::RenderResult::DepthTexture;
201 break;
202 case QQuick3DRenderOutputProvider::TextureSource::ScreenTexture:
203 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
204 providerNode->m_builtInPass = QSSGFrameData::RenderResult::ScreenTexture;
205 break;
206 case QQuick3DRenderOutputProvider::TextureSource::NormalTexture:
207 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
208 providerNode->m_builtInPass = QSSGFrameData::RenderResult::NormalTexture;
209 break;
210 case QQuick3DRenderOutputProvider::TextureSource::MotionVectorTexture:
211 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
212 providerNode->m_builtInPass = QSSGFrameData::RenderResult::MotionVectorTexture;
213 break;
214 }
215 }
216
217 if (m_dirtyAttributes & UserPassTextureDirty) {
218 // m_builtInPass is not used in this case
219 QSSGResourceId userPassId = m_renderPass ? QQuick3DExtensionHelpers::getResourceId(*m_renderPass) : QSSGResourceId::Invalid;
220 providerNode->userPassId = userPassId;
221 providerNode->attachmentSelector = QSSGFrameData::AttachmentSelector(m_attachmentSelector);
222 }
223
224 m_dirtyAttributes = 0;
225
226 return node;
227}
228
229void QQuick3DRenderOutputProvider::markAllDirty()
230{
231 m_dirtyAttributes = AllDirty;
232 QQuick3DTextureProviderExtension::markAllDirty();
233}
234
235void QQuick3DRenderOutputProvider::markDirty(QQuick3DRenderOutputProvider::DirtyType type)
236{
237 if (!(m_dirtyAttributes & quint32(type))) {
238 m_dirtyAttributes |= quint32(type);
239 update();
240 }
241}
242
243/*!
244 \qmlproperty enumeration RenderOutputProvider::textureSource
245 This property holds which pass buffer texture to expose.
246
247 \value RenderOutputProvider.None No texture source is selected.
248 \value RenderOutputProvider.UserPassTexture Accesses a color attachment from a user-defined
249 \l RenderPass. Use the \l renderPass and \l attachmentSelector properties to specify
250 which pass and attachment to use.
251 \value RenderOutputProvider.AoTexture The ambient occlusion texture created by QtQuick3D's SSAO pass.
252 \value RenderOutputProvider.DepthTexture The depth texture created by QtQuick3D's depth pre-pass.
253 \value RenderOutputProvider.ScreenTexture The texture containing the rendered scene.
254 \value RenderOutputProvider.NormalTexture The world-space normal texture created by QtQuick3D's normal pre-pass.
255 \value RenderOutputProvider.MotionVectorTexture The motion vector texture created by QtQuick3D's motion vector pass.
256 */
257
258QQuick3DRenderOutputProvider::TextureSource QQuick3DRenderOutputProvider::textureSource() const
259{
260 return m_textureSource;
261}
262
263void QQuick3DRenderOutputProvider::setTextureSource(TextureSource newTextureSource)
264{
265 if (m_textureSource == newTextureSource)
266 return;
267 m_textureSource = newTextureSource;
268 emit textureSourceChanged();
269 markDirty(TextureSourceDirty);
270}
271
272/*!
273 \qmlproperty RenderPass RenderOutputProvider::renderPass
274 The \l RenderPass whose output attachments will be exposed as a texture. Setting this
275 property automatically sets \l textureSource to \c UserPassTexture. Use
276 \l attachmentSelector to choose which color attachment of the pass to expose.
277
278 \sa attachmentSelector, textureSource, RenderPass
279*/
280
281QQuick3DRenderPass *QQuick3DRenderOutputProvider::renderPass() const
282{
283 return m_renderPass;
284}
285
286void QQuick3DRenderOutputProvider::setRenderPass(QQuick3DRenderPass *newRenderPass)
287{
288 if (m_renderPass == newRenderPass)
289 return;
290
291 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DRenderOutputProvider::setRenderPass, newRenderPass, m_renderPass);
292
293 m_renderPass = newRenderPass;
294
295 setTextureSource(m_renderPass ? TextureSource::UserPassTexture : TextureSource::None);
296
297 markDirty(UserPassTextureDirty);
298
299 emit renderPassChanged();
300}
301
302/*!
303 \qmlproperty enumeration RenderOutputProvider::attachmentSelector
304 Selects which color attachment of the user-defined \l RenderPass to expose as a texture.
305 Only relevant when \l textureSource is set to \c UserPassTexture.
306
307 \value RenderOutputProvider.Attachment0 Use color attachment 0 (default).
308 \value RenderOutputProvider.Attachment1 Use color attachment 1.
309 \value RenderOutputProvider.Attachment2 Use color attachment 2.
310 \value RenderOutputProvider.Attachment3 Use color attachment 3.
311
312 \sa renderPass, textureSource
313*/
314
315QQuick3DRenderOutputProvider::AttachmentSelector QQuick3DRenderOutputProvider::attachmentSelector() const
316{
317 return m_attachmentSelector;
318}
319
320void QQuick3DRenderOutputProvider::setAttachmentSelector(AttachmentSelector newAttachmentSelector)
321{
322 if (m_attachmentSelector == newAttachmentSelector)
323 return;
324 m_attachmentSelector = newAttachmentSelector;
325 emit attachmentSelectorChanged();
326}
327
328QT_END_NAMESPACE
QSSGFrameData::AttachmentSelector attachmentSelector
QSSGRenderOutputProviderExtension(QQuick3DRenderOutputProvider *ext)
void prepareRender(QSSGFrameData &data) override
Prepare data for rendering.
bool prepareData(QSSGFrameData &data) override
Called after scene data is collected, but before any render data or rendering in the current frame ha...
QPointer< QQuick3DRenderOutputProvider > m_ext
void render(QSSGFrameData &data) override
Record the render pass.
void resetForFrame() override
Called each time a new frame starts.
Combined button and popup list for selecting options.