27using namespace Qt::StringLiterals;
31 return u
"phongtextured"_s;
69 return *
this == *otherPhong;
74 return !mDiffuseTexturePath.isEmpty();
79 return mTextureRotation;
84 const double avgDiffuseFactor = 0.3;
85 const double avgSpecularFactor = 0.2;
87 const double kAmbient = 0.2;
88 const double kDiffuse = 0.6;
89 const double kSpecular = 0.2;
91 const QColor diffuse = textureAverageColor();
93 double red = kAmbient * mAmbient.redF() + kDiffuse * avgDiffuseFactor * diffuse.redF() + kSpecular * avgSpecularFactor * mSpecular.redF();
95 double green = kAmbient * mAmbient.greenF() + kDiffuse * avgDiffuseFactor * diffuse.greenF() + kSpecular * avgSpecularFactor * mSpecular.greenF();
97 double blue = kAmbient * mAmbient.blueF() + kDiffuse * avgDiffuseFactor * diffuse.blueF() + kSpecular * avgSpecularFactor * mSpecular.blueF();
99 red = std::clamp( red, 0.0, 1.0 );
100 green = std::clamp( green, 0.0, 1.0 );
101 blue = std::clamp( blue, 0.0, 1.0 );
103 return QColor::fromRgbF(
static_cast<float>( red ),
static_cast<float>( green ),
static_cast<float>( blue ),
static_cast<float>( mOpacity ) );
107QColor QgsPhongTexturedMaterialSettings::textureAverageColor()
const
109 if ( mTextureAverageColor.has_value() )
111 return *mTextureAverageColor;
114 bool fitsInCache =
false;
116 if ( texture.isNull() )
118 mTextureAverageColor = QColor( 127, 127, 127 );
119 return *mTextureAverageColor;
122 if ( texture.format() != QImage::Format_ARGB32 )
124 texture = texture.convertToFormat( QImage::Format_ARGB32 );
127 unsigned long long red = 0;
128 unsigned long long green = 0;
129 unsigned long long blue = 0;
130 unsigned long long pixelCount = 0;
133 const int sampleStep = std::min( texture.width() / 5, texture.height() / 5 );
134 const int width = texture.width();
135 const int height = texture.height();
136 for (
int y = 0; y < height; y += sampleStep )
138 const QRgb *line =
reinterpret_cast< const QRgb *
>( texture.constScanLine( y ) );
139 for (
int x = 0; x < width; x += sampleStep )
141 const QRgb pixel = line[x];
142 red += qRed( pixel );
143 green += qGreen( pixel );
144 blue += qBlue( pixel );
149 mTextureAverageColor = QColor(
static_cast<int>( red / pixelCount ),
static_cast<int>( green / pixelCount ),
static_cast<int>( blue / pixelCount ) );
150 return *mTextureAverageColor;
155 metallic = std::clamp( metallic, 0.0f, 1.0f );
157 const float baseR = baseColor.redF();
158 const float baseG = baseColor.greenF();
159 const float baseB = baseColor.blueF();
162 constexpr float AMBIENT_FACTOR = 0.2f;
163 mAmbient = QColor::fromRgbF( baseR * AMBIENT_FACTOR, baseG * AMBIENT_FACTOR, baseB * AMBIENT_FACTOR );
166 constexpr float F0_DIELECTRIC = 0.04f;
173 mSpecular = QColor::fromRgbF( ( 1.0f - metallic ) * F0_DIELECTRIC + metallic * baseR, ( 1.0f - metallic ) * F0_DIELECTRIC + metallic * baseG, ( 1.0f - metallic ) * F0_DIELECTRIC + metallic * baseB );
175 constexpr float MIN_SHININESS = 32.0f;
176 constexpr float MAX_SHININESS = 200.0f;
177 mShininess = MIN_SHININESS + metallic * ( MAX_SHININESS - MIN_SHININESS );
189 mShininess = elem.attribute( u
"shininess"_s ).toDouble();
190 mOpacity = elem.attribute( u
"opacity"_s, u
"1.0"_s ).toDouble();
191 mDiffuseTexturePath = elem.attribute( u
"diffuse_texture_path"_s, QString() );
192 mTextureScale = elem.attribute( u
"texture_scale"_s, QString(
"1.0" ) ).toDouble();
193 mTextureRotation = elem.attribute( u
"texture-rotation"_s, QString(
"0.0" ) ).toDouble();
202 elem.setAttribute( u
"shininess"_s, mShininess );
203 elem.setAttribute( u
"opacity"_s, mOpacity );
204 elem.setAttribute( u
"diffuse_texture_path"_s, mDiffuseTexturePath );
205 elem.setAttribute( u
"texture_scale"_s, mTextureScale );
206 elem.setAttribute( u
"texture-rotation"_s, mTextureRotation );
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.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
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 requiresTextureCoordinates() const override
Returns true if the material requires texture coordinates to be generated during triangulation.
QgsPhongTexturedMaterialSettings()=default
static bool supportsTechnique(Qgis::MaterialRenderingTechnique technique)
Returns true if the specified technique is supported by the Phong material.
bool equals(const QgsAbstractMaterialSettings *other) const override
Returns true if this settings exactly matches an other settings.
QColor averageColor() const override
Returns an approximate color representing the blended material color.
void setColorsFromBase(const QColor &baseColor, float metallic)
Decompose an average color into Phong material components, and sets the material's colors accordingly...
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes settings to a DOM element.
double textureRotation() const
Returns the texture rotation, in degrees.
QString type() const override
Returns the unique type name for the material.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads settings from a DOM element.
QgsPhongTexturedMaterialSettings * clone() const override
Clones the material settings.
static QgsAbstractMaterialSettings * create()
Returns a new instance of QgsPhongTexturedMaterialSettings.
A container for the context for various read/write operations on objects.