summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/extras/defaults/qmetalroughmaterial.cpp10
-rw-r--r--src/extras/defaults/qmetalroughmaterial_p.h2
-rw-r--r--src/extras/defaults/qtexturedmetalroughmaterial.cpp10
-rw-r--r--src/extras/defaults/qtexturedmetalroughmaterial_p.h2
-rw-r--r--src/extras/extras.qrc6
-rw-r--r--src/extras/shaders/gl3/coordinatesystems.inc70
-rw-r--r--src/extras/shaders/gl3/metalrough.frag395
-rw-r--r--src/extras/shaders/gl3/metalrough.inc.frag (renamed from src/extras/shaders/gl3/metalroughuniform.frag)89
-rw-r--r--src/extras/shaders/graphs/metalrough.frag.json290
-rw-r--r--src/extras/shaders/graphs/metalroughuniform.frag.json126
-rw-r--r--src/render/materialsystem/prototypes/default.json665
11 files changed, 1206 insertions, 459 deletions
diff --git a/src/extras/defaults/qmetalroughmaterial.cpp b/src/extras/defaults/qmetalroughmaterial.cpp
index ea213ab82..c42029300 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>
@@ -71,6 +72,7 @@ QMetalRoughMaterialPrivate::QMetalRoughMaterialPrivate()
, 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,6 +90,8 @@ QMetalRoughMaterialPrivate::QMetalRoughMaterialPrivate()
void QMetalRoughMaterialPrivate::init()
{
+ Q_Q(QMetalRoughMaterial);
+
connect(m_baseColorParameter, &Qt3DRender::QParameter::valueChanged,
this, &QMetalRoughMaterialPrivate::handleBaseColorChanged);
connect(m_metalnessParameter, &Qt3DRender::QParameter::valueChanged,
@@ -96,14 +100,16 @@ void QMetalRoughMaterialPrivate::init()
this, &QMetalRoughMaterialPrivate::handleRoughnessChanged);
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_metalRoughGL3ShaderBuilder->setParent(q);
+ m_metalRoughGL3ShaderBuilder->setShaderProgram(m_metalRoughGL3Shader);
+ m_metalRoughGL3ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/metalroughuniform.frag.json")));
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"));
diff --git a/src/extras/defaults/qmetalroughmaterial_p.h b/src/extras/defaults/qmetalroughmaterial_p.h
index 3090b9757..38ec0b78d 100644
--- a/src/extras/defaults/qmetalroughmaterial_p.h
+++ b/src/extras/defaults/qmetalroughmaterial_p.h
@@ -63,6 +63,7 @@ class QAbstractTexture;
class QTechnique;
class QParameter;
class QShaderProgram;
+class QShaderProgramBuilder;
class QRenderPass;
} // namespace Qt3DRender
@@ -93,6 +94,7 @@ public:
Qt3DRender::QTechnique *m_metalRoughGL3Technique;
Qt3DRender::QRenderPass *m_metalRoughGL3RenderPass;
Qt3DRender::QShaderProgram *m_metalRoughGL3Shader;
+ Qt3DRender::QShaderProgramBuilder *m_metalRoughGL3ShaderBuilder;
Qt3DRender::QFilterKey *m_filterKey;
Q_DECLARE_PUBLIC(QMetalRoughMaterial)
diff --git a/src/extras/defaults/qtexturedmetalroughmaterial.cpp b/src/extras/defaults/qtexturedmetalroughmaterial.cpp
index e09517866..9de8ec522 100644
--- a/src/extras/defaults/qtexturedmetalroughmaterial.cpp
+++ b/src/extras/defaults/qtexturedmetalroughmaterial.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>
@@ -78,6 +79,7 @@ QTexturedMetalRoughMaterialPrivate::QTexturedMetalRoughMaterialPrivate()
, m_metalRoughGL3Technique(new QTechnique())
, m_metalRoughGL3RenderPass(new QRenderPass())
, m_metalRoughGL3Shader(new QShaderProgram())
+ , m_metalRoughGL3ShaderBuilder(new QShaderProgramBuilder())
, m_filterKey(new QFilterKey)
{
m_baseColorTexture->setMagnificationFilter(QAbstractTexture::Linear);
@@ -125,6 +127,8 @@ QTexturedMetalRoughMaterialPrivate::QTexturedMetalRoughMaterialPrivate()
void QTexturedMetalRoughMaterialPrivate::init()
{
+ Q_Q(QTexturedMetalRoughMaterial);
+
connect(m_baseColorParameter, &Qt3DRender::QParameter::valueChanged,
this, &QTexturedMetalRoughMaterialPrivate::handleBaseColorChanged);
connect(m_metalnessParameter, &Qt3DRender::QParameter::valueChanged,
@@ -137,14 +141,16 @@ void QTexturedMetalRoughMaterialPrivate::init()
this, &QTexturedMetalRoughMaterialPrivate::handleNormalChanged);
m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalrough.vert"))));
- m_metalRoughGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalrough.frag"))));
+
+ m_metalRoughGL3ShaderBuilder->setParent(q);
+ m_metalRoughGL3ShaderBuilder->setShaderProgram(m_metalRoughGL3Shader);
+ m_metalRoughGL3ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/metalrough.frag.json")));
m_metalRoughGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
m_metalRoughGL3Technique->graphicsApiFilter()->setMajorVersion(3);
m_metalRoughGL3Technique->graphicsApiFilter()->setMinorVersion(1);
m_metalRoughGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
- Q_Q(QTexturedMetalRoughMaterial);
m_filterKey->setParent(q);
m_filterKey->setName(QStringLiteral("renderingStyle"));
m_filterKey->setValue(QStringLiteral("forward"));
diff --git a/src/extras/defaults/qtexturedmetalroughmaterial_p.h b/src/extras/defaults/qtexturedmetalroughmaterial_p.h
index 8972726e5..63d5c7d6f 100644
--- a/src/extras/defaults/qtexturedmetalroughmaterial_p.h
+++ b/src/extras/defaults/qtexturedmetalroughmaterial_p.h
@@ -63,6 +63,7 @@ class QAbstractTexture;
class QTechnique;
class QParameter;
class QShaderProgram;
+class QShaderProgramBuilder;
class QRenderPass;
} // namespace Qt3DRender
@@ -102,6 +103,7 @@ public:
Qt3DRender::QTechnique *m_metalRoughGL3Technique;
Qt3DRender::QRenderPass *m_metalRoughGL3RenderPass;
Qt3DRender::QShaderProgram *m_metalRoughGL3Shader;
+ Qt3DRender::QShaderProgramBuilder *m_metalRoughGL3ShaderBuilder;
Qt3DRender::QFilterKey *m_filterKey;
Q_DECLARE_PUBLIC(QTexturedMetalRoughMaterial)
diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc
index 9fce08a9f..609f5b9ca 100644
--- a/src/extras/extras.qrc
+++ b/src/extras/extras.qrc
@@ -1,8 +1,12 @@
<RCC>
<qresource prefix="/">
+ <file>shaders/graphs/metalrough.frag.json</file>
+ <file>shaders/graphs/metalroughuniform.frag.json</file>
<file>shaders/gl3/light.inc.frag</file>
<file>shaders/es2/light.inc.frag</file>
<file>shaders/es2/light.inc.frag100</file>
+ <file>shaders/gl3/metalrough.inc.frag</file>
+ <file>shaders/gl3/coordinatesystems.inc</file>
<file>shaders/gl3/phong.vert</file>
<file>shaders/gl3/phong.frag</file>
<file>shaders/es2/phong.vert</file>
@@ -40,8 +44,6 @@
<file>shaders/es2/unlittexture.frag</file>
<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/coordinatesystems.inc b/src/extras/shaders/gl3/coordinatesystems.inc
new file mode 100644
index 000000000..ed3d2cb92
--- /dev/null
+++ b/src/extras/shaders/gl3/coordinatesystems.inc
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+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;
+}
+
diff --git a/src/extras/shaders/gl3/metalrough.frag b/src/extras/shaders/gl3/metalrough.frag
deleted file mode 100644
index 7f2f3d20e..000000000
--- a/src/extras/shaders/gl3/metalrough.frag
+++ /dev/null
@@ -1,395 +0,0 @@
-/****************************************************************************
-**
-** 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
-
-// PBR Material maps
-uniform sampler2D baseColorMap;
-uniform sampler2D metalnessMap;
-uniform sampler2D roughnessMap;
-uniform sampler2D normalMap;
-uniform sampler2D ambientOcclusionMap;
-
-// User control parameters
-uniform float metalFactor = 1.0;
-
-// Exposure correction
-uniform float exposure = 0.0;
-// Gamma correction
-uniform float gamma = 2.2;
-
-#pragma include light.inc.frag
-
-int mipLevelCount(const in samplerCube cube)
-{
- int baseSize = textureSize(cube, 0).x;
- int nMips = int(log2(float(baseSize>0 ? baseSize : 1))) + 1;
- return nMips;
-}
-
-float remapRoughness(const in float roughness)
-{
- // As per page 14 of
- // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
- // we remap the roughness to give a more perceptually linear response
- // of "bluriness" as a function of the roughness specified by the user.
- // r = roughness^2
- const float maxSpecPower = 999999.0;
- const float minRoughness = sqrt(2.0 / (maxSpecPower + 2));
- return max(roughness * roughness, minRoughness);
-}
-
-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 alphaToMipLevel(float alpha)
-{
- float specPower = 2.0 / (alpha * alpha) - 2.0;
-
- // We use the mip level calculation from Lys' default power drop, which in
- // turn is a slight modification of that used in Marmoset Toolbag. See
- // https://docs.knaldtech.com/doku.php?id=specular_lys for details.
- // For now we assume a max specular power of 999999 which gives
- // maxGlossiness = 1.
- const float k0 = 0.00098;
- const float k1 = 0.9921;
- float glossiness = (pow(2.0, -10.0 / sqrt(specPower)) - k0) / k1;
-
- // TODO: Optimize by doing this on CPU and set as
- // uniform int envLight.specularMipLevels say (if present in shader).
- // Lookup the number of mips in the specular envmap
- int mipLevels = mipLevelCount(envLight.specular);
-
- // Offset of smallest miplevel we should use (corresponds to specular
- // power of 1). I.e. in the 32x32 sized mip.
- const float mipOffset = 5.0;
-
- // The final factor is really 1 - g / g_max but as mentioned above g_max
- // is 1 by definition here so we can avoid the division. If we make the
- // max specular power for the spec map configurable, this will need to
- // be handled properly.
- float mipLevel = (mipLevels - 1.0 - mipOffset) * (1.0 - glossiness);
- return mipLevel;
-}
-
-float normalDistribution(const in vec3 n, const in vec3 h, const in float alpha)
-{
- // Blinn-Phong approximation - see
- // http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html
- float specPower = 2.0 / (alpha * alpha) - 2.0;
- return (specPower + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), specPower);
-}
-
-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 lDotN * vDotN;
-}
-
-vec3 specularModel(const in vec3 F0,
- const in float sDotH,
- const in float sDotN,
- const in float vDotN,
- const in vec3 n,
- const in vec3 h)
-{
- // Clamp sDotN 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(sDotN, 0.001);
- float vDotNPrime = max(vDotN, 0.001);
-
- vec3 F = fresnelFactor(F0, sDotH);
- float G = geometricModel(sDotNPrime, vDotNPrime, h);
-
- vec3 cSpec = F * G / (4.0 * sDotNPrime * vDotNPrime);
- return clamp(cSpec, vec3(0.0), vec3(1.0));
-}
-
-vec3 pbrModel(const in int lightIndex,
- const in vec3 wPosition,
- const in vec3 wNormal,
- const in vec3 wView,
- const in vec3 baseColor,
- const in float metalness,
- const in float alpha,
- const in float ambientOcclusion)
-{
- // Calculate some useful quantities
- vec3 n = wNormal;
- vec3 s = vec3(0.0);
- vec3 v = wView;
- vec3 h = vec3(0.0);
-
- float vDotN = dot(v, n);
- float sDotN = 0.0;
- float sDotH = 0.0;
- float att = 1.0;
-
- if (lights[lightIndex].type != TYPE_DIRECTIONAL) {
- // Point and Spot lights
- vec3 sUnnormalized = vec3(lights[lightIndex].position) - wPosition;
- s = normalize(sUnnormalized);
-
- // Calculate the attenuation factor
- sDotN = dot(s, n);
- if (sDotN > 0.0) {
- if (lights[lightIndex].constantAttenuation != 0.0
- || lights[lightIndex].linearAttenuation != 0.0
- || lights[lightIndex].quadraticAttenuation != 0.0) {
- float dist = length(sUnnormalized);
- att = 1.0 / (lights[lightIndex].constantAttenuation +
- lights[lightIndex].linearAttenuation * dist +
- lights[lightIndex].quadraticAttenuation * dist * dist);
- }
-
- // The light direction is in world space already
- if (lights[lightIndex].type == TYPE_SPOT) {
- // Check if fragment is inside or outside of the spot light cone
- if (degrees(acos(dot(-s, lights[lightIndex].direction))) > lights[lightIndex].cutOffAngle)
- sDotN = 0.0;
- }
- }
- } else {
- // Directional lights
- // The light direction is in world space already
- s = normalize(-lights[lightIndex].direction);
- sDotN = dot(s, n);
- }
-
- h = normalize(s + v);
- sDotH = dot(s, h);
-
- // Calculate diffuse component
- vec3 diffuseColor = (1.0 - metalness) * baseColor;
- vec3 diffuse = diffuseColor * max(sDotN, 0.0) / 3.14159;
-
- // Calculate specular component
- vec3 dielectricColor = vec3(0.04);
- vec3 F0 = mix(dielectricColor, baseColor, metalness);
- vec3 specularFactor = vec3(0.0);
- if (sDotN > 0.0) {
- specularFactor = specularModel(F0, sDotH, sDotN, vDotN, n, h);
- specularFactor *= normalDistribution(n, h, alpha);
- }
- vec3 specularColor = lights[lightIndex].color;
- vec3 specular = specularColor * specularFactor;
-
- // Blend between diffuse and specular to conserver energy
- vec3 color = lights[lightIndex].intensity * (specular + diffuse * (vec3(1.0) - specular));
-
- // Reduce by ambient occlusion amount
- color *= ambientOcclusion;
-
- return color;
-}
-
-vec3 pbrIblModel(const in vec3 wNormal,
- const in vec3 wView,
- const in vec3 baseColor,
- const in float metalness,
- const in float alpha,
- const in float ambientOcclusion)
-{
- // 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 - metalness) * baseColor;
- vec3 diffuse = diffuseColor * texture(envLight.irradiance, l).rgb;
-
- // Calculate specular component
- vec3 dielectricColor = vec3(0.04);
- vec3 F0 = mix(dielectricColor, baseColor, metalness);
- vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h);
-
- float lod = alphaToMipLevel(alpha);
-//#define DEBUG_SPECULAR_LODS
-#ifdef DEBUG_SPECULAR_LODS
- if (lod > 7.0)
- return vec3(1.0, 0.0, 0.0);
- else if (lod > 6.0)
- return vec3(1.0, 0.333, 0.0);
- else if (lod > 5.0)
- return vec3(1.0, 1.0, 0.0);
- else if (lod > 4.0)
- return vec3(0.666, 1.0, 0.0);
- else if (lod > 3.0)
- return vec3(0.0, 1.0, 0.666);
- else if (lod > 2.0)
- return vec3(0.0, 0.666, 1.0);
- else if (lod > 1.0)
- return vec3(0.0, 0.0, 1.0);
- else if (lod > 0.0)
- return vec3(1.0, 0.0, 1.0);
-#endif
- vec3 specularSkyColor = textureLod(envLight.specular, l, lod).rgb;
- vec3 specular = specularSkyColor * specularFactor;
-
- // Blend between diffuse and specular to conserve energy
- vec3 iblColor = specular + diffuse * (vec3(1.0) - specularFactor);
-
- // Reduce by ambient occlusion amount
- iblColor *= ambientOcclusion;
-
- return iblColor;
-}
-
-vec3 toneMap(const in vec3 c)
-{
- return c / (c + vec3(1.0));
-}
-
-vec3 gammaCorrect(const in vec3 color)
-{
- return pow(color, vec3(1.0 / gamma));
-}
-
-void main()
-{
- vec3 cLinear = vec3(0.0);
-
- // Calculate the perturbed texture coordinates from parallax occlusion mapping
- mat3 worldToTangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
- vec3 wView = normalize(eyePosition - worldPosition);
- vec3 tView = worldToTangentMatrix * wView;
-
- // Sample the inputs needed for the metal-roughness PBR BRDF
- vec3 baseColor = texture(baseColorMap, texCoord).rgb;
- float metalness = texture(metalnessMap, texCoord).r * metalFactor;
- float roughness = texture(roughnessMap, texCoord).r;
- float ambientOcclusion = texture(ambientOcclusionMap, texCoord).r;
- vec3 tNormal = 2.0 * texture(normalMap, texCoord).rgb - vec3(1.0);
- vec3 wNormal = normalize(transpose(worldToTangentMatrix) * tNormal);
-
- // Remap roughness for a perceptually more linear correspondence
- float alpha = remapRoughness(roughness);
-
- for (int i = 0; i < envLightCount; ++i) {
- cLinear += pbrIblModel(wNormal,
- wView,
- baseColor,
- metalness,
- alpha,
- ambientOcclusion);
- }
-
- for (int i = 0; i < lightCount; ++i) {
- cLinear += pbrModel(i,
- worldPosition,
- wNormal,
- wView,
- baseColor.rgb,
- metalness,
- alpha,
- ambientOcclusion);
- }
-
- // Apply exposure correction
- cLinear *= pow(2.0, exposure);
-
- // 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/extras/shaders/gl3/metalroughuniform.frag b/src/extras/shaders/gl3/metalrough.inc.frag
index f4bad0a00..f7e3eecb7 100644
--- a/src/extras/shaders/gl3/metalroughuniform.frag
+++ b/src/extras/shaders/gl3/metalrough.inc.frag
@@ -48,24 +48,6 @@
**
****************************************************************************/
-#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
-
-// PBR Material maps
-uniform vec4 baseColor;
-uniform float metalness;
-uniform float roughness;
-
// Exposure correction
uniform float exposure = 0.0;
// Gamma correction
@@ -76,7 +58,7 @@ uniform float gamma = 2.2;
int mipLevelCount(const in samplerCube cube)
{
int baseSize = textureSize(cube, 0).x;
- int nMips = int(log2(float(baseSize>0 ? baseSize : 1))) + 1;
+ int nMips = int(log2(float(baseSize > 0 ? baseSize : 1))) + 1;
return nMips;
}
@@ -92,26 +74,6 @@ float remapRoughness(const in float roughness)
return max(roughness * roughness, minRoughness);
}
-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 alphaToMipLevel(float alpha)
{
float specPower = 2.0 / (alpha * alpha) - 2.0;
@@ -195,7 +157,8 @@ vec3 pbrModel(const in int lightIndex,
const in vec3 wView,
const in vec3 baseColor,
const in float metalness,
- const in float alpha)
+ const in float alpha,
+ const in float ambientOcclusion)
{
// Calculate some useful quantities
vec3 n = wNormal;
@@ -258,14 +221,20 @@ vec3 pbrModel(const in int lightIndex,
vec3 specular = specularColor * specularFactor;
// Blend between diffuse and specular to conserver energy
- return att * lights[lightIndex].intensity * (specular + diffuse * (vec3(1.0) - specular));
+ vec3 color = att * lights[lightIndex].intensity * (specular + diffuse * (vec3(1.0) - specular));
+
+ // Reduce by ambient occlusion amount
+ color *= ambientOcclusion;
+
+ return color;
}
vec3 pbrIblModel(const in vec3 wNormal,
const in vec3 wView,
const in vec3 baseColor,
const in float metalness,
- const in float alpha)
+ const in float alpha,
+ const in float ambientOcclusion)
{
// Calculate reflection direction of view vector about surface normal
// vector in world space. This is used in the fragment shader to sample
@@ -289,11 +258,6 @@ vec3 pbrIblModel(const in vec3 wNormal,
vec3 F0 = mix(dielectricColor, baseColor, metalness);
vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h);
- // As per page 14 of
- // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
- // we remap the roughness to give a more perceptually linear response
- // of "bluriness" as a function of the roughness specified by the user.
- // r = roughness^2
float lod = alphaToMipLevel(alpha);
//#define DEBUG_SPECULAR_LODS
#ifdef DEBUG_SPECULAR_LODS
@@ -318,7 +282,12 @@ vec3 pbrIblModel(const in vec3 wNormal,
vec3 specular = specularSkyColor * specularFactor;
// Blend between diffuse and specular to conserve energy
- return specular + diffuse * (vec3(1.0) - specularFactor);
+ vec3 color = specular + diffuse * (vec3(1.0) - specularFactor);
+
+ // Reduce by ambient occlusion amount
+ color *= ambientOcclusion;
+
+ return color;
}
vec3 toneMap(const in vec3 c)
@@ -331,32 +300,37 @@ vec3 gammaCorrect(const in vec3 color)
return pow(color, vec3(1.0 / gamma));
}
-void main()
+vec4 metalRoughFunction(const in vec4 baseColor,
+ const in float metalness,
+ const in float roughness,
+ const in float ambientOcclusion,
+ const in vec3 worldPosition,
+ const in vec3 worldView,
+ const in vec3 worldNormal)
{
vec3 cLinear = vec3(0.0);
// Remap roughness for a perceptually more linear correspondence
float alpha = remapRoughness(roughness);
-
- vec3 wNormal = normalize(worldNormal);
- vec3 worldView = normalize(eyePosition - worldPosition);
for (int i = 0; i < envLightCount; ++i) {
- cLinear += pbrIblModel(wNormal,
+ cLinear += pbrIblModel(worldNormal,
worldView,
baseColor.rgb,
metalness,
- alpha);
+ alpha,
+ ambientOcclusion);
}
for (int i = 0; i < lightCount; ++i) {
cLinear += pbrModel(i,
worldPosition,
- wNormal,
+ worldNormal,
worldView,
baseColor.rgb,
metalness,
- alpha);
+ alpha,
+ ambientOcclusion);
}
// Apply exposure correction
@@ -367,5 +341,6 @@ void main()
// Apply gamma correction prior to display
vec3 cGamma = gammaCorrect(cToneMapped);
- fragColor = vec4(cGamma, 1.0);
+
+ return vec4(cGamma, 1.0);
}
diff --git a/src/extras/shaders/graphs/metalrough.frag.json b/src/extras/shaders/graphs/metalrough.frag.json
new file mode 100644
index 000000000..2e200bf15
--- /dev/null
+++ b/src/extras/shaders/graphs/metalrough.frag.json
@@ -0,0 +1,290 @@
+{
+ "nodes": [
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000001}",
+ "type": "worldPosition"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000002}",
+ "type": "eyePosition"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000003}",
+ "type": "worldNormal"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000004}",
+ "type": "worldTangent"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000005}",
+ "type": "texCoord"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000006}",
+ "type": "sampleBaseColorMap"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000007}",
+ "type": "sampleMetalnessMap"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000008}",
+ "type": "sampleRoughnessMap"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000009}",
+ "type": "sampleAmbientOcclusionMap"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000010}",
+ "type": "sampleNormalMap"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000011}",
+ "type": "substractVec3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000012}",
+ "type": "normalizeVec3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000013}",
+ "type": "worldSpaceToTangentSpaceMatrix"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000014}",
+ "type": "transposeMat3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000015}",
+ "type": "multiplyVec3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000016}",
+ "type": "normalizeVec3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000017}",
+ "type": "swizzleR"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000018}",
+ "type": "swizzleR"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000019}",
+ "type": "swizzleR"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000020}",
+ "type": "swizzleRGB"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000021}",
+ "type": "constantTwo"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000022}",
+ "type": "multiplyVec3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000023}",
+ "type": "constantVec3One"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000024}",
+ "type": "substractVec3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000025}",
+ "type": "metalRoughFunction"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000026}",
+ "type": "fragColor"
+ }
+ ],
+ "edges": [
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000001}",
+ "sourcePort": "worldPosition",
+ "targetUuid": "{00000000-0000-0000-0000-000000000025}",
+ "targetPort": "worldPosition"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000001}",
+ "sourcePort": "worldPosition",
+ "targetUuid": "{00000000-0000-0000-0000-000000000011}",
+ "targetPort": "substrahend"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000002}",
+ "sourcePort": "eyePosition",
+ "targetUuid": "{00000000-0000-0000-0000-000000000011}",
+ "targetPort": "minuend"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000011}",
+ "sourcePort": "difference",
+ "targetUuid": "{00000000-0000-0000-0000-000000000012}",
+ "targetPort": "input"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000012}",
+ "sourcePort": "output",
+ "targetUuid": "{00000000-0000-0000-0000-000000000025}",
+ "targetPort": "worldView"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000003}",
+ "sourcePort": "worldNormal",
+ "targetUuid": "{00000000-0000-0000-0000-000000000013}",
+ "targetPort": "worldNormal"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000004}",
+ "sourcePort": "worldTangent",
+ "targetUuid": "{00000000-0000-0000-0000-000000000013}",
+ "targetPort": "worldTangent"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000013}",
+ "sourcePort": "matrix",
+ "targetUuid": "{00000000-0000-0000-0000-000000000014}",
+ "targetPort": "input"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000014}",
+ "sourcePort": "output",
+ "targetUuid": "{00000000-0000-0000-0000-000000000015}",
+ "targetPort": "first"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000005}",
+ "sourcePort": "texCoord",
+ "targetUuid": "{00000000-0000-0000-0000-000000000010}",
+ "targetPort": "coord"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000010}",
+ "sourcePort": "color",
+ "targetUuid": "{00000000-0000-0000-0000-000000000020}",
+ "targetPort": "input"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000020}",
+ "sourcePort": "output",
+ "targetUuid": "{00000000-0000-0000-0000-000000000022}",
+ "targetPort": "first"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000021}",
+ "sourcePort": "two",
+ "targetUuid": "{00000000-0000-0000-0000-000000000022}",
+ "targetPort": "second"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000022}",
+ "sourcePort": "product",
+ "targetUuid": "{00000000-0000-0000-0000-000000000024}",
+ "targetPort": "minuend"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000023}",
+ "sourcePort": "one",
+ "targetUuid": "{00000000-0000-0000-0000-000000000024}",
+ "targetPort": "substrahend"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000024}",
+ "sourcePort": "difference",
+ "targetUuid": "{00000000-0000-0000-0000-000000000015}",
+ "targetPort": "second"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000015}",
+ "sourcePort": "product",
+ "targetUuid": "{00000000-0000-0000-0000-000000000016}",
+ "targetPort": "input"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000016}",
+ "sourcePort": "output",
+ "targetUuid": "{00000000-0000-0000-0000-000000000025}",
+ "targetPort": "worldNormal"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000005}",
+ "sourcePort": "texCoord",
+ "targetUuid": "{00000000-0000-0000-0000-000000000006}",
+ "targetPort": "coord"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000006}",
+ "sourcePort": "color",
+ "targetUuid": "{00000000-0000-0000-0000-000000000025}",
+ "targetPort": "baseColor"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000005}",
+ "sourcePort": "texCoord",
+ "targetUuid": "{00000000-0000-0000-0000-000000000007}",
+ "targetPort": "coord"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000007}",
+ "sourcePort": "color",
+ "targetUuid": "{00000000-0000-0000-0000-000000000017}",
+ "targetPort": "input"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000017}",
+ "sourcePort": "output",
+ "targetUuid": "{00000000-0000-0000-0000-000000000025}",
+ "targetPort": "metalness"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000005}",
+ "sourcePort": "texCoord",
+ "targetUuid": "{00000000-0000-0000-0000-000000000008}",
+ "targetPort": "coord"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000008}",
+ "sourcePort": "color",
+ "targetUuid": "{00000000-0000-0000-0000-000000000018}",
+ "targetPort": "input"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000018}",
+ "sourcePort": "output",
+ "targetUuid": "{00000000-0000-0000-0000-000000000025}",
+ "targetPort": "roughness"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000005}",
+ "sourcePort": "texCoord",
+ "targetUuid": "{00000000-0000-0000-0000-000000000009}",
+ "targetPort": "coord"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000009}",
+ "sourcePort": "color",
+ "targetUuid": "{00000000-0000-0000-0000-000000000019}",
+ "targetPort": "input"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000019}",
+ "sourcePort": "output",
+ "targetUuid": "{00000000-0000-0000-0000-000000000025}",
+ "targetPort": "ambientOcclusion"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000025}",
+ "sourcePort": "outputColor",
+ "targetUuid": "{00000000-0000-0000-0000-000000000026}",
+ "targetPort": "fragColor"
+ }
+ ]
+}
diff --git a/src/extras/shaders/graphs/metalroughuniform.frag.json b/src/extras/shaders/graphs/metalroughuniform.frag.json
new file mode 100644
index 000000000..8abfc57b4
--- /dev/null
+++ b/src/extras/shaders/graphs/metalroughuniform.frag.json
@@ -0,0 +1,126 @@
+{
+ "nodes": [
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000001}",
+ "type": "worldPosition"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000002}",
+ "type": "worldNormal"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000003}",
+ "type": "eyePosition"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000004}",
+ "type": "baseColor"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000005}",
+ "type": "metalness"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000006}",
+ "type": "roughness"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000007}",
+ "type": "ambientOcclusion"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000008}",
+ "type": "normalizeVec3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000009}",
+ "type": "substractVec3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-00000000000a}",
+ "type": "normalizeVec3"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-00000000000b}",
+ "type": "metalRoughFunction"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-00000000000c}",
+ "type": "fragColor"
+ }
+ ],
+ "edges": [
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000001}",
+ "sourcePort": "worldPosition",
+ "targetUuid": "{00000000-0000-0000-0000-00000000000b}",
+ "targetPort": "worldPosition"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000001}",
+ "sourcePort": "worldPosition",
+ "targetUuid": "{00000000-0000-0000-0000-000000000009}",
+ "targetPort": "substrahend"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000002}",
+ "sourcePort": "worldNormal",
+ "targetUuid": "{00000000-0000-0000-0000-000000000008}",
+ "targetPort": "input"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000003}",
+ "sourcePort": "eyePosition",
+ "targetUuid": "{00000000-0000-0000-0000-000000000009}",
+ "targetPort": "minuend"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000004}",
+ "sourcePort": "baseColor",
+ "targetUuid": "{00000000-0000-0000-0000-00000000000b}",
+ "targetPort": "baseColor"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000005}",
+ "sourcePort": "metalness",
+ "targetUuid": "{00000000-0000-0000-0000-00000000000b}",
+ "targetPort": "metalness"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000006}",
+ "sourcePort": "roughness",
+ "targetUuid": "{00000000-0000-0000-0000-00000000000b}",
+ "targetPort": "roughness"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000007}",
+ "sourcePort": "ambientOcclusion",
+ "targetUuid": "{00000000-0000-0000-0000-00000000000b}",
+ "targetPort": "ambientOcclusion"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000008}",
+ "sourcePort": "output",
+ "targetUuid": "{00000000-0000-0000-0000-00000000000b}",
+ "targetPort": "worldNormal"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000009}",
+ "sourcePort": "difference",
+ "targetUuid": "{00000000-0000-0000-0000-00000000000a}",
+ "targetPort": "input"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-00000000000a}",
+ "sourcePort": "output",
+ "targetUuid": "{00000000-0000-0000-0000-00000000000b}",
+ "targetPort": "worldView"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-00000000000b}",
+ "sourcePort": "outputColor",
+ "targetUuid": "{00000000-0000-0000-0000-00000000000c}",
+ "targetPort": "fragColor"
+ }
+ ]
+}
diff --git a/src/render/materialsystem/prototypes/default.json b/src/render/materialsystem/prototypes/default.json
index da9f0534d..5dad2e555 100644
--- a/src/render/materialsystem/prototypes/default.json
+++ b/src/render/materialsystem/prototypes/default.json
@@ -17,11 +17,674 @@
"format": {
"api": "OpenGLCoreProfile",
"major": 3,
- "minor": 2
+ "minor": 0
},
"substitution": "vec3 $worldPosition = worldPosition;",
"headerSnippets": [ "in vec3 worldPosition;" ]
}
]
+ },
+ "worldNormal": {
+ "outputs": [
+ "worldNormal"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec3 $worldNormal = worldNormal;",
+ "headerSnippets": [ "varying highp vec3 worldNormal;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec3 $worldNormal = worldNormal;",
+ "headerSnippets": [ "in vec3 worldNormal;" ]
+ }
+ ]
+ },
+ "worldTangent": {
+ "outputs": [
+ "worldTangent"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $worldTangent = worldTangent;",
+ "headerSnippets": [ "varying highp vec4 worldTangent;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec4 $worldTangent = worldTangent;",
+ "headerSnippets": [ "in vec4 worldTangent;" ]
+ }
+ ]
+ },
+ "texCoord": {
+ "outputs": [
+ "texCoord"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec2 $texCoord = texCoord;",
+ "headerSnippets": [ "varying highp vec2 texCoord;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec2 $texCoord = texCoord;",
+ "headerSnippets": [ "in vec2 texCoord;" ]
+ }
+ ]
+ },
+ "fragColor": {
+ "inputs": [
+ "fragColor"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "gl_fragColor = $fragColor;"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "fragColor = $fragColor;",
+ "headerSnippets": [ "out vec4 fragColor;" ]
+ }
+ ]
+ },
+ "eyePosition": {
+ "outputs": [
+ "eyePosition"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec3 $eyePosition = eyePosition;",
+ "headerSnippets": [ "uniform highp vec3 eyePosition;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec3 $eyePosition = eyePosition;",
+ "headerSnippets": [ "uniform vec3 eyePosition;" ]
+ }
+ ]
+ },
+ "time": {
+ "outputs": [
+ "time"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp float $time = time;",
+ "headerSnippets": [ "uniform highp float time;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "float $time = time;",
+ "headerSnippets": [ "uniform float time;" ]
+ }
+ ]
+ },
+ "baseColor": {
+ "outputs": [
+ "baseColor"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $baseColor = baseColor;",
+ "headerSnippets": [ "uniform highp vec4 baseColor;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec4 $baseColor = baseColor;",
+ "headerSnippets": [ "uniform vec4 baseColor;" ]
+ }
+ ]
+ },
+ "metalness": {
+ "outputs": [
+ "metalness"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp float $metalness = metalness;",
+ "headerSnippets": [ "uniform highp float metalness;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "float $metalness = metalness;",
+ "headerSnippets": [ "uniform float metalness;" ]
+ }
+ ]
+ },
+ "roughness": {
+ "outputs": [
+ "roughness"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp float $roughness = roughness;",
+ "headerSnippets": [ "uniform highp float roughness;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "float $roughness = roughness;",
+ "headerSnippets": [ "uniform float roughness;" ]
+ }
+ ]
+ },
+ "ambientOcclusion": {
+ "outputs": [
+ "ambientOcclusion"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp float $ambientOcclusion = 1.0;"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "float $ambientOcclusion = 1.0;"
+ }
+ ]
+ },
+ "constantTwo": {
+ "outputs": [
+ "two"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp float $two = 2.0;"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "float $two = 2.0;"
+ }
+ ]
+ },
+ "constantVec3One": {
+ "outputs": [
+ "one"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec3 $one = vec3(1.0);"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec3 $one = vec3(1.0);"
+ }
+ ]
+ },
+ "sampleBaseColorMap": {
+ "inputs": [
+ "coord"
+ ],
+ "outputs": [
+ "color"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $color = texture2D(baseColorMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D baseColorMap;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec4 $color = texture2D(baseColorMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D baseColorMap;" ]
+ }
+ ]
+ },
+ "sampleMetalnessMap": {
+ "inputs": [
+ "coord"
+ ],
+ "outputs": [
+ "color"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $color = texture2D(metalnessMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D metalnessMap;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec4 $color = texture2D(metalnessMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D metalnessMap;" ]
+ }
+ ]
+ },
+ "sampleRoughnessMap": {
+ "inputs": [
+ "coord"
+ ],
+ "outputs": [
+ "color"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $color = texture2D(roughnessMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D roughnessMap;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec4 $color = texture2D(roughnessMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D roughnessMap;" ]
+ }
+ ]
+ },
+ "sampleAmbientOcclusionMap": {
+ "inputs": [
+ "coord"
+ ],
+ "outputs": [
+ "color"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $color = texture2D(ambientOcclusionMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D ambientOcclusionMap;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec4 $color = texture2D(ambientOcclusionMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D ambientOcclusionMap;" ]
+ }
+ ]
+ },
+ "sampleNormalMap": {
+ "inputs": [
+ "coord"
+ ],
+ "outputs": [
+ "color"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $color = texture2D(normalMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D normalMap;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec4 $color = texture2D(normalMap, $coord);",
+ "headerSnippets": [ "uniform sampler2D normalMap;" ]
+ }
+ ]
+ },
+ "transposeMat3": {
+ "inputs": [
+ "input"
+ ],
+ "outputs": [
+ "output"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp mat3 $output = transpose($input);"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "mat3 $output = transpose($input);"
+ }
+ ]
+ },
+ "normalizeVec3": {
+ "inputs": [
+ "input"
+ ],
+ "outputs": [
+ "output"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec3 $output = normalize($input);"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec3 $output = normalize($input);"
+ }
+ ]
+ },
+ "substractVec3": {
+ "inputs": [
+ "minuend",
+ "substrahend"
+ ],
+ "outputs": [
+ "difference"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec3 $difference = $minuend - $substrahend;"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec3 $difference = $minuend - $substrahend;"
+ }
+ ]
+ },
+ "addVec3": {
+ "inputs": [
+ "first",
+ "second"
+ ],
+ "outputs": [
+ "sum"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec3 $sum = $first + $second;"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec3 $sum = $first + $second;"
+ }
+ ]
+ },
+ "multiplyVec3": {
+ "inputs": [
+ "first",
+ "second"
+ ],
+ "outputs": [
+ "product"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec3 $product = $first * $second;"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec3 $product = $first * $second;"
+ }
+ ]
+ },
+ "swizzleRGB": {
+ "inputs": [
+ "input"
+ ],
+ "outputs": [
+ "output"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec3 $output = $input.rgb;"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec3 $output = $input.rgb;"
+ }
+ ]
+ },
+ "swizzleR": {
+ "inputs": [
+ "input"
+ ],
+ "outputs": [
+ "output"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp float $output = $input.r;"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "float $output = $input.r;"
+ }
+ ]
+ },
+ "worldSpaceToTangentSpaceMatrix": {
+ "inputs": [
+ "worldNormal",
+ "worldTangent"
+ ],
+ "outputs": [
+ "matrix"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "mat3 $matrix = calcWorldSpaceToTangentSpaceMatrix($worldNormal, $worldTangent);",
+ "headerSnippets": [ "#pragma include :/shaders/gl3/coordinatesystems.inc" ]
+ }
+ ]
+ },
+ "metalRoughFunction": {
+ "inputs": [
+ "baseColor",
+ "metalness",
+ "roughness",
+ "ambientOcclusion",
+ "worldPosition",
+ "worldView",
+ "worldNormal"
+ ],
+ "outputs": [
+ "outputColor"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 1
+ },
+ "substitution": "vec4 $outputColor = metalRoughFunction($baseColor, $metalness, $roughness, $ambientOcclusion, $worldPosition, $worldView, $worldNormal);",
+ "headerSnippets": [ "#pragma include :/shaders/gl3/metalrough.inc.frag" ]
+ }
+ ]
}
}