24using namespace Qt::StringLiterals;
28 return u
"metalroughtextured"_s;
66 return *
this == *otherMetal;
76 return !mNormalTexturePath.isEmpty() || !mHeightTexturePath.isEmpty();
79QColor QgsMetalRoughTexturedMaterialSettings::textureAverageColor(
const QString &texturePath )
const
81 bool fitsInCache =
false;
83 if ( texture.isNull() )
85 return QColor( 127, 127, 127 );
88 if ( texture.format() != QImage::Format_ARGB32 )
90 texture = texture.convertToFormat( QImage::Format_ARGB32 );
93 unsigned long long red = 0;
94 unsigned long long green = 0;
95 unsigned long long blue = 0;
96 unsigned long long pixelCount = 0;
99 const int sampleStep = std::min( texture.width() / 5, texture.height() / 5 );
100 const int width = texture.width();
101 const int height = texture.height();
102 for (
int y = 0; y < height; y += sampleStep )
104 const QRgb *line =
reinterpret_cast< const QRgb *
>( texture.constScanLine( y ) );
105 for (
int x = 0; x < width; x += sampleStep )
107 const QRgb pixel = line[x];
108 red += qRed( pixel );
109 green += qGreen( pixel );
110 blue += qBlue( pixel );
115 return QColor(
static_cast<int>( red / pixelCount ),
static_cast<int>( green / pixelCount ),
static_cast<int>( blue / pixelCount ) );
120 if ( mAverageColor.has_value() )
122 return *mAverageColor;
125 mAverageColor = textureAverageColor( mBaseColorTexturePath );
126 if ( !mEmissionTexturePath.isEmpty() )
128 const QColor emission = textureAverageColor( mEmissionTexturePath );
130 const double red = std::clamp( mAverageColor->redF() + emission.redF() * mEmissionFactor, 0.0, 1.0 );
131 const double green = std::clamp( mAverageColor->greenF() + emission.greenF() * mEmissionFactor, 0.0, 1.0 );
132 const double blue = std::clamp( mAverageColor->blueF() + emission.blueF() * mEmissionFactor, 0.0, 1.0 );
134 mAverageColor = QColor::fromRgbF(
static_cast<float>( red ),
static_cast<float>( green ),
static_cast<float>( blue ) );
137 return *mAverageColor;
142 Q_UNUSED( baseColor );
143 QgsDebugMsgLevel( u
"setColorsFromBase() has no effect for textured PBR materials"_s, 2 );
148 mBaseColorTexturePath = elem.attribute( u
"base_color_texture_path"_s, QString() );
149 mMetalnessTexturePath = elem.attribute( u
"metalness_texture_path"_s, QString() );
150 mRoughnessTexturePath = elem.attribute( u
"roughness_texture_path"_s, QString() );
151 mNormalTexturePath = elem.attribute( u
"normal_texture_path"_s, QString() );
152 mHeightTexturePath = elem.attribute( u
"height_texture_path"_s, QString() );
153 mAmbientOcclusionTexturePath = elem.attribute( u
"ambient_occlusion_texture_path"_s, QString() );
154 mEmissionTexturePath = elem.attribute( u
"emission_texture_path"_s, QString() );
155 mEmissionFactor = elem.attribute( u
"emission_factor"_s, QString(
"1.0" ) ).toDouble();
156 mParallaxScale = elem.attribute( u
"parallax_scale"_s, QString(
"0.1" ) ).toDouble();
157 mTextureScale = elem.attribute( u
"texture_scale"_s, QString(
"1.0" ) ).toDouble();
158 mTextureRotation = elem.attribute( u
"texture_rotation"_s, QString(
"0.0" ) ).toDouble();
159 mOpacity = elem.attribute( u
"opacity"_s, u
"1.0"_s ).toDouble();
166 elem.setAttribute( u
"base_color_texture_path"_s, mBaseColorTexturePath );
167 elem.setAttribute( u
"metalness_texture_path"_s, mMetalnessTexturePath );
168 elem.setAttribute( u
"roughness_texture_path"_s, mRoughnessTexturePath );
169 elem.setAttribute( u
"normal_texture_path"_s, mNormalTexturePath );
170 elem.setAttribute( u
"parallax_scale"_s, mParallaxScale );
171 elem.setAttribute( u
"height_texture_path"_s, mHeightTexturePath );
172 elem.setAttribute( u
"emission_texture_path"_s, mEmissionTexturePath );
173 elem.setAttribute( u
"ambient_occlusion_texture_path"_s, mAmbientOcclusionTexturePath );
175 elem.setAttribute( u
"emission_factor"_s, mEmissionFactor );
176 elem.setAttribute( u
"texture_scale"_s, mTextureScale );
177 elem.setAttribute( u
"texture_rotation"_s, mTextureRotation );
179 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.
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.
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.
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)