1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Quick 3D.
7 **
8 ** $QT_BEGIN_LICENSE:GPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 or (at your option) any later version
20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 ** included in the packaging of this file. Please review the following
23 ** information to ensure the GNU General Public License requirements will
24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 **
26 ** $QT_END_LICENSE$
27 **
28 ****************************************************************************/
29 
30 #ifndef QSSGPRINCIPLEDMATERIAL_H
31 #define QSSGPRINCIPLEDMATERIAL_H
32 
33 //
34 //  W A R N I N G
35 //  -------------
36 //
37 // This file is not part of the Qt API.  It exists purely as an
38 // implementation detail.  This header file may change from version to
39 // version without notice, or even be removed.
40 //
41 // We mean it.
42 //
43 
44 #include <QtQuick3D/private/qquick3dmaterial_p.h>
45 #include <QtQuick3D/private/qquick3dtexture_p.h>
46 
47 #include <QColor>
48 #include <QHash>
49 
50 QT_BEGIN_NAMESPACE
51 
52 class Q_QUICK3D_EXPORT QQuick3DPrincipledMaterial : public QQuick3DMaterial
53 {
54     Q_OBJECT
55     Q_PROPERTY(Lighting lighting READ lighting WRITE setLighting NOTIFY lightingChanged)
56     Q_PROPERTY(BlendMode blendMode READ blendMode WRITE setBlendMode NOTIFY blendModeChanged)
57 
58     Q_PROPERTY(QColor baseColor READ baseColor WRITE setBaseColor NOTIFY baseColorChanged)
59     Q_PROPERTY(QQuick3DTexture *baseColorMap READ baseColorMap WRITE setBaseColorMap NOTIFY baseColorMapChanged)
60 
61     Q_PROPERTY(float metalness READ metalness WRITE setMetalness NOTIFY metalnessChanged)
62     Q_PROPERTY(QQuick3DTexture *metalnessMap READ metalnessMap WRITE setMetalnessMap NOTIFY metalnessMapChanged)
63     Q_PROPERTY(TextureChannelMapping metalnessChannel READ metalnessChannel WRITE setMetalnessChannel NOTIFY metalnessChannelChanged REVISION 1)
64 
65     Q_PROPERTY(float specularAmount READ specularAmount WRITE setSpecularAmount NOTIFY specularAmountChanged)
66     Q_PROPERTY(QQuick3DTexture *specularMap READ specularMap WRITE setSpecularMap NOTIFY specularMapChanged)
67     Q_PROPERTY(float specularTint READ specularTint WRITE setSpecularTint NOTIFY specularTintChanged)
68 
69     Q_PROPERTY(float roughness READ roughness WRITE setRoughness NOTIFY roughnessChanged)
70     Q_PROPERTY(QQuick3DTexture *roughnessMap READ roughnessMap WRITE setRoughnessMap NOTIFY roughnessMapChanged)
71     Q_PROPERTY(TextureChannelMapping roughnessChannel READ roughnessChannel WRITE setRoughnessChannel NOTIFY roughnessChannelChanged REVISION 1)
72 
73     Q_PROPERTY(float indexOfRefraction READ indexOfRefraction WRITE setIndexOfRefraction NOTIFY indexOfRefractionChanged)
74 
75     Q_PROPERTY(QColor emissiveColor READ emissiveColor WRITE setEmissiveColor NOTIFY emissiveColorChanged)
76     Q_PROPERTY(QQuick3DTexture *emissiveMap READ emissiveMap WRITE setEmissiveMap NOTIFY emissiveMapChanged)
77 
78     Q_PROPERTY(float opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
79     Q_PROPERTY(QQuick3DTexture *opacityMap READ opacityMap WRITE setOpacityMap NOTIFY opacityMapChanged)
80     Q_PROPERTY(TextureChannelMapping opacityChannel READ opacityChannel WRITE setOpacityChannel NOTIFY opacityChannelChanged REVISION 1)
81 
82     Q_PROPERTY(QQuick3DTexture *normalMap READ normalMap WRITE setNormalMap NOTIFY normalMapChanged)
83     Q_PROPERTY(float normalStrength READ normalStrength WRITE setNormalStrength NOTIFY normalStrengthChanged)
84 
85     Q_PROPERTY(QQuick3DTexture *specularReflectionMap READ specularReflectionMap WRITE setSpecularReflectionMap NOTIFY specularReflectionMapChanged)
86 
87     Q_PROPERTY(QQuick3DTexture *occlusionMap READ occlusionMap WRITE setOcclusionMap NOTIFY occlusionMapChanged)
88     Q_PROPERTY(TextureChannelMapping occlusionChannel READ occlusionChannel WRITE setOcclusionChannel NOTIFY occlusionChannelChanged REVISION 1)
89     Q_PROPERTY(float occlusionAmount READ occlusionAmount WRITE setOcclusionAmount NOTIFY occlusionAmountChanged)
90 
91     Q_PROPERTY(AlphaMode alphaMode READ alphaMode WRITE setAlphaMode NOTIFY alphaModeChanged)
92     Q_PROPERTY(float alphaCutoff READ alphaCutoff WRITE setAlphaCutoff NOTIFY alphaCutoffChanged)
93 
94 public:
95     enum Lighting {
96         NoLighting = 0,
97         FragmentLighting
98     };
99     Q_ENUM(Lighting)
100 
101     enum BlendMode {
102         SourceOver = 0,
103         Screen,
104         Multiply,
105         Overlay,
106         ColorBurn,
107         ColorDodge
108     };
109     Q_ENUM(BlendMode)
110 
111     enum AlphaMode {
112         Opaque = 0,
113         Mask,
114         Blend
115     };
116     Q_ENUM(AlphaMode)
117 
118     explicit QQuick3DPrincipledMaterial(QQuick3DObject *parent = nullptr);
119     ~QQuick3DPrincipledMaterial() override;
120 
121     Lighting lighting() const;
122     BlendMode blendMode() const;
123     QColor baseColor() const;
124     QQuick3DTexture *baseColorMap() const;
125     QQuick3DTexture *emissiveMap() const;
126     QColor emissiveColor() const;
127     QQuick3DTexture *specularReflectionMap() const;
128     QQuick3DTexture *specularMap() const;
129     float specularTint() const;
130     float indexOfRefraction() const;
131     float specularAmount() const;
132     float roughness() const;
133     QQuick3DTexture *roughnessMap() const;
134     float opacity() const;
135     QQuick3DTexture *opacityMap() const;
136     QQuick3DTexture *normalMap() const;
137     float metalness() const;
138     QQuick3DTexture *metalnessMap() const;
139     float normalStrength() const;
140     QQuick3DTexture *occlusionMap() const;
141     float occlusionAmount() const;
142     AlphaMode alphaMode() const;
143     float alphaCutoff() const;
144     Q_REVISION(1) TextureChannelMapping metalnessChannel() const;
145     Q_REVISION(1) TextureChannelMapping roughnessChannel() const;
146     Q_REVISION(1) TextureChannelMapping opacityChannel() const;
147     Q_REVISION(1) TextureChannelMapping occlusionChannel() const;
148 
149 public Q_SLOTS:
150     void setLighting(Lighting lighting);
151     void setBlendMode(BlendMode blendMode);
152     void setBaseColor(QColor baseColor);
153     void setBaseColorMap(QQuick3DTexture *baseColorMap);
154     void setEmissiveMap(QQuick3DTexture *emissiveMap);
155     void setEmissiveColor(QColor emissiveColor);
156     void setSpecularReflectionMap(QQuick3DTexture *specularReflectionMap);
157     void setSpecularMap(QQuick3DTexture *specularMap);
158     void setSpecularTint(float specularTint);
159     void setIndexOfRefraction(float indexOfRefraction);
160     void setSpecularAmount(float specularAmount);
161     void setRoughness(float roughness);
162     void setRoughnessMap(QQuick3DTexture *roughnessMap);
163     void setOpacity(float opacity);
164     void setOpacityMap(QQuick3DTexture *opacityMap);
165     void setNormalMap(QQuick3DTexture *normalMap);
166     void setMetalness(float metalnessAmount);
167     void setMetalnessMap(QQuick3DTexture * metalnessMap);
168     void setNormalStrength(float normalStrength);
169     void setOcclusionMap(QQuick3DTexture *occlusionMap);
170     void setOcclusionAmount(float occlusionAmount);
171     void setAlphaMode(AlphaMode alphaMode);
172     void setAlphaCutoff(float alphaCutoff);
173     Q_REVISION(1) void setMetalnessChannel(TextureChannelMapping channel);
174     Q_REVISION(1) void setRoughnessChannel(TextureChannelMapping channel);
175     Q_REVISION(1) void setOpacityChannel(TextureChannelMapping channel);
176     Q_REVISION(1) void setOcclusionChannel(TextureChannelMapping channel);
177 
178 Q_SIGNALS:
179     void lightingChanged(Lighting lighting);
180     void blendModeChanged(BlendMode blendMode);
181     void baseColorChanged(QColor baseColor);
182     void baseColorMapChanged(QQuick3DTexture *baseColorMap);
183     void emissiveMapChanged(QQuick3DTexture *emissiveMap);
184     void emissiveColorChanged(QColor emissiveColor);
185     void specularReflectionMapChanged(QQuick3DTexture *specularReflectionMap);
186     void specularMapChanged(QQuick3DTexture *specularMap);
187     void specularTintChanged(float specularTint);
188     void indexOfRefractionChanged(float indexOfRefraction);
189     void specularAmountChanged(float specularAmount);
190     void roughnessChanged(float roughness);
191     void roughnessMapChanged(QQuick3DTexture *roughnessMap);
192     void opacityChanged(float opacity);
193     void opacityMapChanged(QQuick3DTexture *opacityMap);
194     void normalMapChanged(QQuick3DTexture *normalMap);
195     void metalnessChanged(float metalness);
196     void metalnessMapChanged(QQuick3DTexture * metalnessMap);
197     void normalStrengthChanged(float normalStrength);
198     void occlusionMapChanged(QQuick3DTexture *occlusionMap);
199     void occlusionAmountChanged(float occlusionAmount);
200     void alphaModeChanged(AlphaMode alphaMode);
201     void alphaCutoffChanged(float alphaCutoff);
202     Q_REVISION(1) void metalnessChannelChanged(TextureChannelMapping channel);
203     Q_REVISION(1) void roughnessChannelChanged(TextureChannelMapping channel);
204     Q_REVISION(1) void opacityChannelChanged(TextureChannelMapping channel);
205     Q_REVISION(1) void occlusionChannelChanged(TextureChannelMapping channel);
206 
207 protected:
208     QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
209     void markAllDirty() override;
210     void itemChange(ItemChange, const ItemChangeData &) override;
211 private:
212     using ConnectionMap = QHash<QByteArray, QMetaObject::Connection>;
213 
214     enum DirtyType {
215         LightingModeDirty = 0x00000001,
216         BlendModeDirty = 0x00000002,
217         BaseColorDirty = 0x00000004,
218         EmissiveDirty = 0x00000008,
219         SpecularDirty = 0x00000010,
220         OpacityDirty = 0x00000020,
221         NormalDirty = 0x00000040,
222         MetalnessDirty = 0x00000080,
223         RoughnessDirty = 0x00000100,
224         OcclusionDirty = 0x00000200,
225         AlphaModeDirty = 0x00000400,
226         IorDirty = 0x00000800
227     };
228 
229     void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &window);
230     Lighting m_lighting = FragmentLighting;
231     BlendMode m_blendMode = SourceOver;
232     AlphaMode m_alphaMode = Opaque;
233     QColor m_baseColor = Qt::white;
234     QQuick3DTexture *m_baseColorMap = nullptr;
235     QQuick3DTexture *m_emissiveMap = nullptr;
236     ConnectionMap m_connections;
237 
238     QColor m_emissiveColor = Qt::black;
239     QQuick3DTexture *m_specularReflectionMap = nullptr;
240     QQuick3DTexture *m_specularMap = nullptr;
241     QQuick3DTexture *m_roughnessMap = nullptr;
242     QQuick3DTexture *m_opacityMap = nullptr;
243     QQuick3DTexture *m_normalMap = nullptr;
244     QQuick3DTexture *m_metalnessMap = nullptr;
245     QQuick3DTexture* m_occlusionMap = nullptr;
246     float m_emissivePower = 0.0f;
247     float m_specularTint = 0.0f;
248     float m_indexOfRefraction = 1.45f;
249     float m_specularAmount = 0.0f;
250     float m_roughness = 0.0f;
251     float m_opacity = 1.0f;
252     float m_metalnessAmount = 1.0f;
253     float m_normalStrength = 1.0f;
254     float m_occlusionAmount = 1.0f;
255     float m_alphaCutoff = 0.5f;
256     TextureChannelMapping m_metalnessChannel = QQuick3DMaterial::B;
257     TextureChannelMapping m_roughnessChannel = QQuick3DMaterial::G;
258     TextureChannelMapping m_opacityChannel = QQuick3DMaterial::A;
259     TextureChannelMapping m_occlusionChannel = QQuick3DMaterial::R;
260 
261     quint32 m_dirtyAttributes = 0xffffffff; // all dirty by default
262     void markDirty(DirtyType type);
263 };
264 
265 QT_END_NAMESPACE
266 
267 #endif // QSSGPRINCIPLEDMATERIAL_H
268