QGIS API Documentation 4.1.0-Master (3fcefe620d1)
Loading...
Searching...
No Matches
qgsmetalroughtexturedmaterial3dhandler.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmetalroughtexturedmaterial3dhandler.cpp
3 --------------------------------------
4 Date : April 2026
5 Copyright : (C) 2026 by Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgs3dutils.h"
19#include "qgsapplication.h"
21#include "qgsimagecache.h"
22#include "qgsimagetexture.h"
25
26#include <QString>
27#include <Qt3DCore/QEntity>
28#include <Qt3DRender/QEffect>
29#include <Qt3DRender/QGraphicsApiFilter>
30#include <Qt3DRender/QPaintedTextureImage>
31#include <Qt3DRender/QParameter>
32#include <Qt3DRender/QTechnique>
33#include <Qt3DRender/QTexture>
34
35using namespace Qt::StringLiterals;
36
38{
39 const QgsMetalRoughTexturedMaterialSettings *texturedSettings = dynamic_cast< const QgsMetalRoughTexturedMaterialSettings * >( settings );
40 Q_ASSERT( texturedSettings );
41
42 switch ( technique )
43 {
45 {
46 Q_ASSERT( false );
47 return nullptr;
48 }
51 {
52 if ( context.isHighlighted() )
53 {
54 return new QgsHighlightMaterial();
55 }
56
57 QgsMetalRoughMaterial *material = new QgsMetalRoughMaterial( nullptr );
58 material->setEnvironmentalLightingEnabled( !context.isPreview() );
59 material->setObjectName( u"metalRoughTexturedMaterial"_s );
60 applySettingsToMaterial( texturedSettings, material, context );
61
62 return material;
63 }
64
65 default:
66 return nullptr;
67 }
68}
69
71 const QgsAbstractMaterialSettings *settings, const QgsMaterialContext &context, Qgis::InstancedMaterialFlags flags, const QMatrix4x4 &transform
72) const
73{
74 const QgsMetalRoughTexturedMaterialSettings *texturedSettings = qgis::down_cast< const QgsMetalRoughTexturedMaterialSettings * >( settings );
75
76 QgsMetalRoughMaterial *material = new QgsMetalRoughMaterial();
77 material->setEnvironmentalLightingEnabled( true );
78 material->setInstancingEnabled( true, flags );
79 material->setInstancingMeshTransform( transform );
80
81 material->setObjectName( u"metalRoughTexturedMaterial"_s );
82 applySettingsToMaterial( texturedSettings, material, context );
83
84 return material;
85}
86
88{
89 QMap<QString, QString> parameters;
90 return parameters;
91}
92
93bool QgsMetalRoughTexturedMaterial3DHandler::updatePreviewScene( Qt3DCore::QEntity *sceneRoot, const QgsAbstractMaterialSettings *settings, const QgsMaterialContext &context ) const
94{
95 const QgsMetalRoughTexturedMaterialSettings *metalRoughTexturedSettings = qgis::down_cast< const QgsMetalRoughTexturedMaterialSettings * >( settings );
96
97 QgsMetalRoughMaterial *material = sceneRoot->findChild<QgsMetalRoughMaterial *>();
98 if ( !material || material->objectName() != "metalRoughTexturedMaterial"_L1 )
99 return false;
100
101 applySettingsToMaterial( metalRoughTexturedSettings, material, context );
102 return true;
103}
104
105Qt3DRender::QTexture2D *QgsMetalRoughTexturedMaterial3DHandler::loadTexture( const QString &path, bool isSrgb, const QgsMaterialContext &context )
106{
107 if ( path.isEmpty() )
108 return nullptr;
109
110 bool fitsInCache = false;
111 QImage image = QgsApplication::imageCache()->pathAsImage( path, QSize(), true, 1.0, fitsInCache );
112 if ( image.isNull() )
113 return nullptr;
114
115 Qt3DRender::QTexture2D *texture = new Qt3DRender::QTexture2D();
116
117 if ( isSrgb )
118 {
119 texture->setFormat( Qt3DRender::QAbstractTexture::SRGB8_Alpha8 );
120 }
121 else
122 {
123 texture->setFormat( Qt3DRender::QAbstractTexture::RGBA8_UNorm );
124 }
125
126 texture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::Repeat );
127 texture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::Repeat );
128 Qgs3DUtils::setTextureFiltering( texture, context );
129
130 // texture takes ownership of textureImage
131 texture->addTextureImage( new QgsImageTexture( image ) );
132
133 return texture;
134}
135
136void QgsMetalRoughTexturedMaterial3DHandler::applySettingsToMaterial( const QgsMetalRoughTexturedMaterialSettings *texturedSettings, QgsMetalRoughMaterial *material, const QgsMaterialContext &context )
137{
138 material->setTextureScale( static_cast<float>( texturedSettings->textureScale() ) );
139 material->setTextureRotation( static_cast<float>( texturedSettings->textureRotation() ) );
140 material->setTextureOffset( static_cast<float>( texturedSettings->textureOffset().x() ), static_cast<float>( texturedSettings->textureOffset().y() ) );
141
142 // base color
143 if ( Qt3DRender::QTexture2D *baseTex = loadTexture( texturedSettings->baseColorTexturePath(), true, context ) )
144 {
145 // takes ownership of texture
146 material->setBaseColorTexture( baseTex );
147 }
148 else
149 {
150 // fallback to default solid color if no texture specified
151 material->setBaseColor( QColor( "grey" ) );
152 }
153
154 // metalness
155 if ( Qt3DRender::QTexture2D *metalTex = loadTexture( texturedSettings->metalnessTexturePath(), false, context ) )
156 {
157 // takes ownership of texture
158 material->setMetalnessTexture( metalTex );
159 }
160 else
161 {
162 // fallback to constant default value if no texture specified
163 material->setMetalness( 0.0 );
164 }
165
166 // roughness
167 if ( Qt3DRender::QTexture2D *roughTex = loadTexture( texturedSettings->roughnessTexturePath(), false, context ) )
168 {
169 // takes ownership of texture
170 material->setRoughnessTexture( roughTex );
171 }
172 else
173 {
174 // fallback to constant default value if no texture specified
175 material->setRoughness( 0.5 );
176 }
177
178 if ( Qt3DRender::QTexture2D *normalTex = loadTexture( texturedSettings->normalTexturePath(), false, context ) )
179 {
180 // takes ownership of texture
181 material->setNormalTexture( normalTex );
182 }
183 else
184 {
185 // default to none
186 material->setNormalTexture( nullptr );
187 }
188
189 if ( Qt3DRender::QTexture2D *heightTex = loadTexture( texturedSettings->heightTexturePath(), false, context ) )
190 {
191 material->setHeightTexture( heightTex );
192 }
193 else
194 {
195 // default to none
196 material->setHeightTexture( nullptr );
197 }
198 material->setParallaxScale( texturedSettings->parallaxScale() );
199
200 // ambient occlusion
201 if ( Qt3DRender::QTexture2D *aoTex = loadTexture( texturedSettings->ambientOcclusionTexturePath(), false, context ) )
202 {
203 // takes ownership of texture
204 material->setAmbientOcclusionTexture( aoTex );
205 }
206 else
207 {
208 // default to none
209 material->setAmbientOcclusionTexture( nullptr );
210 }
211
212 if ( Qt3DRender::QTexture2D *emissionTex = loadTexture( texturedSettings->emissionTexturePath(), true, context ) )
213 {
214 material->setEmissionTexture( emissionTex );
215 }
216 else
217 {
218 // default to none
219 material->setEmissionTexture( nullptr );
220 }
221
222 material->setEmissionFactor( texturedSettings->emissionFactor() );
223 material->setOpacity( static_cast< float >( texturedSettings->opacity() ) );
224
225 const QgsPropertyCollection ddProps = texturedSettings->dataDefinedProperties();
226 const bool hasDDTextureTransform = ddProps.isActive( QgsAbstractMaterialSettings::Property::TextureOffset )
229 material->setDataDefinedTextureTransformEnabled( hasDDTextureTransform );
230};
MaterialRenderingTechnique
Material rendering techniques.
Definition qgis.h:4375
@ Triangles
Triangle based rendering (default).
Definition qgis.h:4376
@ TrianglesDataDefined
Triangle based rendering with possibility of datadefined color.
Definition qgis.h:4382
@ InstancedPoints
Instanced based rendering, requiring triangles and point data.
Definition qgis.h:4378
QFlags< InstancedMaterialFlag > InstancedMaterialFlags
Definition qgis.h:4398
static void setTextureFiltering(Qt3DRender::QAbstractTexture *texture, const QgsMaterialContext &context)
Sets the default filtering options for a texture.
Abstract base class for material settings.
QgsPropertyCollection dataDefinedProperties() const
Returns the symbol material property collection, used for data defined overrides.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
Context settings for a material.
bool isHighlighted() const
Returns true if the material should represent a highlighted state.
bool isPreview() const
Returns true if the material is being shown in a preview widget.
Base class for all materials used within QGIS 3D views.
Definition qgsmaterial.h:40
bool updatePreviewScene(Qt3DCore::QEntity *sceneRoot, const QgsAbstractMaterialSettings *settings, const QgsMaterialContext &context) const override
Updates an existing material preview scene with new material settings.
QMap< QString, QString > toExportParameters(const QgsAbstractMaterialSettings *settings) const override
Returns the parameters to be exported to .mtl file.
QgsMaterial * toMaterial(const QgsAbstractMaterialSettings *settings, Qgis::MaterialRenderingTechnique technique, const QgsMaterialContext &context) const override
Creates a new QgsMaterial object representing the material settings.
QgsMaterial * toInstancedMaterial(const QgsAbstractMaterialSettings *settings, const QgsMaterialContext &context, Qgis::InstancedMaterialFlags flags, const QMatrix4x4 &transform=QMatrix4x4()) const override
Creates a QgsMaterial for instanced point rendering.
A PBR metal rough shading material used for rendering with support for image texture maps.
double emissionFactor() const
Returns the emission factor, which dictates the strength of the emission effect.
QString roughnessTexturePath() const
Returns the path to the roughness texture map.
double textureRotation() const
Returns the texture rotation, in degrees.
double textureScale() const
Returns the texture scale.
double opacity() const
Returns the opacity of the surface.
QPointF textureOffset() const
Returns the texture offset.
QString normalTexturePath() const
Returns the path to the normal texture map.
QString ambientOcclusionTexturePath() const
Returns the path to the ambient occlusion texture map.
QString metalnessTexturePath() const
Returns the path to the metalness texture map.
QString baseColorTexturePath() const
Returns the path to the base color texture map.
QString heightTexturePath() const
Returns the path to the height texture map.
QString emissionTexturePath() const
Returns the path to the emission/luminosity texture map.
double parallaxScale() const
Returns the parallax scale, which dictates the strength of the height displacement effect.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.