diff options
-rw-r--r-- | src/extras/defaults/qmetalroughmaterial.cpp | 10 | ||||
-rw-r--r-- | src/extras/defaults/qmetalroughmaterial_p.h | 2 | ||||
-rw-r--r-- | src/extras/defaults/qtexturedmetalroughmaterial.cpp | 10 | ||||
-rw-r--r-- | src/extras/defaults/qtexturedmetalroughmaterial_p.h | 2 | ||||
-rw-r--r-- | src/extras/extras.qrc | 6 | ||||
-rw-r--r-- | src/extras/shaders/gl3/coordinatesystems.inc | 70 | ||||
-rw-r--r-- | src/extras/shaders/gl3/metalrough.frag | 395 | ||||
-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.json | 290 | ||||
-rw-r--r-- | src/extras/shaders/graphs/metalroughuniform.frag.json | 126 | ||||
-rw-r--r-- | src/render/materialsystem/prototypes/default.json | 665 |
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" ] + } + ] } } |