21#include <Qt3DRender/QAbstractTexture>
22#include <Qt3DRender/QGraphicsApiFilter>
23#include <Qt3DRender/QParameter>
24#include <Qt3DRender/QRenderPass>
25#include <Qt3DRender/QSeamlessCubemap>
26#include <Qt3DRender/QShaderProgramBuilder>
27#include <Qt3DRender/QTechnique>
28#include <Qt3DRender/QTexture>
30#include "moc_qgsmetalroughmaterial.cpp"
32using namespace Qt::StringLiterals;
35QgsMetalRoughMaterial::QgsMetalRoughMaterial( QNode *parent )
37 , mBaseColorParameter( new
Qt3DRender::QParameter( u
"baseColor"_s,
Qgs3DUtils::srgbToLinear( QColor(
"grey" ) ), this ) )
38 , mMetalnessParameter( new
Qt3DRender::QParameter( u
"metalness"_s, 0.0f, this ) )
39 , mRoughnessParameter( new
Qt3DRender::QParameter( u
"roughness"_s, 0.0f, this ) )
40 , mBaseColorMapParameter( new
Qt3DRender::QParameter( u
"baseColorMap"_s, QVariant(), this ) )
41 , mMetalnessMapParameter( new
Qt3DRender::QParameter( u
"metalnessMap"_s, QVariant(), this ) )
42 , mRoughnessMapParameter( new
Qt3DRender::QParameter( u
"roughnessMap"_s, QVariant(), this ) )
43 , mAmbientOcclusionMapParameter( new
Qt3DRender::QParameter( u
"ambientOcclusionMap"_s, QVariant(), this ) )
44 , mNormalMapParameter( new
Qt3DRender::QParameter( u
"normalMap"_s, QVariant(), this ) )
45 , mHeightMapParameter( new
Qt3DRender::QParameter( u
"heightMap"_s, QVariant(), this ) )
46 , mParallaxScaleParameter( new
Qt3DRender::QParameter( u
"parallaxScale"_s, 0.1f, this ) )
47 , mEmissionMapParameter( new
Qt3DRender::QParameter( u
"emissionMap"_s, QVariant(), this ) )
48 , mEmissiveColorParameter( new
Qt3DRender::QParameter( u
"emissiveColor"_s,
Qgs3DUtils::srgbToLinear( QColor( 0, 0, 0 ) ), this ) )
49 , mEmissionFactorParameter( new
Qt3DRender::QParameter( u
"emissiveFactor"_s, 1.0f, this ) )
50 , mTextureScaleParameter( new
Qt3DRender::QParameter( u
"texCoordScale"_s, 1.0f, this ) )
51 , mTextureRotationParameter( new
Qt3DRender::QParameter( u
"texCoordRotation"_s, 0.0f, this ) )
52 , mOpacityParameter( new
Qt3DRender::QParameter( u
"opacity"_s, 1.0f ) )
53 , mMetalRoughEffect( new
Qt3DRender::QEffect( this ) )
54 , mMetalRoughGL3Technique( new
Qt3DRender::QTechnique( this ) )
55 , mMetalRoughGL3RenderPass( new
Qt3DRender::QRenderPass( this ) )
56 , mMetalRoughGL3Shader( new
Qt3DRender::QShaderProgram( this ) )
57 , mFilterKey( new
Qt3DRender::QFilterKey( this ) )
62QgsMetalRoughMaterial::~QgsMetalRoughMaterial() =
default;
64void QgsMetalRoughMaterial::setBaseColor(
const QColor &baseColor )
67 bool oldUsingBaseColorMap = mUsingBaseColorMap;
69 mUsingBaseColorMap =
false;
70 if ( mMetalRoughEffect->parameters().contains( mBaseColorMapParameter ) )
71 mMetalRoughEffect->removeParameter( mBaseColorMapParameter );
72 mMetalRoughEffect->addParameter( mBaseColorParameter );
74 if ( oldUsingBaseColorMap != mUsingBaseColorMap )
80void QgsMetalRoughMaterial::setBaseColorTexture( Qt3DRender::QAbstractTexture *baseColor )
82 mBaseColorMapParameter->setValue( QVariant::fromValue( baseColor ) );
83 bool oldUsingBaseColorMap = mUsingBaseColorMap;
85 mUsingBaseColorMap =
true;
86 mMetalRoughEffect->addParameter( mBaseColorMapParameter );
87 if ( mMetalRoughEffect->parameters().contains( mBaseColorParameter ) )
88 mMetalRoughEffect->removeParameter( mBaseColorParameter );
90 if ( oldUsingBaseColorMap != mUsingBaseColorMap )
96void QgsMetalRoughMaterial::setMetalness(
float metalness )
98 mMetalnessParameter->setValue( metalness );
99 bool oldUsingMetalnessMap = mUsingMetalnessMap;
101 mUsingMetalnessMap =
false;
102 if ( mMetalRoughEffect->parameters().contains( mMetalnessMapParameter ) )
103 mMetalRoughEffect->removeParameter( mMetalnessMapParameter );
104 mMetalRoughEffect->addParameter( mMetalnessParameter );
106 if ( oldUsingMetalnessMap != mUsingMetalnessMap )
112void QgsMetalRoughMaterial::setMetalnessTexture( Qt3DRender::QAbstractTexture *metalness )
114 mMetalnessMapParameter->setValue( QVariant::fromValue( metalness ) );
115 bool oldUsingMetalnessMap = mUsingMetalnessMap;
117 mUsingMetalnessMap =
true;
118 mMetalRoughEffect->addParameter( mMetalnessMapParameter );
119 if ( mMetalRoughEffect->parameters().contains( mMetalnessParameter ) )
120 mMetalRoughEffect->removeParameter( mMetalnessParameter );
122 if ( oldUsingMetalnessMap != mUsingMetalnessMap )
128void QgsMetalRoughMaterial::setRoughness(
float roughness )
130 mRoughnessParameter->setValue( roughness );
131 bool oldUsingRoughnessMap = mUsingRoughnessMap;
133 mUsingRoughnessMap =
false;
134 if ( mMetalRoughEffect->parameters().contains( mRoughnessMapParameter ) )
135 mMetalRoughEffect->removeParameter( mRoughnessMapParameter );
136 mMetalRoughEffect->addParameter( mRoughnessParameter );
138 if ( oldUsingRoughnessMap != mUsingRoughnessMap )
144void QgsMetalRoughMaterial::setRoughnessTexture( Qt3DRender::QAbstractTexture *roughness )
146 mRoughnessMapParameter->setValue( QVariant::fromValue( roughness ) );
147 bool oldUsingRoughnessMap = mUsingRoughnessMap;
149 mUsingRoughnessMap =
true;
150 mMetalRoughEffect->addParameter( mRoughnessMapParameter );
151 if ( mMetalRoughEffect->parameters().contains( mRoughnessParameter ) )
152 mMetalRoughEffect->removeParameter( mRoughnessParameter );
154 if ( oldUsingRoughnessMap != mUsingRoughnessMap )
160void QgsMetalRoughMaterial::setAmbientOcclusionTexture( Qt3DRender::QAbstractTexture *ambientOcclusion )
162 bool oldUsingAmbientOcclusionMap = mUsingAmbientOcclusionMap;
164 if ( ambientOcclusion )
166 mAmbientOcclusionMapParameter->setValue( QVariant::fromValue( ambientOcclusion ) );
167 mUsingAmbientOcclusionMap =
true;
168 mMetalRoughEffect->addParameter( mAmbientOcclusionMapParameter );
172 mAmbientOcclusionMapParameter->setValue( QVariant() );
173 mUsingAmbientOcclusionMap =
false;
174 if ( mMetalRoughEffect->parameters().contains( mAmbientOcclusionMapParameter ) )
175 mMetalRoughEffect->removeParameter( mAmbientOcclusionMapParameter );
178 if ( oldUsingAmbientOcclusionMap != mUsingAmbientOcclusionMap )
184void QgsMetalRoughMaterial::setNormalTexture( Qt3DRender::QAbstractTexture *normal )
186 bool oldUsingNormalMap = mUsingNormalMap;
190 mNormalMapParameter->setValue( QVariant::fromValue( normal ) );
191 mUsingNormalMap =
true;
192 mMetalRoughEffect->addParameter( mNormalMapParameter );
196 mNormalMapParameter->setValue( QVariant() );
197 mUsingNormalMap =
false;
198 if ( mMetalRoughEffect->parameters().contains( mNormalMapParameter ) )
199 mMetalRoughEffect->removeParameter( mNormalMapParameter );
202 if ( oldUsingNormalMap != mUsingNormalMap )
208void QgsMetalRoughMaterial::setHeightTexture( Qt3DRender::QAbstractTexture *height )
210 bool oldUsingHeightMap = mUsingHeightMap;
214 mHeightMapParameter->setValue( QVariant::fromValue( height ) );
215 mUsingHeightMap =
true;
216 mMetalRoughEffect->addParameter( mHeightMapParameter );
220 mHeightMapParameter->setValue( QVariant() );
221 mUsingHeightMap =
false;
222 if ( mMetalRoughEffect->parameters().contains( mHeightMapParameter ) )
223 mMetalRoughEffect->removeParameter( mHeightMapParameter );
226 if ( oldUsingHeightMap != mUsingHeightMap )
232void QgsMetalRoughMaterial::setParallaxScale(
double scale )
234 mParallaxScaleParameter->setValue( scale );
237void QgsMetalRoughMaterial::setEmissionColor(
const QColor &color )
240 const bool oldUsingEmissionMap = mUsingEmissionMap;
242 mUsingEmissionMap =
false;
243 if ( mMetalRoughEffect->parameters().contains( mEmissionMapParameter ) )
244 mMetalRoughEffect->removeParameter( mEmissionMapParameter );
245 mMetalRoughEffect->addParameter( mEmissiveColorParameter );
247 if ( oldUsingEmissionMap != mUsingEmissionMap )
253void QgsMetalRoughMaterial::setEmissionTexture( Qt3DRender::QAbstractTexture *emission )
255 const bool oldUsingEmissionMap = mUsingEmissionMap;
259 mEmissionMapParameter->setValue( QVariant::fromValue( emission ) );
260 mUsingEmissionMap =
true;
261 mMetalRoughEffect->addParameter( mEmissionMapParameter );
262 if ( mMetalRoughEffect->parameters().contains( mEmissiveColorParameter ) )
263 mMetalRoughEffect->removeParameter( mEmissiveColorParameter );
267 mEmissionMapParameter->setValue( QVariant() );
268 mUsingEmissionMap =
false;
269 if ( mMetalRoughEffect->parameters().contains( mEmissionMapParameter ) )
270 mMetalRoughEffect->removeParameter( mEmissionMapParameter );
271 mMetalRoughEffect->addParameter( mEmissiveColorParameter );
274 if ( oldUsingEmissionMap != mUsingEmissionMap )
280void QgsMetalRoughMaterial::setEmissionFactor(
double factor )
282 mEmissionFactorParameter->setValue( factor );
285void QgsMetalRoughMaterial::setTextureScale(
float textureScale )
287 mTextureScaleParameter->setValue( textureScale );
290void QgsMetalRoughMaterial::setTextureRotation(
float textureRotation )
292 mTextureRotationParameter->setValue( textureRotation );
295void QgsMetalRoughMaterial::init()
297 mMetalRoughGL3Technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
298 mMetalRoughGL3Technique->graphicsApiFilter()->setMajorVersion( 3 );
299 mMetalRoughGL3Technique->graphicsApiFilter()->setMinorVersion( 3 );
300 mMetalRoughGL3Technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
302 mFilterKey->setParent(
this );
303 mFilterKey->setName( u
"renderingStyle"_s );
304 mFilterKey->setValue( u
"forward"_s );
306 mMetalRoughGL3Technique->addFilterKey( mFilterKey );
307 mMetalRoughGL3RenderPass->setShaderProgram( mMetalRoughGL3Shader );
308 mMetalRoughGL3Technique->addRenderPass( mMetalRoughGL3RenderPass );
309 mMetalRoughEffect->addTechnique( mMetalRoughGL3Technique );
313 mMetalRoughGL3RenderPass->addRenderState(
new Qt3DRender::QSeamlessCubemap(
this ) );
316 mBaseColorMapParameter->setParent( mMetalRoughEffect );
317 mMetalnessMapParameter->setParent( mMetalRoughEffect );
318 mRoughnessMapParameter->setParent( mMetalRoughEffect );
319 mNormalMapParameter->setParent( mMetalRoughEffect );
320 mHeightMapParameter->setParent( mMetalRoughEffect );
321 mAmbientOcclusionMapParameter->setParent( mMetalRoughEffect );
322 mEmissionMapParameter->setParent( mMetalRoughEffect );
324 mMetalRoughEffect->addParameter( mBaseColorParameter );
325 mMetalRoughEffect->addParameter( mMetalnessParameter );
326 mMetalRoughEffect->addParameter( mRoughnessParameter );
327 mMetalRoughEffect->addParameter( mParallaxScaleParameter );
328 mMetalRoughEffect->addParameter( mEmissiveColorParameter );
329 mMetalRoughEffect->addParameter( mEmissionFactorParameter );
330 mMetalRoughEffect->addParameter( mTextureScaleParameter );
331 mMetalRoughEffect->addParameter( mTextureRotationParameter );
332 mMetalRoughEffect->addParameter( mOpacityParameter );
334 setEffect( mMetalRoughEffect );
339void QgsMetalRoughMaterial::updateShaders()
341 QByteArray fragmentShaderCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u
"qrc:/shaders/metalrough.frag"_s ) );
344 QStringList fragShaderDefines;
345 if ( mUsingBaseColorMap )
346 fragShaderDefines +=
"BASE_COLOR_MAP";
347 if ( mUsingMetalnessMap )
348 fragShaderDefines +=
"METALNESS_MAP";
349 if ( mUsingRoughnessMap )
350 fragShaderDefines +=
"ROUGHNESS_MAP";
351 if ( mUsingAmbientOcclusionMap )
352 fragShaderDefines +=
"AMBIENT_OCCLUSION_MAP";
353 if ( mUsingNormalMap )
354 fragShaderDefines +=
"NORMAL_MAP";
355 if ( mUsingHeightMap )
356 fragShaderDefines +=
"HEIGHT_MAP";
357 if ( mUsingEmissionMap )
358 fragShaderDefines +=
"EMISSION_MAP";
360 fragShaderDefines +=
"FLAT_SHADING";
361 if ( mEnableEnvironmentalLighting )
362 fragShaderDefines +=
"ENABLE_IBL";
366 QStringList defines = { u
"HAS_TEXTURE"_s, u
"HAS_TANGENT"_s };
368 defines << u
"USE_INSTANCE_SCALE"_s;
370 defines << u
"USE_INSTANCE_ROTATION"_s;
371 const QByteArray vertCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u
"qrc:/shaders/instanced.vert"_s ) );
374 else if ( mDataDefinedEnabled )
376 fragShaderDefines +=
"DATA_DEFINED";
377 mMetalRoughGL3Shader->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( QUrl( u
"qrc:/shaders/metalroughDataDefined.vert"_s ) ) );
381 const QByteArray vertexShaderCode = Qt3DRender::QShaderProgram::loadSource( QUrl( u
"qrc:/shaders/default.vert"_s ) );
383 mMetalRoughGL3Shader->setVertexShaderCode( finalVertexShaderCode );
387 mMetalRoughGL3Shader->setFragmentShaderCode( finalShaderCode );
390void QgsMetalRoughMaterial::setFlatShadingEnabled(
bool enabled )
392 if ( enabled != mFlatShading )
394 mFlatShading = enabled;
399void QgsMetalRoughMaterial::setOpacity(
float opacity )
401 mOpacityParameter->setValue( opacity );
404void QgsMetalRoughMaterial::setDataDefinedEnabled(
bool enabled )
406 if ( enabled != mDataDefinedEnabled )
408 mDataDefinedEnabled = enabled;
413void QgsMetalRoughMaterial::setEnvironmentalLightingEnabled(
bool enabled )
415 if ( enabled != mEnableEnvironmentalLighting )
417 mEnableEnvironmentalLighting = enabled;
424 mInstanced = enabled;
425 mInstanceFlags = flags;
QFlags< InstancedMaterialFlag > InstancedMaterialFlags
@ DataDefinedRotation
Per-instance data-defined rotation.
@ DataDefinedScale
Per-instance data-defined scale.
Miscellaneous utility functions used from 3D code.
static QByteArray addDefinesToShaderCode(const QByteArray &shaderCode, const QStringList &defines)
Inserts some define macros into a shader source code.
static QColor srgbToLinear(const QColor &color)
Converts a SRGB color to a linear color.
Base class for all materials used within QGIS 3D views.