summaryrefslogtreecommitdiffstats
path: root/src/Runtime/res/effectlib
diff options
context:
space:
mode:
authorMäättä Antti <antti.maatta@qt.io>2017-10-11 12:50:42 +0300
committerAntti Määttä <antti.maatta@qt.io>2017-10-20 09:22:33 +0000
commite45ef3505b735ac422ecd2c69b0a19f30c2ff946 (patch)
treeba64c305c9823570c3d2af309dc27abe3e9e6bdb /src/Runtime/res/effectlib
parentd0dbd6cdbf8c4cc5b4b46ec1cdd3687b1170edc6 (diff)
Add GLES2 backend to runtime
Task-number: BOUL-789 Change-Id: I4a076b6a56860275d3ea89dd4d6709cb14fb1c40 Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src/Runtime/res/effectlib')
-rw-r--r--src/Runtime/res/effectlib/defaultMaterialFresnelNoDvn.glsllib43
-rw-r--r--src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib22
-rw-r--r--src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib2
-rw-r--r--src/Runtime/res/effectlib/funcspecularBSDF.glsllib14
-rw-r--r--src/Runtime/res/effectlib/gles2/SSAOCustomMaterial.glsllib100
-rw-r--r--src/Runtime/res/effectlib/gles2/defaultMaterialBumpNoLod.glsllib52
-rw-r--r--src/Runtime/res/effectlib/gles2/funcareaLightVars.glsllib29
-rw-r--r--src/Runtime/res/effectlib/gles2/funcsampleLightVars.glsllib27
-rw-r--r--src/Runtime/res/effectlib/gles2/monoChannel.glsllib58
-rw-r--r--src/Runtime/res/effectlib/gles2/sampleProbe.glsllib482
-rw-r--r--src/Runtime/res/effectlib/gles2/shadowMapping.glsllib106
-rw-r--r--src/Runtime/res/effectlib/gles2/tangentSpaceNormalTexture.glsllib97
-rw-r--r--src/Runtime/res/effectlib/monoChannel.glsllib6
-rw-r--r--src/Runtime/res/effectlib/physGlossyBSDF.glsllib4
-rw-r--r--src/Runtime/res/effectlib/rotationTranslationScale.glsllib18
-rw-r--r--src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib10
-rw-r--r--src/Runtime/res/effectlib/transformCoordinate.glsllib8
17 files changed, 1036 insertions, 42 deletions
diff --git a/src/Runtime/res/effectlib/defaultMaterialFresnelNoDvn.glsllib b/src/Runtime/res/effectlib/defaultMaterialFresnelNoDvn.glsllib
new file mode 100644
index 00000000..90958a3f
--- /dev/null
+++ b/src/Runtime/res/effectlib/defaultMaterialFresnelNoDvn.glsllib
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEFAULT_MATERIAL_FRESNEL_NO_DVN_GLSLLIB
+#define DEFAULT_MATERIAL_FRESNEL_NO_DVN_GLSLLIB
+
+float defaultMaterialSimpleFresnel( in vec3 N, in vec3 viewDir, in float ior, float fresnelPower )
+{
+ float F = ((1.0-ior) * (1.0-ior)) / ((1.0+ior) * (1.0+ior));
+ float VdotN = dot(viewDir, N);
+ VdotN = clamp( VdotN, 0.0, 1.0 );
+ float ratio = F + (1.0 - F) * pow(1.0 - VdotN, fresnelPower);
+ return clamp( ratio * pow( VdotN, fresnelPower ), 0.0, 1.0 );
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib b/src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib
index 250056af..bda0ea60 100644
--- a/src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib
+++ b/src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib
@@ -1,31 +1,31 @@
#ifndef PI
-#define PI 3.14159265358979f
+#define PI 3.14159265358979
#define PI_SQUARE ( PI * PI )
#endif
vec4 diffuseReflectionBSDF(in vec3 N, in vec3 L, in vec3 viewDir,
in vec3 lightDiffuse, in float roughness)
{
- float cosThetaI = max( 0.0f, dot( N, L ) );
+ float cosThetaI = max( 0.0, dot( N, L ) );
float factor = cosThetaI;
- if ( ( 0.0f < factor ) && ( 0.0f < roughness ) )
+ if ( ( 0.0 < factor ) && ( 0.0 < roughness ) )
{
// see http://en.wikipedia.org/wiki/Oren%E2%80%93Nayar_reflectance_model
- float sigmaSquare = 0.25f * PI_SQUARE * roughness * roughness;
- float A = 1.0f - 0.5f * sigmaSquare / ( sigmaSquare + 0.33f );
- float B = 0.45f * sigmaSquare / ( sigmaSquare + 0.09f );
+ float sigmaSquare = 0.25 * PI_SQUARE * roughness * roughness;
+ float A = 1.0 - 0.5 * sigmaSquare / ( sigmaSquare + 0.33 );
+ float B = 0.45 * sigmaSquare / ( sigmaSquare + 0.09 );
// project L and viewDir on surface to get the azimuthal angle between them
// as we don't really need the projections, but the angle between them,
// it's enough to just use the cross instead
vec3 pl = normalize( cross( L, N ) );
vec3 pv = normalize( cross( viewDir, N ) );
- float cosPhi = max( 0.0f, dot( pl, pv ) );
+ float cosPhi = max( 0.0, dot( pl, pv ) );
float sinAlpha, tanBeta;
- float cosThetaO = max( 0.0f, dot( N, viewDir ) );
- float sinThetaI = sqrt( max( 0.0f, 1.0f - cosThetaI * cosThetaI ) );
- float sinThetaO = sqrt( max( 0.0f, 1.0f - cosThetaO * cosThetaO ) );
+ float cosThetaO = max( 0.0, dot( N, viewDir ) );
+ float sinThetaI = sqrt( max( 0.0, 1.0 - cosThetaI * cosThetaI ) );
+ float sinThetaO = sqrt( max( 0.0, 1.0 - cosThetaO * cosThetaO ) );
if ( cosThetaI < cosThetaO )
{ // -> thetaO < thetaI
sinAlpha = sinThetaI;
@@ -39,5 +39,5 @@ vec4 diffuseReflectionBSDF(in vec3 N, in vec3 L, in vec3 viewDir,
factor *= A + B * cosPhi * sinAlpha * tanBeta;
}
- return( vec4( factor * lightDiffuse, 1.0f ) );
+ return( vec4( factor * lightDiffuse, 1.0 ) );
}
diff --git a/src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib b/src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib
index 3b8f2d9f..9afc58b4 100644
--- a/src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib
+++ b/src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib
@@ -1,5 +1,5 @@
vec4 diffuseReflectionWrapBSDF(vec3 normalDir, in vec3 L, in vec3 lightDiffuse, float wrap)
{
float I = max( 0.0, ((dot(L, normalDir) + wrap)/ (1.0 + wrap)) ); //diffuseIntensity
- return vec4( I * lightDiffuse, 1.0f );
+ return vec4( I * lightDiffuse, 1.0 );
}
diff --git a/src/Runtime/res/effectlib/funcspecularBSDF.glsllib b/src/Runtime/res/effectlib/funcspecularBSDF.glsllib
index 44e81966..e9450bfe 100644
--- a/src/Runtime/res/effectlib/funcspecularBSDF.glsllib
+++ b/src/Runtime/res/effectlib/funcspecularBSDF.glsllib
@@ -9,14 +9,14 @@
vec4 specularBSDF(in vec3 N, in vec3 L, in vec3 viewDir, in vec3 lightSpecular,
in float ior, in float shininess, in vec3 tint, int mode)
{
- vec4 rgba = vec4( 0.0f, 0.0f, 0.0f, 1.0f );
+ vec4 rgba = vec4( 0.0, 0.0, 0.0, 1.0 );
float cosTheta = dot( N, L );
- if ( 0.0f < cosTheta )
+ if ( 0.0 < cosTheta )
{
if ( ( mode == scatter_reflect ) || ( mode == scatter_reflect_transmit ) )
{
vec3 R = reflect( -L, N );
- float cosAlpha = max( 0.0f, dot( R, viewDir ) );
+ float cosAlpha = max( 0.0, dot( R, viewDir ) );
float shine = pow( cosAlpha, shininess );
rgba.rgb = shine * lightSpecular;
}
@@ -25,17 +25,17 @@ vec4 specularBSDF(in vec3 N, in vec3 L, in vec3 viewDir, in vec3 lightSpecular,
{
// check against total reflection
vec3 R = refract( -viewDir, N, ior );
- if ( R == vec3( 0.0f, 0.0f, 0.0f ) )
+ if ( R == vec3( 0.0, 0.0, 0.0 ) )
{
- rgba.a = 1.0f;
+ rgba.a = 1.0;
}
else if ( mode == scatter_transmit )
{
- rgba.a = 0.0f;
+ rgba.a = 0.0;
}
else
{
- rgba.a = 1.0f - luminance( tint );
+ rgba.a = 1.0 - luminance( tint );
}
}
return( rgba );
diff --git a/src/Runtime/res/effectlib/gles2/SSAOCustomMaterial.glsllib b/src/Runtime/res/effectlib/gles2/SSAOCustomMaterial.glsllib
new file mode 100644
index 00000000..d3994a61
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/SSAOCustomMaterial.glsllib
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SSAO_CUSTOM_MATERIAL_GLSLLIB
+#define SSAO_CUSTOM_MATERIAL_GLSLLIB
+
+#ifndef UIC_ENABLE_SSAO
+#define UIC_ENABLE_SSAO 0
+#endif
+
+#ifndef UIC_ENABLE_SSDO
+#define UIC_ENABLE_SSDO 0
+#endif
+
+#if UIC_ENABLE_SSAO || UIC_ENABLE_SSDO
+
+#include "viewProperties.glsllib"
+#if UIC_ENABLE_SSDO
+#include "screenSpaceDO.glsllib"
+
+
+uniform vec4 ao_properties;
+uniform vec4 ao_properties2;
+uniform vec4 shadow_properties;
+uniform vec4 aoScreenConst;
+uniform vec4 UvToEyeConst;
+
+
+uniform sampler2D depth_sampler;
+#endif
+uniform sampler2D ao_sampler;
+uniform vec2 ao_sampler_size;
+
+#endif // UIC_ENABLE_SSAO || UIC_ENABLE_SSDO
+
+#if UIC_ENABLE_SSAO
+
+float customMaterialAO()
+{
+#if UIC_ENABLE_SSDO
+ vec2 smpUV = (gl_FragCoord.xy) * aoScreenConst.zw;
+#else
+ vec2 smpUV = gl_FragCoord.xy / ao_sampler_size;
+#endif
+ return texture(ao_sampler, smpUV).x;
+}
+
+#else
+
+float customMaterialAO()
+{
+ return 1.0;
+}
+
+#endif
+
+#if UIC_ENABLE_SSDO
+
+float customMaterialShadow( vec3 lightDir, vec3 varWorldPos )
+{
+ return shadowOcclusion( depth_sampler, lightDir, varWorldPos, view_matrix, view_projection_matrix, shadow_properties, camera_properties, aoScreenConst, UvToEyeConst );
+}
+
+#else
+
+float customMaterialShadow( vec3 lightDir, vec3 varWorldPos )
+{
+ return 1.0;
+}
+
+#endif
+
+#endif // #ifndef SSAO_CUSTOM_MATERIAL_GLSLLIB
diff --git a/src/Runtime/res/effectlib/gles2/defaultMaterialBumpNoLod.glsllib b/src/Runtime/res/effectlib/gles2/defaultMaterialBumpNoLod.glsllib
new file mode 100644
index 00000000..2f3bd150
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/defaultMaterialBumpNoLod.glsllib
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+float calcRGBAvg(in vec4 rgba)
+{
+ return (rgba.r + rgba.g + rgba.b) / 3.0;
+}
+
+vec3 defaultMaterialBumpNoLod(in sampler2D sampler, in float factor,
+ in vec2 texCoord, in vec3 tangent, in vec3 binormal,
+ in vec3 normal, in vec2 bumpSize )
+{
+ // invert factor
+ float invFactor = -factor;
+
+ vec2 unitStep = 1.0 / bumpSize;
+
+ float du = calcRGBAvg(texture2D( sampler, vec2( texCoord.x + unitStep.x, texCoord.y )))
+ - calcRGBAvg(texture2D( sampler, vec2( texCoord.x, texCoord.y )));
+ float dv = calcRGBAvg(texture2D( sampler, vec2( texCoord.x, texCoord.y + unitStep.y )))
+ - calcRGBAvg(texture2D( sampler, vec2( texCoord.x, texCoord.y )));
+
+ vec3 n = normalize(vec3(invFactor * du, invFactor * dv, 1.0));
+ n = n.x * normalize(tangent) + n.y * normalize(binormal) + n.z * normal;
+ return normalize(normal + n);
+}
diff --git a/src/Runtime/res/effectlib/gles2/funcareaLightVars.glsllib b/src/Runtime/res/effectlib/gles2/funcareaLightVars.glsllib
new file mode 100644
index 00000000..cdb8c92a
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/funcareaLightVars.glsllib
@@ -0,0 +1,29 @@
+#define MAX_AREA_LIGHTS 16
+
+// note this struct must exactly match the memory layout of the
+// struct SLightSourceShader in the source code. If you make changes here you need
+// to adjust the struct SLightSourceShader as well
+struct AreaLight
+{
+ vec4 position;
+ vec4 direction; // Specifies the light direction in world coordinates.
+ vec4 up;
+ vec4 right;
+ vec4 diffuse;
+ vec4 ambient;
+ vec4 specular;
+ float spotExponent; // Specifies the intensity distribution of the light.
+ float spotCutoff; // Specifies the maximum spread angle of the light.
+ float constantAttenuation; // Specifies the constant light attenuation factor.
+ float linearAttenuation; // Specifies the linear light attenuation factor.
+ float quadraticAttenuation; // Specifies the quadratic light attenuation factor.
+ float range; // Specifies the maximum distance of the light influence
+ float width; // Specifies the width of the area light surface.
+ float height; // Specifies the height of the area light surface;
+ vec4 shadowControls;
+ mat4 shadowView;
+ int shadowIdx;
+};
+
+uniform int uNumAreaLights;
+uniform AreaLight arealights[MAX_AREA_LIGHTS];
diff --git a/src/Runtime/res/effectlib/gles2/funcsampleLightVars.glsllib b/src/Runtime/res/effectlib/gles2/funcsampleLightVars.glsllib
new file mode 100644
index 00000000..6cb0d831
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/funcsampleLightVars.glsllib
@@ -0,0 +1,27 @@
+
+#define MAX_NUM_LIGHTS 16
+
+struct LightSource
+{
+ vec4 position;
+ vec4 direction; // Specifies the light direction in world coordinates.
+ vec4 up;
+ vec4 right;
+ vec4 diffuse;
+ vec4 ambient;
+ vec4 specular;
+ float spotExponent; // Specifies the intensity distribution of the light.
+ float spotCutoff; // Specifies the maximum spread angle of the light.
+ float constantAttenuation; // Specifies the constant light attenuation factor.
+ float linearAttenuation; // Specifies the linear light attenuation factor.
+ float quadraticAttenuation; // Specifies the quadratic light attenuation factor.
+ float range; // Specifies the maximum distance of the light influence
+ float width; // Specifies the width of the area light surface.
+ float height; // Specifies the height of the area light surface;
+ vec4 shadowControls;
+ mat4 shadowView;
+ int shadowIdx;
+};
+
+uniform int uNumLights;
+uniform LightSource lights[MAX_NUM_LIGHTS];
diff --git a/src/Runtime/res/effectlib/gles2/monoChannel.glsllib b/src/Runtime/res/effectlib/gles2/monoChannel.glsllib
new file mode 100644
index 00000000..1460aae1
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/monoChannel.glsllib
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MONO_CHANNEL_GLSLLIB
+#define MONO_CHANNEL_GLSLLIB
+
+#ifdef UIC_DEFINE_API
+#define mono_alpha 0
+#define mono_average 1
+#define mono_luminance 2
+#define mono_maximum 3
+#endif
+
+float monoChannel( in vec4 t, const in int monoSource )
+{
+ if ( monoSource == mono_alpha )
+ return( t.w );
+
+ if ( monoSource == mono_average )
+ return( ( t.x + t.y + t.z ) / 3.0 );
+
+ if ( monoSource == mono_luminance )
+ return( luminance( t.xyz ) );
+
+ if ( monoSource == mono_maximum )
+ return( max( t.x, max( t.y, t.z ) ) );
+
+ return( 1.0 );
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/gles2/sampleProbe.glsllib b/src/Runtime/res/effectlib/gles2/sampleProbe.glsllib
new file mode 100644
index 00000000..4b328183
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/sampleProbe.glsllib
@@ -0,0 +1,482 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SAMPLE_PROBE_GLSLLIB
+#define SAMPLE_PROBE_GLSLLIB 1
+
+#ifndef UIC_ENABLE_LIGHT_PROBE_2
+#define UIC_ENABLE_LIGHT_PROBE_2 0
+#endif
+
+#ifndef UIC_ENABLE_IBL_FOV
+#define UIC_ENABLE_IBL_FOV 0
+#endif
+
+uniform sampler2D light_probe;
+uniform vec4 light_probe_props;
+uniform vec4 light_probe_rotation;
+uniform vec4 light_probe_offset; // light_probe_offset.w = number of mipmaps
+uniform vec2 light_probe_size;
+
+#if UIC_ENABLE_LIGHT_PROBE_2
+uniform sampler2D light_probe2;
+uniform vec4 light_probe2_props;
+uniform vec2 light_probe2_size;
+#endif
+
+#if UIC_ENABLE_IBL_FOV
+uniform vec4 light_probe_opts;
+#endif
+
+float noise1d(vec2 n)
+{
+ return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);
+}
+
+mat3 orthoNormalize( in mat3 tanFrame )
+{
+ mat3 outMat;
+ outMat[0] = normalize( cross( tanFrame[1], tanFrame[2] ) );
+ outMat[1] = normalize( cross( tanFrame[2], outMat[0] ) );
+ outMat[2] = tanFrame[2];
+
+ return outMat;
+}
+
+mat3 tangentFrame( vec3 N, vec3 p )
+{
+ // get edge vectors of the pixel triangle
+ vec3 dp1 = dFdx( p );
+ vec3 dp2 = dFdy( p );
+ // Using dPdu and dPdv would be nicer, but the nature of our materials
+ // are not ones with intrinsic UVs, so we can't really go there.
+// vec2 duv1 = dFdx( uv );
+// vec2 duv2 = dFdy( uv );
+
+ // solve the linear system
+ vec3 dp2perp = cross( dp2, N );
+ vec3 dp1perp = cross( N, dp1 );
+// vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
+// vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
+
+ vec3 T = normalize(dp1perp);
+ vec3 B = normalize(dp2perp);
+ return mat3( T , B , N );
+}
+
+vec2 transformSample( vec2 origUV, vec4 probeRot, vec2 probeOfs )
+{
+ vec2 retUV;
+ retUV.x = dot( vec3(origUV, 1.0), vec3(probeRot.xy, probeOfs.x) );
+ retUV.y = dot( vec3(origUV, 1.0), vec3(probeRot.zw, probeOfs.y) );
+ return retUV;
+}
+
+// This is broken out into its own routine so that if we get some other
+// format image than a lat-long, then we can account for that by changing
+// the code here alone.
+vec2 getProbeSampleUV( vec3 smpDir, vec4 probeRot, vec2 probeOfs )
+{
+ vec2 smpUV;
+
+#if UIC_ENABLE_IBL_FOV
+ smpUV.x = (2.0 * atan(-smpDir.z, smpDir.x) + 3.14159265358 ) / light_probe_opts.x;
+ smpUV.y = (2.0 * atan(-smpDir.z, smpDir.y) + 3.14159265358 ) / light_probe_opts.x;
+#else
+ smpUV.x = atan( smpDir.x, -smpDir.z) / 3.14159265359;
+ smpUV.y = 1.0 - (acos(smpDir.y) / 1.57079632679);
+#endif
+ smpUV = transformSample( smpUV.xy * 0.5, probeRot, probeOfs ) + vec2(0.5, 0.5);
+
+ return smpUV;
+}
+
+vec4 getTopLayerSample( vec3 inDir, float lodShift, vec3 lodOffsets )
+{
+#if UIC_ENABLE_LIGHT_PROBE_2
+ if ( light_probe2_props.w < 0.5 )
+ return vec4(0.0, 0.0, 0.0, 0.0);
+
+ vec2 smpUV = getProbeSampleUV( inDir, vec4(1.0, 0.0, 0.0, 1.0), light_probe_props.xy );
+ smpUV.x -= 0.5;
+ smpUV.x *= light_probe2_props.x;
+ smpUV.x += light_probe2_props.y;
+
+ vec4 retVal = 0.4 * textureLod( light_probe2, smpUV , lodShift );
+ retVal += 0.2 * textureLod( light_probe2, smpUV , lodShift+lodOffsets.x );
+ retVal += 0.3 * textureLod( light_probe2, smpUV , lodShift+lodOffsets.y );
+ retVal += 0.1 * textureLod( light_probe2, smpUV , lodShift+lodOffsets.z );
+ return retVal;
+#else
+ return vec4(0.0, 0.0, 0.0, 0.0);
+#endif
+}
+
+vec3 getProbeSample( vec3 smpDir, float lodShift, vec3 normal )
+{
+ vec2 smpUV = getProbeSampleUV( smpDir, light_probe_rotation, light_probe_offset.xy );
+ return textureLod( light_probe, smpUV , lodShift ).xyz;
+}
+
+vec3 getProbeWeightedSample( vec3 smpDir, float lodShift, float roughness, vec3 normal )
+{
+ // This gives us a weighted sum that approximates the total filter support
+ // of the full-blown convolution.
+ vec2 smpUV = getProbeSampleUV( smpDir, light_probe_rotation, light_probe_offset.xy );
+ float wt = 1.0;
+
+#if UIC_ENABLE_IBL_FOV
+ wt = min(wt, smoothstep(roughness * -0.25, roughness * 0.25, smpUV.x));
+ wt = min(wt, smoothstep(roughness * -0.25, roughness * 0.25, smpUV.y));
+ wt = min(wt, 1.0 - smoothstep(1.0 - roughness*0.25, 1.0 + roughness*0.25, smpUV.x));
+ wt = min(wt, 1.0 - smoothstep(1.0 - roughness*0.25, 1.0 + roughness*0.25, smpUV.y));
+#endif
+
+ vec3 lodOffsets;
+ lodOffsets.x = mix(-2.0, -0.70710678, roughness);
+ lodOffsets.y = min( 2.0 * smoothstep(0.0, 0.1, roughness), 2.0 - 1.29289 * smoothstep(0.1, 1.0, roughness) );
+ lodOffsets.z = min( 6.0 * smoothstep(0.0, 0.1, roughness), 6.0 - 4.585786 * smoothstep(0.1, 1.0, roughness) );
+
+ ivec2 iSize = ivec2(light_probe_size);
+ vec3 ddx = dFdx( smpDir ) * float(iSize.x);
+ vec3 ddy = dFdy( smpDir ) * float(iSize.y);
+// vec2 ddxUV = dFdx( smpUV ) * float(iSize.x);
+// vec2 ddyUV = dFdy( smpUV ) * float(iSize.y);
+
+ vec2 deriv;
+ deriv.x = max( dot(ddx, ddx), dot(ddy, ddy) );
+// deriv.y = max( dot(ddxUV, ddxUV), dot(ddyUV, ddyUV) );
+ deriv = clamp( deriv, vec2(1.0), vec2(iSize.x * iSize.y) );
+ vec2 lodBound = 0.5 * log2( deriv ) - vec2(1.0);
+
+// float minLod = 0.5 * (lodBound.x + lodBound.y);
+ float minLod = lodBound.x;
+ float maxLod = log2( max(float(iSize.x), float(iSize.y)) );
+ minLod = clamp( minLod / maxLod, 0.0, 1.0 );
+ minLod *= minLod * maxLod;
+
+ lodShift = max( lodShift, minLod );
+
+ vec3 retVal = 0.4 * textureLod( light_probe, smpUV , lodShift ).xyz;
+ retVal += 0.2 * textureLod( light_probe, smpUV , max(minLod, lodShift+lodOffsets.x) ).xyz;
+ retVal += 0.3 * textureLod( light_probe, smpUV , lodShift+lodOffsets.y ).xyz;
+ retVal += 0.1 * textureLod( light_probe, smpUV , lodShift+lodOffsets.z ).xyz;
+
+#if UIC_ENABLE_LIGHT_PROBE_2
+ vec4 topSmp = getTopLayerSample( smpDir, lodShift, lodOffsets );
+ vec3 tempVal = mix( retVal, topSmp.xyz, topSmp.w );
+ retVal = mix( retVal, tempVal, light_probe2_props.z );
+#endif
+
+ if (light_probe_props.z > -1.0) {
+ float ctr = 0.5 + 0.5 * light_probe_props.z;
+ float vertWt = smoothstep(ctr-roughness*0.25, ctr+roughness*0.25, smpUV.y);
+ float wtScaled = mix(1.0, vertWt, light_probe_props.z + 1.0);
+ retVal *= wtScaled;
+ }
+
+ return retVal * wt;
+}
+
+vec2 textureSizeLod( vec2 size, int level )
+{
+ return size / pow(2.0, float(level));
+}
+
+vec3 getProbeAnisoSample( vec3 smpDir, float roughU, float roughV, mat3 tanFrame )
+{
+ float minRough = min(roughU, roughV);
+ float maxRough = max(roughU, roughV);
+
+ float lodMin = log2( (minRough*3.0 + maxRough)*0.25 ) + (light_probe_offset.w - 2.0);
+
+ float ratio = clamp( maxRough / minRough, 1.01, 27.0);
+ vec2 texSize = textureSizeLod( light_probe_size, int(floor( lodMin )) );
+ texSize = mix( texSize, texSize * 0.5, fract(lodMin) );
+
+ // Boundary of 1.0..9.0 is just to keep the number of samples to within a
+ // reasonable number of samples in the filter. Similarly, with the clamping
+ // of the ratio to a max of 27.0 is just to prevent the step size in the filter
+ // to be no bigger than 3 texels (beyond which, there are some artifacts at high
+ // roughness, aka low texture res).
+ float stepFig = clamp(floor( ratio ), 1.0, 9.0);
+
+ // numSteps is half the number of samples we need to take, which makes it
+ // the number of steps to take on each side.
+ int numSteps = int( floor(stepFig * 0.5) );
+
+ vec2 smpUV = getProbeSampleUV( smpDir, light_probe_rotation, light_probe_offset.xy );
+ vec4 result = vec4(0.0);
+
+ vec3 smpDirOfs = (maxRough == roughU) ? 0.01 * tanFrame[0] : 0.01 * tanFrame[1];
+ vec2 stepPos = getProbeSampleUV(normalize(smpDir + smpDirOfs), light_probe_rotation, light_probe_offset.xy);
+ vec2 stepNeg = getProbeSampleUV(normalize(smpDir - smpDirOfs), light_probe_rotation, light_probe_offset.xy);
+ stepPos -= smpUV; stepNeg -= smpUV;
+ stepPos *= texSize; stepNeg *= texSize;
+
+ // This ensures that we step along a size that makes sense even if one of the two
+ // sammpling directions wraps around the edges of the IBL texture.
+ smpDirOfs /= min( length(stepPos), length(stepNeg) );
+ smpDirOfs *= ratio / stepFig;
+
+ float sigma = mix(0.0, 2.0, ratio / 27.0);
+ sigma *= sigma;
+
+ float wt = (1.0 / (ratio - 1.0)) + 1.0;
+ result.xyz += wt * getProbeWeightedSample( smpDir, lodMin, minRough, tanFrame[2] );
+ result.w += wt;
+ for (int i = 0; i < numSteps; ++i)
+ {
+ wt = sigma / (sigma + float(i * i));
+ vec2 uv0 = getProbeSampleUV(normalize(smpDir + smpDirOfs * float(i)), light_probe_rotation, light_probe_offset.xy);
+ vec2 uv1 = getProbeSampleUV(normalize(smpDir - smpDirOfs * float(i)), light_probe_rotation, light_probe_offset.xy);
+ result.xyz += wt * textureLod( light_probe, uv0 , lodMin ).xyz;
+ result.w += wt;
+ result.xyz += wt * textureLod( light_probe, uv1 , lodMin ).xyz;
+ result.w += wt;
+ }
+
+ result /= result.w;
+ return result.xyz;
+}
+
+vec4 sampleDiffuse( mat3 tanFrame )
+{
+ if ( light_probe_props.w < 0.005 )
+ return vec4( 0.0 );
+
+// if ( light_probe_offset.w > 0.5 )
+// {
+ // The LOD offset comes from the assumption that a full diffuse convolution
+ // has a support of pi/2, which translates into x pixels, and the base 2 log
+ // gives us this LOD... Technically, "x" pixels depends on what the original
+ // texture resolution was, which is why we use light_probe_offset.w, which holds
+ // the number of mip levels the texture has.
+
+ return vec4( light_probe_props.w * getProbeWeightedSample( tanFrame[2], light_probe_offset.w - 2.65149613, 1.0, tanFrame[2] ), 1.0 );
+// }
+
+ /*
+ // PKC -- the code below is for full-blown IBL, which we'll skip for now
+
+ // Hand-calculated Hammersley points for t = 2, n = 33
+ // I exclude the 0,0 first point, hence why n=33 and not 32
+ // Nice thing about 2d Hammersley points is that any subset is
+ // also stratified, so even if I have 1000 points and truncate
+ // anywhere, I'm fine. Each of these represent the y of an xy
+ // while x for the kth point is always (k+1)/n.
+ float kernel[32];
+ kernel[0] = 0.5; kernel[1] = 0.25;
+ kernel[2] = 0.75; kernel[3] = 0.125;
+ kernel[4] = 0.625; kernel[5] = 0.375;
+ kernel[6] = 0.875; kernel[7] = 0.0625;
+ kernel[8] = 0.5625; kernel[9] = 0.3125;
+ kernel[10] = 0.8125; kernel[11] = 0.1875;
+ kernel[12] = 0.6875; kernel[13] = 0.4375;
+ kernel[14] = 0.9375; kernel[15] = 0.03125;
+ kernel[16] = 0.53125; kernel[17] = 0.28125;
+ kernel[18] = 0.78125; kernel[19] = 0.15625;
+ kernel[20] = 0.65625; kernel[21] = 0.40625;
+ kernel[22] = 0.90625; kernel[23] = 0.09375;
+ kernel[24] = 0.59375; kernel[25] = 0.34375;
+ kernel[26] = 0.84375; kernel[27] = 0.28175;
+ kernel[28] = 0.71875; kernel[29] = 0.46875;
+ kernel[30] = 0.96875; kernel[31] = 0.015625;
+
+ float phiShift = noise1d(gl_FragCoord.xy) - 0.5;
+
+ vec3 ret = vec3(0, 0, 0);
+
+ int ct = 24;
+ float step = 25.0;
+
+ // Importance sampling a cosine-weighted distribution. Since this
+ // matches the BSDF exactly, we are just going to assume that the PDF
+ // and the BSDF cancel out in sampling, so we just need to accumulate
+ // texture colors. The noise function puts randomized "twist" into
+ // the sampled directions.
+ for( int i = 0; i < ct; ++i )
+ {
+ vec3 localDir;
+ float phi = 6.28318530718 * (kernel[i] + phiShift);
+ float cosTheta = sqrt( float(i+1) / step);
+ localDir.z = sqrt(1.0 - cosTheta*cosTheta);
+ localDir.x = cos(phi) * cosTheta;
+ localDir.y = sin(phi) * cosTheta;
+ vec3 smpDir = tanFrame[0]*localDir.x + tanFrame[1]*localDir.y + tanFrame[2]*localDir.z;
+
+
+ float lodShift = light_probe_offset.w - 2 + log2( 3.1415926535 / (localDir.z * step) );
+ vec3 smpColor = getProbeSample( smpDir, lodShift, tanFrame[2] );
+
+ // The assumption here is that the BSDF and the sampling PDF are identical
+ // so they cancel out and therefore, we don't need to include it here.
+ ret += smpColor;
+ }
+
+ ret *= aoFactor / 24.0;
+ return ret;
+ */
+}
+
+vec4 sampleDiffuseCustomMaterial( vec3 normal, vec3 worldPos, float aoFactor )
+{
+
+ mat3 tanFrame = tangentFrame( normal, worldPos );
+ return sampleDiffuse( tanFrame );
+}
+
+vec4 sampleGlossyAniso( mat3 tanFrame, vec3 viewDir, float roughU, float roughV )
+{
+ if ( light_probe_props.w < 0.005 )
+ return vec4( 0.0 );
+
+ // PKC : If we do the full IBL sampling, it's useful to square the roughnesses because
+ // it makes the effect of roughness feel more linear in the low end. This isn't necessary
+ // for fast IBL.
+// float sigmaU = clamp(roughU*roughU, 0.0001, 1.0);
+// float sigmaV = clamp(roughV*roughV, 0.0001, 1.0);
+ float sigmaU = smoothstep( 0.0, 1.0, clamp(roughU, 0.0001, 1.0) );
+ float sigmaV = smoothstep( 0.0, 1.0, clamp(roughV, 0.0001, 1.0) );
+ vec3 ret = vec3(0, 0, 0);
+
+// if ( light_probe_offset.w > 0.5 )
+// {
+ vec3 smpDir = reflect( -viewDir, tanFrame[2] );
+ float sigma = sqrt(sigmaU * sigmaV);
+
+ // Compute the Geometric occlusion/self-shadowing term
+ float NdotL = clamp( dot( smpDir, tanFrame[2] ), 0.0, 0.999995);
+ float k = sigma * 0.31830988618; // roughness / pi
+ float Gl = clamp( (NdotL / (NdotL*(1.0-k) + k) + (1.0 - k*k)) * 0.5, 0.0, 1.0 );
+
+ vec3 outColor;
+
+ outColor = getProbeAnisoSample( smpDir, sigmaU, sigmaV, tanFrame );
+
+ return vec4( light_probe_props.w * Gl * outColor, 1.0 );
+// }
+
+ // PKC -- the code below is for full-blown IBL, which we'll skip for now
+
+/*
+ float step = clamp( ceil(32.0 * sqrt(max(sigmaU, sigmaV))), 4.0, 32.0 );
+ int actualCt = int(step);
+ float phiShift = noise1d(gl_FragCoord.xy) - 0.5;
+
+ // Hand-calculated Hammersley points for t = 2, n = 33
+ // I exclude the 0,0 first point, hence why n=33 and not 32
+ // Nice thing about 2d Hammersley points is that any subset is
+ // also stratified, so even if I have 1000 points and truncate
+ // anywhere, I'm fine. Each of these represent the y of an xy
+ // while x for the kth point is always (k+1)/n.
+ float kernel[32];
+ kernel[0] = 0.5; kernel[1] = 0.25;
+ kernel[2] = 0.75; kernel[3] = 0.125;
+ kernel[4] = 0.625; kernel[5] = 0.375;
+ kernel[6] = 0.875; kernel[7] = 0.0625;
+ kernel[8] = 0.5625; kernel[9] = 0.3125;
+ kernel[10] = 0.8125; kernel[11] = 0.1875;
+ kernel[12] = 0.6875; kernel[13] = 0.4375;
+ kernel[14] = 0.9375; kernel[15] = 0.03125;
+ kernel[16] = 0.53125; kernel[17] = 0.28125;
+ kernel[18] = 0.78125; kernel[19] = 0.15625;
+ kernel[20] = 0.65625; kernel[21] = 0.40625;
+ kernel[22] = 0.90625; kernel[23] = 0.09375;
+ kernel[24] = 0.59375; kernel[25] = 0.34375;
+ kernel[26] = 0.84375; kernel[27] = 0.28175;
+ kernel[28] = 0.71875; kernel[29] = 0.46875;
+ kernel[30] = 0.96875; kernel[31] = 0.015625;
+
+ float thetaI = acos( dot(viewDir, tanFrame[2]) );
+
+ // NOTE : The model I'm using here is actually based on the KGGX model used in
+ // physGlossyBSDF. This is my own variation on the original GGX which uses something
+ // closer to a pure Cauchy distribution in tangent space, but also supports anisotropy.
+ for (int i = 0; i < actualCt; ++i)
+ {
+ vec3 localDir;
+
+ float phi = 6.28318530718 * (kernel[i] + phiShift);
+ float u = float(i + 1) / (step + 1.0);
+ float rU = cos(phi) * sigmaU;
+ float rV = sin(phi) * sigmaV;
+ float sigma = sqrt(rU * rU + rV * rV);
+
+ float boundA = atan( ((thetaI - 1.57079632679) * 0.5) / sigma );
+ float boundB = atan( ((thetaI + 1.57079632679) * 0.5) / sigma );
+ float t = (1.0 - u) * boundA + u * boundB;
+ float thetaH = tan( t ) * sigma;
+
+ float cosThetaH = cos( thetaH );
+ float sinThetaH = sin( thetaH );
+ localDir.z = cosThetaH;
+ localDir.y = sin(phi) * sinThetaH;
+ localDir.x = cos(phi) * sinThetaH;
+
+ vec3 halfDir = tanFrame[0]*localDir.x + tanFrame[1]*localDir.y + tanFrame[2]*localDir.z;
+ halfDir = normalize(halfDir);
+ vec3 smpDir = reflect( -viewDir, halfDir );
+
+ vec2 scaledXY = localDir.xy / vec2(sigmaU, sigmaV);
+ float PDF = (sigmaU*sigmaV) / (sigmaU*sigmaV + dot(scaledXY, scaledXY));
+ vec3 Haf = smpDir + viewDir; // We need the unnormalized half vecter as well as the normalized one
+ float HdotL = dot(halfDir, smpDir);
+ // normalize the PDF to compute the filter support
+ // This gives us the ideal miplevel at which to sample the texture map.
+ PDF *= dot(Haf, Haf) / (4.0 * dot(Haf, smpDir) * HdotL * sigmaU*sigmaV * (boundB-boundA)*(boundB-boundA));
+
+ // Again assuming that the pdf and BSDF are equivalent -- that's not generally valid,
+ // but it saves a lot of ALU cycles.
+ float lodShift = log2( 512.0 * sigma / PDF );
+
+ float k = sigma * 0.31830988618; // roughness / pi
+ float Gl = clamp( (HdotL / (HdotL*(1.0-k) + k) + (1.0 - k*k)) * 0.5, 0.0, 1.0 );
+
+ vec3 smpColor = Gl * getProbeSample( smpDir, lodShift, tanFrame[2] );
+ ret += smpColor;
+ }
+ ret /= float(actualCt);
+ return vec4(ret, 1.0);
+*/
+}
+
+vec4 sampleGlossy( mat3 tanFrame, vec3 viewDir, float roughness )
+{
+ return sampleGlossyAniso( tanFrame, viewDir, roughness, roughness );
+}
+
+vec4 sampleGlossyCustomMaterial( vec3 normal, vec3 worldPos, vec3 viewDir, float roughness )
+{
+ mat3 tanFrame = tangentFrame( normal, worldPos );
+ return sampleGlossy( tanFrame, viewDir, roughness );
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/gles2/shadowMapping.glsllib b/src/Runtime/res/effectlib/gles2/shadowMapping.glsllib
new file mode 100644
index 00000000..183ef974
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/shadowMapping.glsllib
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SHADOW_MAPPING_GLSLLIB
+#define SHADOW_MAPPING_GLSLLIB
+
+#include "depthpass.glsllib"
+
+float sampleParaboloid( in sampler2D shadowMap, in vec4 shadowControls, in mat4 shadowMatrix, in vec3 worldPos, in vec2 cameraProps, out vec2 smpUV )
+{
+ vec4 projCoord = shadowMatrix * vec4( worldPos, 1.0 );
+ vec3 smpCoord = projCoord.xyz / projCoord.w;
+
+ float ptDepth = depthValueToLinearDistance( 1.0 - smpCoord.z, cameraProps );
+ ptDepth = (ptDepth - cameraProps.x) / (cameraProps.y - cameraProps.x);
+ smpCoord = normalize( smpCoord.xyz );
+ smpCoord.xy /= -( smpCoord.z + 1.0 );
+ smpCoord.xy = vec2(1.0) - smpCoord.xy;
+ smpCoord.xy *= 0.5;
+
+ smpUV = smpCoord.xy; // This is just for debug purposes to ensure what the sampled UV cooord is.
+
+ float sampleDepth = texture( shadowMap, smpCoord.xy ).x + shadowControls.x;
+ sampleDepth *= sampleDepth;
+ ptDepth *= ptDepth;
+ float shadowFac = min(1.0, exp(shadowControls.y * sampleDepth * sampleDepth) / exp(shadowControls.y * ptDepth * ptDepth));
+
+ smpUV.xy *= shadowFac;
+ return shadowFac;
+}
+
+float sampleCubemap( in samplerCube shadowCube, in vec4 shadowControls, in mat4 shadowViewMat, in vec3 lightPos, in vec3 worldPos, in vec2 cameraProps )
+{
+ vec3 viewDir = worldPos - vec3(lightPos.x, lightPos.y, lightPos.z);
+ float ptDepth = length(viewDir.xyz);
+ vec4 viewCoord = shadowViewMat * vec4( viewDir.xyz, 0.0 );
+ viewCoord.xyz /= ptDepth;
+ ptDepth = clamp((ptDepth - 1.0) / (cameraProps.y - 1.0), 0.0, 1.0);
+
+ float smpDepth = textureCube( shadowCube, viewDir.xyz ).x + shadowControls.x;
+
+ float shadowFac = min(1.0, exp(shadowControls.y * smpDepth) / exp(shadowControls.y * ptDepth));
+ return shadowFac;
+}
+
+float sampleOrthographic( in sampler2D shadowMap, in vec4 shadowControls, in mat4 shadowMatrix, in vec3 worldPos, in vec2 cameraProps )
+{
+ vec4 projCoord = shadowMatrix * vec4( worldPos, 1.0 );
+ vec3 smpCoord = projCoord.xyz / projCoord.w;
+
+ float sampleDepth = texture( shadowMap, smpCoord.xy ).x + shadowControls.x;
+
+ return min(1.0, exp(shadowControls.y * sampleDepth) / exp(shadowControls.y * smpCoord.z));
+}
+
+
+struct ParaboloidMapResult
+{
+ vec4 m_Position;
+ vec4 m_WorldPos;
+};
+
+ParaboloidMapResult VertexParaboloidDepth(vec3 pos, mat4 inMVP)
+{
+ vec4 glPos = inMVP * vec4( pos, 1.0 );
+ glPos /= glPos.w;
+ glPos.xyz = normalize( glPos.xyz );
+ vec4 world_pos;
+ world_pos.w = glPos.z;
+ glPos.xy /= glPos.z + 1.0;
+ world_pos.xyz = pos.xyz;
+
+ ParaboloidMapResult retval;
+ retval.m_Position = glPos;
+ retval.m_WorldPos = world_pos;
+ return retval;
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/gles2/tangentSpaceNormalTexture.glsllib b/src/Runtime/res/effectlib/gles2/tangentSpaceNormalTexture.glsllib
new file mode 100644
index 00000000..fd0a1415
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/tangentSpaceNormalTexture.glsllib
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FILE_NORMAL_TEXTURE_GLSLLIB
+#define FILE_NORMAL_TEXTURE_GLSLLIB
+
+#ifdef UIC_DEFINE_API
+
+#include "luminance.glsllib"
+#include "monoChannel.glsllib"
+#include "textureCoordinateInfo.glsllib"
+#define wrap_clamp 0
+#define wrap_repeat 1
+#define wrap_mirrored_repeat 2
+#include "rotationTranslationScale.glsllib"
+#include "transformCoordinate.glsllib"
+
+#endif
+
+int modulo(int a, int b)
+{
+ int k = (a / b);
+ return a - k*b;
+}
+
+//interpreting the color values of a bitmap as a vector in tangent space
+vec3 tangentSpaceNormalTexture( in sampler2D tex, in float factor, in bool flipTangentU, in bool flipTangentV
+ , in texture_coordinate_info uvw, in vec2 cropU, in vec2 cropV, in int wrapU, in int wrapV )
+{
+ // if we mirror repeat a tangent space texture, tangent space needs to be flipped for every other tile
+ bool flipU = flipTangentU;
+ bool flipV = flipTangentV;
+ if ( wrapU == wrap_mirrored_repeat )
+ {
+ if ( ( ( 0.0 < uvw.position.x ) && ( modulo(int( uvw.position.x ), 2) == 1 ) )
+ || ( ( uvw.position.x < 0.0 ) && ( modulo(int( uvw.position.x ), 2) == 0 ) ) )
+ {
+ flipU = !flipU;
+ }
+ if ( ( ( 0.0 < uvw.position.y ) && ( modulo(int( uvw.position.y ), 2) == 1 ) )
+ || ( ( uvw.position.y < 0.0 ) && ( modulo(int( uvw.position.y ), 2) == 0 ) ) )
+ {
+ flipV = !flipV;
+ }
+ }
+
+ vec3 tangent = 2.0 * texture( tex, uvw.position.xy ).xyz - 1.0;
+
+ vec3 tangentU = normalize( flipU ? -uvw.tangent_u : uvw.tangent_u );
+ vec3 tangentV = normalize( flipV ? -uvw.tangent_v : uvw.tangent_v );
+ vec3 normal = normalize( cross( tangentU, tangentV ) );
+
+ return( mix( normal, normalize( tangent.x * tangentU - tangent.y * tangentV + tangent.z * normal ), factor ) );
+}
+
+#include "textureCoordinateInfo.glsllib"
+
+//Simpler version built to run from UIC image data
+//In our case, we have already generated the texture coordinate x,y position
+//TODO - figure out if we need to manipulate tangent_u, tangent_v.
+vec3 uicDefaultMaterialFileNormalTexture( in sampler2D sampler, in float factor, vec2 texCoord, vec3 tangent, vec3 binormal )
+{
+ // factor should be in [0,1] range
+ return tangentSpaceNormalTexture( sampler, clamp(factor, 0.0, 1.0), false, false
+ , textureCoordinateInfo( vec3( texCoord.x, texCoord.y, 0.0 ), tangent, binormal )
+ , vec2( 0.000000, 1.000000 ), vec2( 0.000000, 1.000000 )
+ , wrap_repeat, wrap_repeat);
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/monoChannel.glsllib b/src/Runtime/res/effectlib/monoChannel.glsllib
index 1ae6d529..e609e68c 100644
--- a/src/Runtime/res/effectlib/monoChannel.glsllib
+++ b/src/Runtime/res/effectlib/monoChannel.glsllib
@@ -45,14 +45,14 @@ float monoChannel( in vec4 t, in int monoSource )
case mono_alpha :
return( t.w );
case mono_average :
- return( ( t.x + t.y + t.z ) / 3.0f );
+ return( ( t.x + t.y + t.z ) / 3.0 );
case mono_luminance :
return( luminance( t.xyz ) );
case mono_maximum :
return( max( t.x, max( t.y, t.z ) ) );
default :
- return( 1.0f );
+ return( 1.0 );
}
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/Runtime/res/effectlib/physGlossyBSDF.glsllib b/src/Runtime/res/effectlib/physGlossyBSDF.glsllib
index d94bc26a..ad805960 100644
--- a/src/Runtime/res/effectlib/physGlossyBSDF.glsllib
+++ b/src/Runtime/res/effectlib/physGlossyBSDF.glsllib
@@ -53,7 +53,7 @@ float Gterm( float cosTheta, float roughness )
vec4 kggxGlossyBSDF( in mat3 tanFrame, in vec3 L, in vec3 V, in vec3 lightSpecular, float ior,
in float roughnessU, in float roughnessV, int mode )
{
- vec4 rgba = vec4( 0.0f, 0.0f, 0.0f, 1.0f );
+ vec4 rgba = vec4( 0.0, 0.0, 0.0, 1.0 );
vec3 H = normalize(L + V);
// NOTE : This BSDF allows roughness up to 2.0 which allows it
@@ -113,7 +113,7 @@ vec4 kggxGlossyDefaultMtl( in vec3 normal, in vec3 tangent, in vec3 L, in vec3 V
vec4 wardGlossyBSDF( in mat3 tanFrame, in vec3 L, in vec3 V, in vec3 lightSpecular, in float ior,
in float roughnessU, in float roughnessV, int mode )
{
- vec4 rgba = vec4( 0.0f, 0.0f, 0.0f, 1.0f );
+ vec4 rgba = vec4( 0.0, 0.0, 0.0, 1.0 );
vec3 H = normalize(L + V);
// specular
diff --git a/src/Runtime/res/effectlib/rotationTranslationScale.glsllib b/src/Runtime/res/effectlib/rotationTranslationScale.glsllib
index 8abc8c9e..78bb8dd1 100644
--- a/src/Runtime/res/effectlib/rotationTranslationScale.glsllib
+++ b/src/Runtime/res/effectlib/rotationTranslationScale.glsllib
@@ -33,18 +33,18 @@
mat4 rotationTranslationScale( in vec3 rotation, in vec3 translation, in vec3 scaling )
{
- mat4 st = mat4( scaling.x, 0.0f, 0.0f, 0.0f
- , 0.0f, scaling.y, 0.0f, 0.0f
- , 0.0f, 0.0f, scaling.z, 0.0f
- , translation.x - 0.5f, translation.y - 0.5f, translation.z - 0.5f, 1.0f );
+ mat4 st = mat4( scaling.x, 0.0, 0.0, 0.0
+ , 0.0, scaling.y, 0.0, 0.0
+ , 0.0, 0.0, scaling.z, 0.0
+ , translation.x - 0.5, translation.y - 0.5, translation.z - 0.5, 1.0 );
vec3 s = sin( rotation );
vec3 c = cos( rotation );
- mat4 r = mat4( c.y * c.z, -c.x * s.z + s.x * s.y * c.z, s.x * s.z + c.x * s.y * c.z, 0.0f
- , c.y * s.z, c.x * c.z + s.x * s.y * s.z, -s.x * c.z + c.x * s.y * s.z, 0.0f
- , -s.y , s.x * c.y , c.x * c.y , 0.0f
- , 0.5f , 0.5f , 0.5f , 1.0f );
+ mat4 r = mat4( c.y * c.z, -c.x * s.z + s.x * s.y * c.z, s.x * s.z + c.x * s.y * c.z, 0.0
+ , c.y * s.z, c.x * c.z + s.x * s.y * s.z, -s.x * c.z + c.x * s.y * s.z, 0.0
+ , -s.y , s.x * c.y , c.x * c.y , 0.0
+ , 0.5 , 0.5 , 0.5 , 1.0 );
return( st * r );
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib b/src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib
index 853a8601..2b7aacdc 100644
--- a/src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib
+++ b/src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib
@@ -53,19 +53,19 @@ vec3 tangentSpaceNormalTexture( in sampler2D tex, in float factor, in bool flipT
bool flipV = flipTangentV;
if ( wrapU == wrap_mirrored_repeat )
{
- if ( ( ( 0.0f < uvw.position.x ) && ( int( uvw.position.x ) % 2 == 1 ) )
- || ( ( uvw.position.x < 0.0f ) && ( int( uvw.position.x ) % 2 == 0 ) ) )
+ if ( ( ( 0.0 < uvw.position.x ) && ( int( uvw.position.x ) % 2 == 1 ) )
+ || ( ( uvw.position.x < 0.0 ) && ( int( uvw.position.x ) % 2 == 0 ) ) )
{
flipU = !flipU;
}
- if ( ( ( 0.0f < uvw.position.y ) && ( int( uvw.position.y ) % 2 == 1 ) )
- || ( ( uvw.position.y < 0.0f ) && ( int( uvw.position.y ) % 2 == 0 ) ) )
+ if ( ( ( 0.0 < uvw.position.y ) && ( int( uvw.position.y ) % 2 == 1 ) )
+ || ( ( uvw.position.y < 0.0 ) && ( int( uvw.position.y ) % 2 == 0 ) ) )
{
flipV = !flipV;
}
}
- vec3 tangent = 2.0f * texture( tex, uvw.position.xy ).xyz - 1.0f;
+ vec3 tangent = 2.0 * texture( tex, uvw.position.xy ).xyz - 1.0;
vec3 tangentU = normalize( flipU ? -uvw.tangent_u : uvw.tangent_u );
vec3 tangentV = normalize( flipV ? -uvw.tangent_v : uvw.tangent_v );
diff --git a/src/Runtime/res/effectlib/transformCoordinate.glsllib b/src/Runtime/res/effectlib/transformCoordinate.glsllib
index 53237d02..ccdf7d0a 100644
--- a/src/Runtime/res/effectlib/transformCoordinate.glsllib
+++ b/src/Runtime/res/effectlib/transformCoordinate.glsllib
@@ -34,10 +34,10 @@
texture_coordinate_info transformCoordinate( in mat4 transform, in texture_coordinate_info coordinate )
{
texture_coordinate_info tci;
- tci.position = ( transform * vec4( coordinate.position, 1.0f ) ).xyz;
- tci.tangent_u = ( transform * vec4( coordinate.tangent_u, 0.0f ) ).xyz;
- tci.tangent_v = ( transform * vec4( coordinate.tangent_v, 0.0f ) ).xyz;
+ tci.position = ( transform * vec4( coordinate.position, 1.0 ) ).xyz;
+ tci.tangent_u = ( transform * vec4( coordinate.tangent_u, 0.0 ) ).xyz;
+ tci.tangent_v = ( transform * vec4( coordinate.tangent_v, 0.0 ) ).xyz;
return( tci );
}
-#endif \ No newline at end of file
+#endif