summaryrefslogtreecommitdiffstats
path: root/res/effectlib/gles2/microfacetBSDF.glsllib
diff options
context:
space:
mode:
Diffstat (limited to 'res/effectlib/gles2/microfacetBSDF.glsllib')
-rw-r--r--res/effectlib/gles2/microfacetBSDF.glsllib233
1 files changed, 233 insertions, 0 deletions
diff --git a/res/effectlib/gles2/microfacetBSDF.glsllib b/res/effectlib/gles2/microfacetBSDF.glsllib
new file mode 100644
index 0000000..7173a74
--- /dev/null
+++ b/res/effectlib/gles2/microfacetBSDF.glsllib
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** 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 MICROFACET_BSDF_GLSLLIB
+#define MICROFACET_BSDF_GLSLLIB 1
+
+
+float GtermSchlick( in mat3 tanFrame, in vec3 l, in vec3 v, in float roughness )
+{
+ float NdotV = clamp(dot(tanFrame[2], v), 0.0, 1.0);
+ float NdotL = clamp(dot(tanFrame[2], l), 0.0, 1.0);
+ float k = roughness*roughness*0.79788;
+
+ float G_V = NdotV / (NdotV * (1.0 + k) + k);
+ float G_L = NdotL / (NdotL * (1.0 + k) + k);
+
+ return clamp(( G_V * G_L ), 0.0, 1.0);
+}
+
+float GtermGGX( in mat3 tanFrame, in vec3 l, in vec3 v, in float roughness )
+{
+ float NdotV = clamp(dot(tanFrame[2], v), 0.0, 1.0);
+ float NdotL = clamp(dot(tanFrame[2], l), 0.0, 1.0);
+ float k = clamp(roughness*roughness, 0.00, 1.0);
+
+ float G_V = NdotV + sqrt( (NdotV - NdotV * k) * NdotV + k );
+ float G_L = NdotL + sqrt( (NdotL - NdotL * k) * NdotL + k );
+
+ return clamp( 2.0 / ( G_V * G_L ), 0.0, 1.0);
+}
+
+float DtermGGX( in mat3 tanFrame, in vec3 L, in vec3 V, in float roughness )
+{
+ float m = clamp(roughness, 0.04, 1.0);
+ float m2 = m*m;
+
+ vec3 H = normalize(L + V);
+ float NdotH = clamp(dot( tanFrame[2], H ), 0.0001, 1.0);
+ float NdotH2 = NdotH * NdotH;
+
+ float denom = NdotH2 * (m2 - 1.0) + 1.0;
+ float D = m2 / (PI * denom * denom);
+
+ return max( 0.0, D);
+}
+
+float DtermGGXAniso( in mat3 tanFrame, in vec3 L, in vec3 V, in float roughnessU, float roughnessV )
+{
+ float roughU = clamp(roughnessU, 0.04, 1.0);
+ float roughV = clamp(roughnessV, 0.04, 1.0);
+ vec3 H = normalize(L + V);
+ float NdotH = clamp( dot(tanFrame[2], H), 0.0001, 1.0 );
+ float m = PI * roughU * roughV;
+ float HdotX = clamp( abs(dot(H, tanFrame[0])), 0.0001, 1.0 );
+ float HdotY = clamp( abs(dot(H, tanFrame[1])), 0.0001, 1.0 );
+
+ float x2 = roughU*roughU;
+ float y2 = roughV*roughV;
+
+ float D = (HdotX*HdotX/x2) + (HdotY*HdotY/y2) + (NdotH*NdotH);
+ D = 1.0 / ( m * D * D );
+
+ return max( 0.0, D);
+}
+
+vec4 microfacetBSDF( 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.0, 0.0, 0.0, 1.0 );
+ vec3 H = normalize(L + V);
+ float HdotL = clamp(dot(H, L), 0.0, 1.0);
+ float NdotL = dot(tanFrame[2], L);
+
+ if ( NdotL > 0.0 )
+ {
+ if ( ( mode == scatter_reflect ) || ( mode == scatter_reflect_transmit ) )
+ {
+ float roughness = calculateRoughness( tanFrame[2], roughnessU, roughnessV, tanFrame[0] );
+ // G term
+ //float G = GtermSchlick( tanFrame, L, V, roughness );
+ float G = GtermGGX( tanFrame, L, V, roughness );
+
+ //float D = DtermGGX( tanFrame, L, V, roughness );
+ float D = DtermGGXAniso( tanFrame, L, V, roughnessU, roughnessV );
+ rgba.rgb = G * D * NdotL * lightSpecular;
+ }
+
+ if ( ( mode == scatter_transmit ) || ( mode == scatter_reflect_transmit ) )
+ {
+ rgba.a = pow(1.0 - clamp(HdotL, 0.0, 1.0), 5.0);
+ }
+ }
+
+ return rgba;
+}
+
+vec4 microfacetBSDFEnvironment( in mat3 tanFrame, in vec3 viewDir, in float roughnessU,
+ in float roughnessV, int mode )
+{
+ vec3 rgb = vec3( 0.0, 0.0, 0.0 );
+#if !QT3DS_ENABLE_LIGHT_PROBE
+ if ( uEnvironmentMappingEnabled )
+ {
+ float roughness = calculateRoughness( tanFrame[2], roughnessU, roughnessV, tanFrame[0] );
+ vec3 R = reflect( -viewDir, tanFrame[2] );
+ rgb = 0.01 * evalEnvironmentMap( R, roughness );
+ rgb = microfacetBSDF( tanFrame, R, viewDir, rgb, 1.0, roughnessU, roughnessV,
+ scatter_reflect ).rgb;
+ }
+#endif
+ return( vec4( rgb, 1.0 ) );
+}
+
+vec3 ImportanceGGX( in mat3 tanFrame, vec2 Xi, float roughness , vec3 N )
+{
+ float a = roughness * roughness;
+ float Phi = 2.0 * PI * Xi.y;
+ float CosTheta = (1.0 - Xi.x);
+ float SinTheta = sqrt( 1.0 - CosTheta * CosTheta );
+
+ vec3 H;
+ H.x = SinTheta * cos( Phi );
+ H.y = SinTheta * sin( Phi );
+ H.z = CosTheta;
+
+ // Tangent to world space
+ return tanFrame[0] * H.x + tanFrame[1] * H.y + tanFrame[2] * H.z;
+}
+
+float DtermGGXAnisoSampled( in mat3 tanFrame, in vec3 H, in float roughnessU, float roughnessV )
+{
+#if (MATERIAL_IS_NON_DIELECTRIC == 1)
+ float roughU = clamp(roughnessU*roughnessU, 0.01, 1.0);
+ float roughV = clamp(roughnessV*roughnessV, 0.01, 1.0);
+#else
+ float roughU = clamp(roughnessU, 0.02, 1.0);
+ float roughV = clamp(roughnessV, 0.02, 1.0);
+#endif
+
+ float NdotH = clamp( dot(tanFrame[2], H), 0.0001, 1.0 );
+ float m = PI * roughU * roughV;
+ float HdotX = clamp( abs(dot(H, tanFrame[0])), 0.0001, 1.0 );
+ float HdotY = clamp( abs(dot(H, tanFrame[1])), 0.0001, 1.0 );
+
+ float x2 = roughU*roughU;
+ float y2 = roughV*roughV;
+
+ float pdf = (HdotX*HdotX/x2) + (HdotY*HdotY/y2) + (NdotH*NdotH);
+ float D = 1.0 / ( m * pdf * pdf );
+
+ return max( 0.0, D);
+}
+
+vec3 sampleEnv(in vec3 L, float pdf, int sampleCount, float roughness )
+{
+ // convert coord to 2D
+ vec2 tc = vec2( ( atan( L.x, -L.z ) + PI ) / ( 2.0 * PI ), acos( -L.y ) / PI );
+ return( textureLod( uEnvironmentTexture, tc, 0.0 ).rgb );
+}
+
+vec4 microfacetSampledBSDF( in mat3 tanFrame, in vec3 viewDir, in float roughnessU,
+ in float roughnessV, int mode )
+{
+ vec2 hammersly[4];
+ hammersly[0] = vec2(0.0, 0.0);
+ hammersly[1] = vec2(0.25, 0.5);
+ hammersly[2] = vec2(0.5, 0.25);
+ hammersly[3] = vec2(0.75, 0.75);
+
+ vec3 rgb = vec3( 0.0, 0.0, 0.0 );
+
+ float roughness = clamp( calculateRoughness( tanFrame[2], roughnessU, roughnessV, tanFrame[0] ),
+ 0.0, 1.0 );
+
+ vec3 R = reflect( -viewDir, tanFrame[2] );
+
+ const int NumSamples = 4;
+ for( int i = 0; i < NumSamples; i++ )
+ {
+ vec2 Xi = hammersly[i]; // pre computed values
+ //vec2 Xi = hammersley2d(i, NumSamples);
+ vec3 Half = ImportanceGGX( tanFrame, Xi, roughness , tanFrame[2] );
+ vec3 H = normalize( Half );
+
+ vec3 L = 2.0 * dot( viewDir, Half ) * Half - viewDir;
+ float NdotV = clamp( dot( tanFrame[2], viewDir ), 0.0001, 1.0 );
+ float NdotR = clamp( dot( tanFrame[2], R ), 0.0, 1.0 );
+ float NdotH = clamp( dot( tanFrame[2], H ), 0.0001, 1.0 );
+
+ if( NdotV > 0.0001 )
+ {
+ float G = GtermGGX( tanFrame, L, viewDir, roughness );
+ float D = DtermGGXAnisoSampled( tanFrame, H, roughnessU, roughnessV);
+
+ vec3 envColor = 0.01 * sampleEnv( L, D, NumSamples, roughness );
+
+ rgb += (envColor * G * D * NdotR) / ( 4.0 * NdotV * NdotH);
+ }
+ }
+
+ rgb /= float(NumSamples);
+
+ return( vec4( rgb, 1.0 ) );
+}
+
+#endif