24using namespace Qt::StringLiterals;
28 return u
"metalroughtextured"_s;
66 return *
this == *otherMetal;
81 return !mNormalTexturePath.isEmpty() || !mHeightTexturePath.isEmpty();
84QColor QgsMetalRoughTexturedMaterialSettings::textureAverageColor(
const QString &texturePath )
const
86 bool fitsInCache =
false;
88 if ( texture.isNull() )
90 return QColor( 127, 127, 127 );
93 if ( texture.format() != QImage::Format_ARGB32 )
95 texture = texture.convertToFormat( QImage::Format_ARGB32 );
98 unsigned long long red = 0;
99 unsigned long long green = 0;
100 unsigned long long blue = 0;
101 unsigned long long pixelCount = 0;
104 const int sampleStep = std::min( texture.width() / 5, texture.height() / 5 );
105 const int width = texture.width();
106 const int height = texture.height();
107 for (
int y = 0; y < height; y += sampleStep )
109 const QRgb *line =
reinterpret_cast< const QRgb *
>( texture.constScanLine( y ) );
110 for (
int x = 0; x < width; x += sampleStep )
112 const QRgb pixel = line[x];
113 red += qRed( pixel );
114 green += qGreen( pixel );
115 blue += qBlue( pixel );
120 return QColor(
static_cast<int>( red / pixelCount ),
static_cast<int>( green / pixelCount ),
static_cast<int>( blue / pixelCount ) );
125 if ( mAverageColor.has_value() )
127 return *mAverageColor;
130 mAverageColor = textureAverageColor( mBaseColorTexturePath );
131 if ( !mEmissionTexturePath.isEmpty() )
133 const QColor emission = textureAverageColor( mEmissionTexturePath );
135 const double red = std::clamp( mAverageColor->redF() + emission.redF() * mEmissionFactor, 0.0, 1.0 );
136 const double green = std::clamp( mAverageColor->greenF() + emission.greenF() * mEmissionFactor, 0.0, 1.0 );
137 const double blue = std::clamp( mAverageColor->blueF() + emission.blueF() * mEmissionFactor, 0.0, 1.0 );
139 mAverageColor = QColor::fromRgbF(
static_cast<float>( red ),
static_cast<float>( green ),
static_cast<float>( blue ) );
142 return *mAverageColor;
147 Q_UNUSED( baseColor );
148 QgsDebugMsgLevel( u
"setColorsFromBase() has no effect for textured PBR materials"_s, 2 );
153 mBaseColorTexturePath = elem.attribute( u
"base_color_texture_path"_s, QString() );
154 mMetalnessTexturePath = elem.attribute( u
"metalness_texture_path"_s, QString() );
155 mRoughnessTexturePath = elem.attribute( u
"roughness_texture_path"_s, QString() );
156 mNormalTexturePath = elem.attribute( u
"normal_texture_path"_s, QString() );
157 mHeightTexturePath = elem.attribute( u
"height_texture_path"_s, QString() );
158 mAmbientOcclusionTexturePath = elem.attribute( u
"ambient_occlusion_texture_path"_s, QString() );
159 mEmissionTexturePath = elem.attribute( u
"emission_texture_path"_s, QString() );
160 mEmissionFactor = elem.attribute( u
"emission_factor"_s, QString(
"1.0" ) ).toDouble();
161 mParallaxScale = elem.attribute( u
"parallax_scale"_s, QString(
"0.1" ) ).toDouble();
162 mTextureScale = elem.attribute( u
"texture_scale"_s, QString(
"1.0" ) ).toDouble();
163 mTextureRotation = elem.attribute( u
"texture_rotation"_s, QString(
"0.0" ) ).toDouble();
165 mOpacity = elem.attribute( u
"opacity"_s, u
"1.0"_s ).toDouble();
172 elem.setAttribute( u
"base_color_texture_path"_s, mBaseColorTexturePath );
173 elem.setAttribute( u
"metalness_texture_path"_s, mMetalnessTexturePath );
174 elem.setAttribute( u
"roughness_texture_path"_s, mRoughnessTexturePath );
175 elem.setAttribute( u
"normal_texture_path"_s, mNormalTexturePath );
176 elem.setAttribute( u
"parallax_scale"_s, mParallaxScale );
177 elem.setAttribute( u
"height_texture_path"_s, mHeightTexturePath );
178 elem.setAttribute( u
"emission_texture_path"_s, mEmissionTexturePath );
179 elem.setAttribute( u
"ambient_occlusion_texture_path"_s, mAmbientOcclusionTexturePath );
181 elem.setAttribute( u
"emission_factor"_s, mEmissionFactor );
182 elem.setAttribute( u
"texture_scale"_s, mTextureScale );
183 elem.setAttribute( u
"texture_rotation"_s, mTextureRotation );
187 elem.setAttribute( u
"opacity"_s, mOpacity );
MaterialRenderingTechnique
Material rendering techniques.
@ Points
Point based rendering, requires point data.
@ Triangles
Triangle based rendering (default).
@ TrianglesFromModel
Triangle based rendering, using a model object source.
@ Lines
Line based rendering, requires line data.
@ Billboards
Flat billboard rendering.
@ TrianglesDataDefined
Triangle based rendering with possibility of datadefined color.
@ InstancedPoints
Instanced based rendering, requiring triangles and point data.
@ TrianglesWithFixedTexture
Triangle based rendering, using a fixed, non-user-configurable texture (e.g. for terrain rendering).
Abstract base class for material settings.
virtual void writeXml(QDomElement &element, const QgsReadWriteContext &) const
Writes settings to a DOM element.
virtual void readXml(const QDomElement &element, const QgsReadWriteContext &)
Reads settings from a DOM element.
@ TextureOffset
Texture offset.
@ TextureRotation
Texture rotation.
@ TextureScale
Texture scale.
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.
bool requiresTangents() const override
Returns true if the material requires tangents generated during triangulation.
QString type() const override
Returns the unique type name for the material.
QgsMetalRoughTexturedMaterialSettings * clone() const override
Clones the material settings.
static QgsAbstractMaterialSettings * create()
Returns a new instance of QgsMetalRoughTexturedMaterialSettings.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes settings to a DOM element.
QColor averageColor() const override
Returns an approximate color representing the blended material color.
void setColorsFromBase(const QColor &baseColor) override
Decomposes a base color into the material's color components, and sets the material's colors accordin...
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads settings from a DOM element.
QSet< QgsAbstractMaterialSettings::Property > supportedProperties() const override
Returns the set of data-defined properties supported by this material.
bool equals(const QgsAbstractMaterialSettings *other) const override
Returns true if this settings exactly matches an other settings.
bool requiresTextureCoordinates() const override
Returns true if the material requires texture coordinates to be generated during triangulation.
static bool supportsTechnique(Qgis::MaterialRenderingTechnique technique)
Returns true if the specified technique is supported by the metal rough material.
QgsMetalRoughTexturedMaterialSettings()=default
A container for the context for various read/write operations on objects.
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
#define QgsDebugMsgLevel(str, level)