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
qssgrenderuserpass.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#include <QtQuick3DRuntimeRender/private/qssgrendercommands_p.h>
8
9#include <QtCore/qregularexpression.h>
10
11#include <ssg/qssgrendercontextcore.h>
12
14
15Q_STATIC_LOGGING_CATEGORY(lcRenderUserPass, "qt.quick3d.runtimerender.renderuserpass")
16
17static const QHash<const char*, const char*> AugmentMacros = {
18 { "BASE_COLOR", "qt_diffuseColor" },
19 { "ROUGHNESS", "qt_roughnessAmount" },
20 { "METALNESS", "qt_metalnessAmount" },
21 { "DIFFUSE_LIGHT", "global_diffuse_light.rgb" },
22 { "SPECULAR_LIGHT", "global_specular_light" },
23 { "EMISSIVE_LIGHT", "global_emission" },
24 { "WORLD_NORMAL", "qt_world_normal" },
25 { "WORLD_TANGENT", "qt_world_tangent" },
26 { "WORLD_BINORMAL", "qt_world_binormal" },
27 { "F0", "qt_f0" },
28 { "F90", "qt_f90" }
29};
30
31// NOTE: While this class doesn't have graphics resources itself, it manages commands that do!
32QSSGRenderUserPass::QSSGRenderUserPass()
33 : QSSGRenderGraphObject(Type::RenderPass, FlagT(Flags::HasGraphicsResources))
34{
35
36}
37
38QSSGRenderUserPass::~QSSGRenderUserPass()
39{
40 resetCommands();
41}
42
43bool QSSGRenderUserPass::isDirty(DirtyFlag flag) const
44{
45 return (flags & FlagT(flag)) != 0;
46}
47
48void QSSGRenderUserPass::markDirty(DirtyFlag flag)
49{
50 flags |= FlagT(flag);
51}
52
53void QSSGRenderUserPass::clearDirty(DirtyFlag flag)
54{
55 flags &= ~FlagT(flag);
56}
57
58QByteArray replaceAugmentMacros(const QByteArray &shaderCode)
59{
60 QString modifiedCode = QString::fromUtf8(shaderCode);
61 for (auto it = AugmentMacros.constBegin(); it != AugmentMacros.constEnd(); ++it) {
62 QString pattern = QStringLiteral("\\b%1\\b").arg(QRegularExpression::escape(QString::fromUtf8(it.key())));
63 QRegularExpression regex(pattern);
64 modifiedCode.replace(regex, QString::fromUtf8(it.value()));
65 }
66 return modifiedCode.toUtf8();
67}
68
69void QSSGRenderUserPass::finalizeShaders(const QSSGRenderContextInterface &ctx)
70{
71 Q_UNUSED(ctx);
72
73 if (materialMode != AugmentMaterial)
74 return;
75
76 if (!isDirty(DirtyFlag::ShaderDirty))
77 return;
78
79 clearDirty(DirtyFlag::ShaderDirty);
80
81 const bool hasShaderCode = (shaderAugmentation.hasUserAugmentation());
82
83 if (hasShaderCode) {
84 qCDebug(lcRenderUserPass) << "Finalizing shaders for user pass with augment shader code.";
85
86 // Replace any instances of the AugmentMacros with the appropriate built-in variable names
87 shaderAugmentation.preamble = replaceAugmentMacros(shaderAugmentation.preamble);
88 shaderAugmentation.body = replaceAugmentMacros(shaderAugmentation.body);
89
90 // Check if body needs certain features
91 shaderAugmentation.needsBaseColor = shaderAugmentation.body.contains(AugmentMacros["BASE_COLOR"]);
92 shaderAugmentation.needsRoughness = shaderAugmentation.body.contains(AugmentMacros["ROUGHNESS"]);
93 shaderAugmentation.needsMetalness = shaderAugmentation.body.contains(AugmentMacros["METALNESS"]);
94 shaderAugmentation.needsDiffuseLight = shaderAugmentation.body.contains(AugmentMacros["DIFFUSE_LIGHT"]);
95 shaderAugmentation.needsSpecularLight = shaderAugmentation.body.contains(AugmentMacros["SPECULAR_LIGHT"]);
96 shaderAugmentation.needsEmissiveLight = shaderAugmentation.body.contains(AugmentMacros["EMISSIVE_LIGHT"]);
97 shaderAugmentation.needsWorldNormal = shaderAugmentation.body.contains(AugmentMacros["WORLD_NORMAL"]);
98 shaderAugmentation.needsWorldTangent = shaderAugmentation.body.contains(AugmentMacros["WORLD_TANGENT"]);
99 shaderAugmentation.needsWorldBinormal = shaderAugmentation.body.contains(AugmentMacros["WORLD_BINORMAL"]);
100 shaderAugmentation.needsF0 = shaderAugmentation.body.contains(AugmentMacros["F0"]);
101 shaderAugmentation.needsF90 = shaderAugmentation.body.contains(AugmentMacros["F90"]);
102
103 m_state = State::Ready;
104
105 } else {
106 m_state = State::Error;
107
108 qWarning() << "No augment shader code provided for user pass.";
109 }
110
111 // Finalize shaders for all commands
112 qCDebug(lcRenderUserPass) << "Finalizing shaders for user pass commands";
113}
114
115void QSSGRenderUserPass::setDependencyIndex(quint32 index)
116{
117 m_dependencyIndex = index;
118}
119
120void QSSGRenderUserPass::resetCommands()
121{
122 qDeleteAll(commands);
123 commands.clear();
124}
125
126QT_END_NAMESPACE
Combined button and popup list for selecting options.
QByteArray replaceAugmentMacros(const QByteArray &shaderCode)