summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Ottens <kevin.ottens@kdab.com>2017-01-30 16:04:06 +0100
committerSean Harmer <sean.harmer@kdab.com>2017-01-31 08:59:47 +0000
commitcfb6bf0c53d9f70f12802cb25a1c14327615b756 (patch)
tree5a2ff6d278de0c954f2a28d5608f9020a86b0e6e
parentae1a3bee761c29edffc5fdbe7b77140f1620a04a (diff)
Uniform color PBR lighting to Qt3DExtras
Second material using PBR. Still uses environment maps and ignores regular lights but provide a plain color variant of the material. Change-Id: Ica2045826f6efdc804240709154b6822b89f4417 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/extras/defaults/defaults.pri3
-rw-r--r--src/extras/defaults/qmetalroughmaterial.cpp328
-rw-r--r--src/extras/defaults/qmetalroughmaterial.h105
-rw-r--r--src/extras/defaults/qmetalroughmaterial_p.h110
-rw-r--r--src/extras/extras.qrc1
-rw-r--r--src/extras/shaders/gl3/metalroughuniform.frag217
-rw-r--r--src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp2
7 files changed, 766 insertions, 0 deletions
diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri
index 58204bd71..cab26cafd 100644
--- a/src/extras/defaults/defaults.pri
+++ b/src/extras/defaults/defaults.pri
@@ -30,6 +30,8 @@ HEADERS += \
$$PWD/qorbitcameracontroller_p.h \
$$PWD/qtexturematerial.h \
$$PWD/qtexturematerial_p.h \
+ $$PWD/qmetalroughmaterial.h \
+ $$PWD/qmetalroughmaterial_p.h \
$$PWD/qtexturedmetalroughmaterial.h \
$$PWD/qtexturedmetalroughmaterial_p.h
@@ -50,5 +52,6 @@ SOURCES += \
$$PWD/qfirstpersoncameracontroller.cpp \
$$PWD/qorbitcameracontroller.cpp \
$$PWD/qtexturematerial.cpp \
+ $$PWD/qmetalroughmaterial.cpp \
$$PWD/qtexturedmetalroughmaterial.cpp
diff --git a/src/extras/defaults/qmetalroughmaterial.cpp b/src/extras/defaults/qmetalroughmaterial.cpp
new file mode 100644
index 000000000..e895da639
--- /dev/null
+++ b/src/extras/defaults/qmetalroughmaterial.cpp
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmetalroughmaterial.h"
+#include "qmetalroughmaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qmaterial.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtexture.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QMetalRoughMaterialPrivate::QMetalRoughMaterialPrivate()
+ : QMaterialPrivate()
+ , m_environmentIrradianceTexture(new QTexture2D())
+ , m_environmentSpecularTexture(new QTexture2D())
+ , m_baseColorParameter(new QParameter(QStringLiteral("baseColor"), QColor("grey")))
+ , m_metallicParameter(new QParameter(QStringLiteral("metallic"), 0.0f))
+ , m_roughnessParameter(new QParameter(QStringLiteral("roughness"), 0.0f))
+ , m_environmentIrradianceParameter(new QParameter(QStringLiteral("skyIrradiance"), m_environmentIrradianceTexture))
+ , m_environmentSpecularParameter(new QParameter(QStringLiteral("skySpecular"), m_environmentSpecularTexture))
+ , m_exposureParameter(new QParameter(QStringLiteral("exposure"), 0.0f))
+ , m_metalRoughEffect(new QEffect())
+ , m_metalRoughGL3Technique(new QTechnique())
+ , m_metalRoughGL3RenderPass(new QRenderPass())
+ , m_metalRoughGL3Shader(new QShaderProgram())
+ , m_filterKey(new QFilterKey)
+{
+ m_environmentIrradianceTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_environmentIrradianceTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
+ m_environmentIrradianceTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_environmentIrradianceTexture->setGenerateMipMaps(true);
+ m_environmentIrradianceTexture->setMaximumAnisotropy(16.0f);
+
+ m_environmentSpecularTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_environmentSpecularTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
+ m_environmentSpecularTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_environmentSpecularTexture->setGenerateMipMaps(true);
+ m_environmentSpecularTexture->setMaximumAnisotropy(16.0f);
+}
+
+void QMetalRoughMaterialPrivate::init()
+{
+ connect(m_baseColorParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMetalRoughMaterialPrivate::handleBaseColorChanged);
+ connect(m_metallicParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMetalRoughMaterialPrivate::handleMetallicChanged);
+ connect(m_roughnessParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMetalRoughMaterialPrivate::handleRoughnessChanged);
+ connect(m_environmentIrradianceParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMetalRoughMaterialPrivate::handleEnvironmentIrradianceChanged);
+ connect(m_environmentSpecularParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMetalRoughMaterialPrivate::handleEnvironmentSpecularChanged);
+ connect(m_exposureParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMetalRoughMaterialPrivate::handleExposureChanged);
+
+ m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalrough.vert"))));
+ m_metalRoughGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalroughuniform.frag"))));
+
+ 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"));
+
+ m_metalRoughGL3Technique->addFilterKey(m_filterKey);
+ m_metalRoughGL3RenderPass->setShaderProgram(m_metalRoughGL3Shader);
+ m_metalRoughGL3Technique->addRenderPass(m_metalRoughGL3RenderPass);
+ m_metalRoughEffect->addTechnique(m_metalRoughGL3Technique);
+
+ m_metalRoughEffect->addParameter(m_baseColorParameter);
+ m_metalRoughEffect->addParameter(m_metallicParameter);
+ m_metalRoughEffect->addParameter(m_roughnessParameter);
+ m_metalRoughEffect->addParameter(m_environmentIrradianceParameter);
+ m_metalRoughEffect->addParameter(m_environmentSpecularParameter);
+ m_metalRoughEffect->addParameter(m_exposureParameter);
+
+ q->setEffect(m_metalRoughEffect);
+}
+
+void QMetalRoughMaterialPrivate::handleBaseColorChanged(const QVariant &var)
+{
+ Q_Q(QMetalRoughMaterial);
+ emit q->baseColorChanged(var.value<QColor>());
+}
+
+void QMetalRoughMaterialPrivate::handleMetallicChanged(const QVariant &var)
+{
+ Q_Q(QMetalRoughMaterial);
+ emit q->metallicChanged(var.toFloat());
+}
+void QMetalRoughMaterialPrivate::handleRoughnessChanged(const QVariant &var)
+{
+ Q_Q(QMetalRoughMaterial);
+ emit q->roughnessChanged(var.toFloat());
+}
+
+void QMetalRoughMaterialPrivate::handleEnvironmentIrradianceChanged(const QVariant &var)
+{
+ Q_Q(QMetalRoughMaterial);
+ emit q->environmentIrradianceChanged(var.value<QAbstractTexture *>());
+}
+
+void QMetalRoughMaterialPrivate::handleEnvironmentSpecularChanged(const QVariant &var)
+{
+ Q_Q(QMetalRoughMaterial);
+ emit q->environmentSpecularChanged(var.value<QAbstractTexture *>());
+}
+
+void QMetalRoughMaterialPrivate::handleExposureChanged(const QVariant &var)
+{
+ Q_Q(QMetalRoughMaterial);
+ emit q->exposureChanged(var.toFloat());
+}
+
+/*!
+ \class Qt3DExtras::QMetalRoughMaterial
+ \brief The QMetalRoughMaterial provides a default implementation of PBR
+ lighting.
+ \inmodule Qt3DExtras
+ \since 5.9
+ \inherits Qt3DRender::QMaterial
+
+ This material uses an effect with a single render pass approach and performs per fragment
+ lighting. Techniques are provided for OpenGL 3 only.
+*/
+
+/*!
+ Constructs a new QMetalRoughMaterial instance with parent object \a parent.
+*/
+QMetalRoughMaterial::QMetalRoughMaterial(QNode *parent)
+ : QMaterial(*new QMetalRoughMaterialPrivate, parent)
+{
+ Q_D(QMetalRoughMaterial);
+ d->init();
+}
+
+/*! \internal */
+QMetalRoughMaterial::QMetalRoughMaterial(QMetalRoughMaterialPrivate &dd, QNode *parent)
+ : QMaterial(dd, parent)
+{
+ Q_D(QMetalRoughMaterial);
+ d->init();
+}
+
+/*!
+ Destroys the QMetalRoughMaterial instance.
+*/
+QMetalRoughMaterial::~QMetalRoughMaterial()
+{
+}
+
+/*!
+ \property QMetalRoughMaterial::baseColor
+
+ Holds the current base color of the material.
+*/
+QColor QMetalRoughMaterial::baseColor() const
+{
+ Q_D(const QMetalRoughMaterial);
+ return d->m_baseColorParameter->value().value<QColor>();
+}
+
+/*!
+ \property QMetalRoughMaterial::metallic
+
+ Holds the current metallic level of the material, since is a value between 0 (purely dielectric, the default)
+ and 1 (purely metallic).
+*/
+float QMetalRoughMaterial::metallic() const
+{
+ Q_D(const QMetalRoughMaterial);
+ return d->m_metallicParameter->value().toFloat();
+}
+
+/*!
+ \property QMetalRoughMaterial::roughness
+
+ Holds the current roughness level of the material.
+*/
+float QMetalRoughMaterial::roughness() const
+{
+ Q_D(const QMetalRoughMaterial);
+ return d->m_roughnessParameter->value().toFloat();
+}
+
+/*!
+ \property QMetalRoughMaterial::environmentIrradiance
+
+ Holds the current environment irradiance map texture.
+
+ By default, the environment irradiance texture has the following properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Linear mipmap with mipmapping enabled
+ \li Repeat wrap mode
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QMetalRoughMaterial::environmentIrradiance() const
+{
+ Q_D(const QMetalRoughMaterial);
+ return d->m_environmentIrradianceParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property QMetalRoughMaterial::environmentSpecular
+
+ Holds the current environment specular map texture.
+
+ By default, the environment specular texture has the following properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Linear mipmap with mipmapping enabled
+ \li Repeat wrap mode
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QMetalRoughMaterial::environmentSpecular() const
+{
+ Q_D(const QMetalRoughMaterial);
+ return d->m_environmentSpecularParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property QMetalRoughMaterial::exposure
+
+ Holds the current exposure as a float value.
+*/
+float QMetalRoughMaterial::exposure() const
+{
+ Q_D(const QMetalRoughMaterial);
+ return d->m_exposureParameter->value().toFloat();
+}
+
+void QMetalRoughMaterial::setBaseColor(const QColor &baseColor)
+{
+ Q_D(QMetalRoughMaterial);
+ d->m_baseColorParameter->setValue(QVariant::fromValue(baseColor));
+}
+
+void QMetalRoughMaterial::setMetallic(float metallic)
+{
+ Q_D(QMetalRoughMaterial);
+ d->m_metallicParameter->setValue(QVariant::fromValue(metallic));
+}
+
+void QMetalRoughMaterial::setRoughness(float roughness)
+{
+ Q_D(QMetalRoughMaterial);
+ d->m_roughnessParameter->setValue(QVariant::fromValue(roughness));
+}
+
+void QMetalRoughMaterial::setEnvironmentIrradiance(QAbstractTexture *environmentIrradiance)
+{
+ Q_D(QMetalRoughMaterial);
+ d->m_environmentIrradianceParameter->setValue(QVariant::fromValue(environmentIrradiance));
+}
+
+void QMetalRoughMaterial::setEnvironmentSpecular(QAbstractTexture *environmentSpecular)
+{
+ Q_D(QMetalRoughMaterial);
+ d->m_environmentSpecularParameter->setValue(QVariant::fromValue(environmentSpecular));
+}
+
+void QMetalRoughMaterial::setExposure(float exposure)
+{
+ Q_D(QMetalRoughMaterial);
+ d->m_exposureParameter->setValue(exposure);
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qmetalroughmaterial.h b/src/extras/defaults/qmetalroughmaterial.h
new file mode 100644
index 000000000..914cef6ca
--- /dev/null
+++ b/src/extras/defaults/qmetalroughmaterial.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QMETALROUGHMATERIAL_H
+#define QT3DEXTRAS_QMETALROUGHMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qmaterial.h>
+#include <QtGui/qcolor.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+class QAbstractTexture;
+}
+
+namespace Qt3DExtras {
+
+class QMetalRoughMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QMetalRoughMaterial : public Qt3DRender::QMaterial
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor baseColor READ baseColor WRITE setBaseColor NOTIFY baseColorChanged)
+ Q_PROPERTY(float metallic READ metallic WRITE setMetallic NOTIFY metallicChanged)
+ Q_PROPERTY(float roughness READ roughness WRITE setRoughness NOTIFY roughnessChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *environmentIrradiance READ environmentIrradiance WRITE setEnvironmentIrradiance NOTIFY environmentIrradianceChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *environmentSpecular READ environmentSpecular WRITE setEnvironmentSpecular NOTIFY environmentSpecularChanged)
+ Q_PROPERTY(float exposure READ exposure WRITE setExposure NOTIFY exposureChanged)
+
+public:
+ explicit QMetalRoughMaterial(Qt3DCore::QNode *parent = nullptr);
+ ~QMetalRoughMaterial();
+
+ QColor baseColor() const;
+ float metallic() const;
+ float roughness() const;
+ Qt3DRender::QAbstractTexture *environmentIrradiance() const;
+ Qt3DRender::QAbstractTexture *environmentSpecular() const;
+ float exposure() const;
+
+public Q_SLOTS:
+ void setBaseColor(const QColor &baseColor);
+ void setMetallic(float metallic);
+ void setRoughness(float roughness);
+ void setEnvironmentIrradiance(Qt3DRender::QAbstractTexture *environmentIrradiance);
+ void setEnvironmentSpecular(Qt3DRender::QAbstractTexture *environmentSpecular);
+ void setExposure(float exposure);
+
+Q_SIGNALS:
+ void baseColorChanged(const QColor &baseColor);
+ void metallicChanged(float metallic);
+ void roughnessChanged(float roughness);
+ void environmentIrradianceChanged(Qt3DRender::QAbstractTexture *environmentIrradiance);
+ void environmentSpecularChanged(Qt3DRender::QAbstractTexture *environmentSpecular);
+ void exposureChanged(float exposure);
+
+protected:
+ QMetalRoughMaterial(QMetalRoughMaterialPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+
+private:
+ Q_DECLARE_PRIVATE(QMetalRoughMaterial)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QMETALROUGHMATERIAL_H
diff --git a/src/extras/defaults/qmetalroughmaterial_p.h b/src/extras/defaults/qmetalroughmaterial_p.h
new file mode 100644
index 000000000..d287f0093
--- /dev/null
+++ b/src/extras/defaults/qmetalroughmaterial_p.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QMETALROUGHMATERIAL_P_H
+#define QT3DEXTRAS_QMETALROUGHMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QAbstractTexture;
+class QTechnique;
+class QParameter;
+class QShaderProgram;
+class QRenderPass;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QMetalRoughMaterial;
+
+class QMetalRoughMaterialPrivate : public Qt3DRender::QMaterialPrivate
+{
+public:
+ QMetalRoughMaterialPrivate();
+
+ void init();
+
+ void handleBaseColorChanged(const QVariant &var);
+ void handleMetallicChanged(const QVariant &var);
+ void handleRoughnessChanged(const QVariant &var);
+ void handleEnvironmentIrradianceChanged(const QVariant &var);
+ void handleEnvironmentSpecularChanged(const QVariant &var);
+ void handleExposureChanged(const QVariant &var);
+
+ Qt3DRender::QAbstractTexture *m_environmentIrradianceTexture;
+ Qt3DRender::QAbstractTexture *m_environmentSpecularTexture;
+ Qt3DRender::QParameter *m_baseColorParameter;
+ Qt3DRender::QParameter *m_metallicParameter;
+ Qt3DRender::QParameter *m_roughnessParameter;
+ Qt3DRender::QParameter *m_environmentIrradianceParameter;
+ Qt3DRender::QParameter *m_environmentSpecularParameter;
+ Qt3DRender::QParameter *m_exposureParameter;
+ Qt3DRender::QEffect *m_metalRoughEffect;
+ Qt3DRender::QTechnique *m_metalRoughGL3Technique;
+ Qt3DRender::QRenderPass *m_metalRoughGL3RenderPass;
+ Qt3DRender::QShaderProgram *m_metalRoughGL3Shader;
+ Qt3DRender::QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QMetalRoughMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QMETALROUGHMATERIAL_P_H
+
diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc
index 04437d599..133955e7d 100644
--- a/src/extras/extras.qrc
+++ b/src/extras/extras.qrc
@@ -41,6 +41,7 @@
<file>shaders/es2/unlittexture.vert</file>
<file>shaders/gl3/metalrough.vert</file>
<file>shaders/gl3/metalrough.frag</file>
+ <file>shaders/gl3/metalroughuniform.frag</file>
<file>shaders/gl3/distancefieldtext.vert</file>
<file>shaders/gl3/distancefieldtext.frag</file>
<file>shaders/es2/distancefieldtext.frag</file>
diff --git a/src/extras/shaders/gl3/metalroughuniform.frag b/src/extras/shaders/gl3/metalroughuniform.frag
new file mode 100644
index 000000000..dfc174e8b
--- /dev/null
+++ b/src/extras/shaders/gl3/metalroughuniform.frag
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#version 150
+
+in vec2 texCoord;
+in vec3 worldPosition;
+in vec3 worldNormal;
+in vec4 worldTangent;
+
+out vec4 fragColor;
+
+// Qt 3D built in uniforms
+uniform vec3 eyePosition; // World space eye position
+uniform float time; // Time in seconds
+
+// Pre-convolved environment maps
+uniform samplerCube skyIrradiance; // For diffuse contribution
+uniform samplerCube skySpecular; // For specular contribution
+
+// PBR Material maps
+uniform vec4 baseColor;
+uniform float metallic;
+uniform float roughness;
+
+// Roughness -> mip level mapping
+uniform float maxT = 0.939824;
+uniform float mipLevels = 11.0;
+uniform float mipOffset = 5.0;
+
+// Exposure correction
+uniform float exposure = 0.0;
+
+mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTangent)
+{
+ // Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
+ // This allows to build the tangentMatrix below by simply transposing the
+ // tangent -> eyespace matrix (which would now be orthogonal)
+ vec3 wFixedTangent = normalize(wTangent.xyz - dot(wTangent.xyz, wNormal) * wNormal);
+
+ // Calculate binormal vector. No "real" need to renormalize it,
+ // as built by crossing two normal vectors.
+ // To orient the binormal correctly, use the fourth coordinate of the tangent,
+ // which is +1 for a right hand system, and -1 for a left hand system.
+ vec3 wBinormal = cross(wNormal, wFixedTangent.xyz) * wTangent.w;
+
+ // Construct matrix to transform from world space to tangent space
+ // This is the transpose of the tangentToWorld transformation matrix
+ mat3 tangentToWorldMatrix = mat3(wFixedTangent, wBinormal, wNormal);
+ mat3 worldToTangentMatrix = transpose(tangentToWorldMatrix);
+ return worldToTangentMatrix;
+}
+
+float roughnessToMipLevel(float roughness)
+{
+ // HACK: Improve the roughness -> mip level mapping for roughness map from substace painter
+ // TODO: Use mathematica or similar to improve this mapping more generally
+ roughness = 0.75 + (1.7 * (roughness - 0.5));
+ return (mipLevels - 1.0 - mipOffset) * (1.0 - (1.0 - roughness) / maxT);
+}
+
+vec3 fresnelFactor(const in vec3 color, const in float cosineFactor)
+{
+ // Calculate the Fresnel effect value
+ vec3 f = color;
+ vec3 F = f + (1.0 - f) * pow(1.0 - cosineFactor, 5.0);
+ return clamp(F, f, vec3(1.0));
+}
+
+float geometricModel(const in float lDotN,
+ const in float vDotN,
+ const in vec3 h)
+{
+ // Implicit geometric model (equal to denominator in specular model).
+ // This currently assumes that there is no attenuation by geometric shadowing or
+ // masking according to the microfacet theory.
+ return 1.0;
+}
+
+vec3 specularModel(const in vec3 F0,
+ const in float lDotH,
+ const in float lDotN,
+ const in float vDotN,
+ const in vec3 n,
+ const in vec3 h)
+{
+ // Clamp lDotN and vDotN to small positive value to prevent the
+ // denominator in the reflection equation going to infinity. Balance this
+ // by using the clamped values in the geometric factor function to
+ // avoid ugly seams in the specular lighting.
+ float sDotNPrime = max(lDotN, 0.001);
+ float vDotNPrime = max(vDotN, 0.001);
+
+ vec3 F = fresnelFactor(F0, lDotH);
+ float G = geometricModel(sDotNPrime, vDotNPrime, h);
+
+ // TODO: Verify which parts of the BRDF Lys is preconvolving and multiply
+ // by the remaining factors here.
+ vec3 cSpec = F * G / (4.0 * sDotNPrime * vDotNPrime);
+ return clamp(cSpec, vec3(0.0), vec3(1.0));
+}
+
+vec3 pbrIblModel(const in vec3 wNormal,
+ const in vec3 wView,
+ const in vec3 baseColor,
+ const in float metallic,
+ const in float roughness)
+{
+ // Calculate reflection direction of view vector about surface normal
+ // vector in world space. This is used in the fragment shader to sample
+ // from the environment textures for a light source. This is equivalent
+ // to the l vector for punctual light sources. Armed with this, calculate
+ // the usual factors needed
+ vec3 n = wNormal;
+ vec3 l = reflect(-wView, n);
+ vec3 v = wView;
+ vec3 h = normalize(l + v);
+ float vDotN = dot(v, n);
+ float lDotN = dot(l, n);
+ float lDotH = dot(l, h);
+
+ // Calculate diffuse component
+ vec3 diffuseColor = (1.0 - metallic) * baseColor;
+ vec3 diffuse = diffuseColor * texture(skyIrradiance, l).rgb;
+
+ // Calculate specular component
+ vec3 dielectricColor = vec3(0.04);
+ vec3 F0 = mix(dielectricColor, baseColor, metallic);
+ vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h);
+
+ float lod = roughnessToMipLevel(roughness);
+ vec3 specularSkyColor = textureLod(skySpecular, l, lod).rgb;
+ vec3 specular = specularSkyColor * specularFactor;
+
+ // Blend between diffuse and specular to conserve energy
+ vec3 iblColor = specular + diffuse * (vec3(1.0) - specularFactor);
+
+ // Apply exposure correction
+ iblColor *= pow(2.0, exposure);
+
+ return iblColor;
+}
+
+vec3 toneMap(const in vec3 c)
+{
+ return c / (c + vec3(1.0));
+}
+
+vec3 gammaCorrect(const in vec3 color)
+{
+ const float gamma = 1.0 / 2.2;
+ return pow(color, vec3(gamma));
+}
+
+void main()
+{
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ vec3 cLinear = pbrIblModel(worldNormal,
+ worldView,
+ baseColor.rgb,
+ metallic,
+ roughness);
+
+ // Apply simple (Reinhard) tonemap transform to get into LDR range [0, 1]
+ vec3 cToneMapped = toneMap(cLinear);
+
+ // Apply gamma correction prior to display
+ vec3 cGamma = gammaCorrect(cToneMapped);
+ fragColor = vec4(cGamma, 1.0);
+}
diff --git a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
index ffa6be945..1edde1e19 100644
--- a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
+++ b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
@@ -46,6 +46,7 @@
#include <Qt3DExtras/qfirstpersoncameracontroller.h>
#include <Qt3DExtras/qforwardrenderer.h>
#include <Qt3DExtras/qgoochmaterial.h>
+#include <Qt3DExtras/qmetalroughmaterial.h>
#include <Qt3DExtras/qnormaldiffusemapalphamaterial.h>
#include <Qt3DExtras/qnormaldiffusemapmaterial.h>
#include <Qt3DExtras/qnormaldiffusespecularmapmaterial.h>
@@ -99,6 +100,7 @@ void Qt3DQuick3DExtrasPlugin::registerTypes(const char *uri)
qmlRegisterType<Qt3DExtras::QPerVertexColorMaterial>(uri, 2, 0, "PerVertexColorMaterial");
qmlRegisterType<Qt3DExtras::QGoochMaterial>(uri, 2, 0, "GoochMaterial");
qmlRegisterType<Qt3DExtras::QTextureMaterial>(uri, 2, 0, "TextureMaterial");
+ qmlRegisterType<Qt3DExtras::QMetalRoughMaterial>(uri, 2, 2, "MetalRoughMaterial");
qmlRegisterType<Qt3DExtras::QTexturedMetalRoughMaterial>(uri, 2, 2, "TexturedMetalRoughMaterial");
// Meshes