diff options
Diffstat (limited to 'src/extras/defaults/qmetalroughmaterial.cpp')
-rw-r--r-- | src/extras/defaults/qmetalroughmaterial.cpp | 217 |
1 files changed, 179 insertions, 38 deletions
diff --git a/src/extras/defaults/qmetalroughmaterial.cpp b/src/extras/defaults/qmetalroughmaterial.cpp index ea213ab82..4d537f20f 100644 --- a/src/extras/defaults/qmetalroughmaterial.cpp +++ b/src/extras/defaults/qmetalroughmaterial.cpp @@ -45,6 +45,7 @@ #include <Qt3DRender/qtexture.h> #include <Qt3DRender/qtechnique.h> #include <Qt3DRender/qshaderprogram.h> +#include <Qt3DRender/qshaderprogrambuilder.h> #include <Qt3DRender/qparameter.h> #include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qgraphicsapifilter.h> @@ -65,12 +66,19 @@ QMetalRoughMaterialPrivate::QMetalRoughMaterialPrivate() , m_baseColorParameter(new QParameter(QStringLiteral("baseColor"), QColor("grey"))) , m_metalnessParameter(new QParameter(QStringLiteral("metalness"), 0.0f)) , m_roughnessParameter(new QParameter(QStringLiteral("roughness"), 0.0f)) + , m_baseColorMapParameter(new QParameter(QStringLiteral("baseColorMap"), QVariant())) + , m_metalnessMapParameter(new QParameter(QStringLiteral("metalnessMap"), QVariant())) + , m_roughnessMapParameter(new QParameter(QStringLiteral("roughnessMap"), QVariant())) + , m_ambientOcclusionMapParameter(new QParameter(QStringLiteral("ambientOcclusionMap"), QVariant())) + , m_normalMapParameter(new QParameter(QStringLiteral("normalMap"), QVariant())) + , m_textureScaleParameter(new QParameter(QStringLiteral("texCoordScale"), 1.0f)) , m_environmentIrradianceParameter(new QParameter(QStringLiteral("envLight.irradiance"), m_environmentIrradianceTexture)) , m_environmentSpecularParameter(new QParameter(QStringLiteral("envLight.specular"), m_environmentSpecularTexture)) , m_metalRoughEffect(new QEffect()) , m_metalRoughGL3Technique(new QTechnique()) , m_metalRoughGL3RenderPass(new QRenderPass()) , m_metalRoughGL3Shader(new QShaderProgram()) + , m_metalRoughGL3ShaderBuilder(new QShaderProgramBuilder()) , m_filterKey(new QFilterKey) { m_environmentIrradianceTexture->setMagnificationFilter(QAbstractTexture::Linear); @@ -88,22 +96,37 @@ QMetalRoughMaterialPrivate::QMetalRoughMaterialPrivate() void QMetalRoughMaterialPrivate::init() { - connect(m_baseColorParameter, &Qt3DRender::QParameter::valueChanged, - this, &QMetalRoughMaterialPrivate::handleBaseColorChanged); - connect(m_metalnessParameter, &Qt3DRender::QParameter::valueChanged, - this, &QMetalRoughMaterialPrivate::handleMetallicChanged); - connect(m_roughnessParameter, &Qt3DRender::QParameter::valueChanged, - this, &QMetalRoughMaterialPrivate::handleRoughnessChanged); + Q_Q(QMetalRoughMaterial); - m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalrough.vert")))); - m_metalRoughGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalroughuniform.frag")))); + QObject::connect(m_baseColorParameter, &Qt3DRender::QParameter::valueChanged, + q, &QMetalRoughMaterial::baseColorChanged); + QObject::connect(m_metalnessParameter, &Qt3DRender::QParameter::valueChanged, + q, &QMetalRoughMaterial::metalnessChanged); + QObject::connect(m_roughnessParameter, &Qt3DRender::QParameter::valueChanged, + q, &QMetalRoughMaterial::roughnessChanged); + QObject::connect(m_ambientOcclusionMapParameter, &Qt3DRender::QParameter::valueChanged, + q, &QMetalRoughMaterial::roughnessChanged); + QObject::connect(m_normalMapParameter, &Qt3DRender::QParameter::valueChanged, + q, &QMetalRoughMaterial::normalChanged); + connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged, + this, &QMetalRoughMaterialPrivate::handleTextureScaleChanged); + + m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert")))); + + m_metalRoughGL3ShaderBuilder->setParent(q); + m_metalRoughGL3ShaderBuilder->setShaderProgram(m_metalRoughGL3Shader); + m_metalRoughGL3ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/metalrough.frag.json"))); + m_metalRoughGL3ShaderBuilder->setEnabledLayers({QStringLiteral("baseColor"), + QStringLiteral("metalness"), + QStringLiteral("roughness"), + QStringLiteral("ambientOcclusion"), + QStringLiteral("normal")}); m_metalRoughGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); m_metalRoughGL3Technique->graphicsApiFilter()->setMajorVersion(3); m_metalRoughGL3Technique->graphicsApiFilter()->setMinorVersion(1); m_metalRoughGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); - Q_Q(QMetalRoughMaterial); m_filterKey->setParent(q); m_filterKey->setName(QStringLiteral("renderingStyle")); m_filterKey->setValue(QStringLiteral("forward")); @@ -116,6 +139,7 @@ void QMetalRoughMaterialPrivate::init() m_metalRoughEffect->addParameter(m_baseColorParameter); m_metalRoughEffect->addParameter(m_metalnessParameter); m_metalRoughEffect->addParameter(m_roughnessParameter); + m_metalRoughEffect->addParameter(m_textureScaleParameter); // Note that even though those parameters are not exposed in the API, // they need to be kept around for now due to a bug in some drivers/GPUs @@ -129,21 +153,10 @@ void QMetalRoughMaterialPrivate::init() q->setEffect(m_metalRoughEffect); } -void QMetalRoughMaterialPrivate::handleBaseColorChanged(const QVariant &var) +void QMetalRoughMaterialPrivate::handleTextureScaleChanged(const QVariant &var) { Q_Q(QMetalRoughMaterial); - emit q->baseColorChanged(var.value<QColor>()); -} - -void QMetalRoughMaterialPrivate::handleMetallicChanged(const QVariant &var) -{ - Q_Q(QMetalRoughMaterial); - emit q->metalnessChanged(var.toFloat()); -} -void QMetalRoughMaterialPrivate::handleRoughnessChanged(const QVariant &var) -{ - Q_Q(QMetalRoughMaterial); - emit q->roughnessChanged(var.toFloat()); + emit q->textureScaleChanged(var.toFloat()); } /*! @@ -186,53 +199,181 @@ QMetalRoughMaterial::~QMetalRoughMaterial() /*! \property QMetalRoughMaterial::baseColor - Holds the current base color of the material. + Holds the current base color of the material. This can be either a plain + color value or a texture. By default the value of this property is "grey". */ -QColor QMetalRoughMaterial::baseColor() const +QVariant QMetalRoughMaterial::baseColor() const { Q_D(const QMetalRoughMaterial); - return d->m_baseColorParameter->value().value<QColor>(); + return d->m_baseColorParameter->value(); } /*! \property QMetalRoughMaterial::metalness - Holds the current metalness level of the material, since is a value between 0 (purely dielectric, the default) - and 1 (purely metallic). + Holds the current metalness level of the material, since is a value between + 0 (purely dielectric, the default) and 1 (purely metallic). This can be + either a plain uniform value or a texture. By default the value of this + property is 0. */ -float QMetalRoughMaterial::metalness() const +QVariant QMetalRoughMaterial::metalness() const { Q_D(const QMetalRoughMaterial); - return d->m_metalnessParameter->value().toFloat(); + return d->m_metalnessParameter->value(); } /*! \property QMetalRoughMaterial::roughness - Holds the current roughness level of the material. + Holds the current roughness level of the material. This can be either a + plain uniform value or a texture. By default the value of this property is + 0. +*/ +QVariant QMetalRoughMaterial::roughness() const +{ + Q_D(const QMetalRoughMaterial); + return d->m_roughnessParameter->value(); +} + +/*! + \property QMetalRoughMaterial::ambientOcclusion + + Holds the current ambient occlusion map texture of the material. This can + only be a texture, otherwise it is ignored. By default this map is not set. +*/ +QVariant QMetalRoughMaterial::ambientOcclusion() const +{ + Q_D(const QMetalRoughMaterial); + return d->m_ambientOcclusionMapParameter->value(); +} + +/*! + \property QMetalRoughMaterial::normal + + Holds the current normal map texture of the material. This can only be a + texture, otherwise it is ignored. By default this map is not set. */ -float QMetalRoughMaterial::roughness() const +QVariant QMetalRoughMaterial::normal() const { Q_D(const QMetalRoughMaterial); - return d->m_roughnessParameter->value().toFloat(); + return d->m_normalMapParameter->value(); +} + +/*! + \property QMetalRoughMaterial::textureScale + + Holds the current texture scale. It is applied as a multiplier to texture + coordinates at render time. Defaults to 1.0. +*/ +float QMetalRoughMaterial::textureScale() const +{ + Q_D(const QMetalRoughMaterial); + return d->m_textureScaleParameter->value().toFloat(); +} + +void QMetalRoughMaterial::setBaseColor(const QVariant &baseColor) +{ + Q_D(QMetalRoughMaterial); + d->m_baseColorParameter->setValue(baseColor); + d->m_baseColorMapParameter->setValue(baseColor); + + auto layers = d->m_metalRoughGL3ShaderBuilder->enabledLayers(); + if (baseColor.value<QAbstractTexture *>()) { + layers.removeAll(QStringLiteral("baseColor")); + layers.append(QStringLiteral("baseColorMap")); + d->m_metalRoughEffect->addParameter(d->m_baseColorMapParameter); + d->m_metalRoughEffect->removeParameter(d->m_baseColorParameter); + } else { + layers.removeAll(QStringLiteral("baseColorMap")); + layers.append(QStringLiteral("baseColor")); + d->m_metalRoughEffect->removeParameter(d->m_baseColorMapParameter); + d->m_metalRoughEffect->addParameter(d->m_baseColorParameter); + } + d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers); +} + +void QMetalRoughMaterial::setMetalness(const QVariant &metalness) +{ + Q_D(QMetalRoughMaterial); + d->m_metalnessParameter->setValue(metalness); + d->m_metalnessMapParameter->setValue(metalness); + + auto layers = d->m_metalRoughGL3ShaderBuilder->enabledLayers(); + if (metalness.value<QAbstractTexture *>()) { + layers.removeAll(QStringLiteral("metalness")); + layers.append(QStringLiteral("metalnessMap")); + d->m_metalRoughEffect->addParameter(d->m_metalnessMapParameter); + d->m_metalRoughEffect->removeParameter(d->m_metalnessParameter); + } else { + layers.removeAll(QStringLiteral("metalnessMap")); + layers.append(QStringLiteral("metalness")); + d->m_metalRoughEffect->removeParameter(d->m_metalnessMapParameter); + d->m_metalRoughEffect->addParameter(d->m_metalnessParameter); + } + d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers); +} + +void QMetalRoughMaterial::setRoughness(const QVariant &roughness) +{ + Q_D(QMetalRoughMaterial); + d->m_roughnessParameter->setValue(roughness); + d->m_roughnessMapParameter->setValue(roughness); + + auto layers = d->m_metalRoughGL3ShaderBuilder->enabledLayers(); + if (roughness.value<QAbstractTexture *>()) { + layers.removeAll(QStringLiteral("roughness")); + layers.append(QStringLiteral("roughnessMap")); + d->m_metalRoughEffect->addParameter(d->m_roughnessMapParameter); + d->m_metalRoughEffect->removeParameter(d->m_roughnessParameter); + } else { + layers.removeAll(QStringLiteral("roughnessMap")); + layers.append(QStringLiteral("roughness")); + d->m_metalRoughEffect->removeParameter(d->m_roughnessMapParameter); + d->m_metalRoughEffect->addParameter(d->m_roughnessParameter); + } + d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers); } -void QMetalRoughMaterial::setBaseColor(const QColor &baseColor) +void QMetalRoughMaterial::setAmbientOcclusion(const QVariant &ambientOcclusion) { Q_D(QMetalRoughMaterial); - d->m_baseColorParameter->setValue(QVariant::fromValue(baseColor)); + d->m_ambientOcclusionMapParameter->setValue(ambientOcclusion); + + auto layers = d->m_metalRoughGL3ShaderBuilder->enabledLayers(); + if (ambientOcclusion.value<QAbstractTexture *>()) { + layers.removeAll(QStringLiteral("ambientOcclusion")); + layers.append(QStringLiteral("ambientOcclusionMap")); + d->m_metalRoughEffect->addParameter(d->m_ambientOcclusionMapParameter); + } else { + layers.removeAll(QStringLiteral("ambientOcclusionMap")); + layers.append(QStringLiteral("ambientOcclusion")); + d->m_metalRoughEffect->removeParameter(d->m_ambientOcclusionMapParameter); + } + d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers); } -void QMetalRoughMaterial::setMetalness(float metalness) +void QMetalRoughMaterial::setNormal(const QVariant &normal) { Q_D(QMetalRoughMaterial); - d->m_metalnessParameter->setValue(QVariant::fromValue(metalness)); + d->m_normalMapParameter->setValue(normal); + + auto layers = d->m_metalRoughGL3ShaderBuilder->enabledLayers(); + if (normal.value<QAbstractTexture *>()) { + layers.removeAll(QStringLiteral("normal")); + layers.append(QStringLiteral("normalMap")); + d->m_metalRoughEffect->addParameter(d->m_normalMapParameter); + } else { + layers.removeAll(QStringLiteral("normalMap")); + layers.append(QStringLiteral("normal")); + d->m_metalRoughEffect->removeParameter(d->m_normalMapParameter); + } + d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers); } -void QMetalRoughMaterial::setRoughness(float roughness) +void QMetalRoughMaterial::setTextureScale(float textureScale) { Q_D(QMetalRoughMaterial); - d->m_roughnessParameter->setValue(QVariant::fromValue(roughness)); + d->m_textureScaleParameter->setValue(textureScale); } } // namespace Qt3DExtras |