summaryrefslogtreecommitdiffstats
path: root/res/effectlib/sampleLight.glsllib
diff options
context:
space:
mode:
Diffstat (limited to 'res/effectlib/sampleLight.glsllib')
-rw-r--r--res/effectlib/sampleLight.glsllib130
1 files changed, 130 insertions, 0 deletions
diff --git a/res/effectlib/sampleLight.glsllib b/res/effectlib/sampleLight.glsllib
new file mode 100644
index 0000000..05ad5b4
--- /dev/null
+++ b/res/effectlib/sampleLight.glsllib
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** 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_LIGHT_GLSLLIB
+#define SAMPLE_LIGHT_GLSLLIB
+
+#define MAX_NUM_SHADOWS 8
+
+#ifndef QT3DS_ENABLE_SSM
+#define QT3DS_ENABLE_SSM 0
+#endif
+
+#include "SSAOCustomMaterial.glsllib"
+#if QT3DS_ENABLE_SSM
+#include "shadowMapping.glsllib"
+#endif
+
+#include "funcsampleLightVars.glsllib"
+
+#if QT3DS_ENABLE_SSM
+uniform sampler2D shadowMaps[MAX_NUM_SHADOWS];
+uniform samplerCube shadowCubes[MAX_NUM_SHADOWS];
+uniform int uNumShadowMaps;
+uniform int uNumShadowCubes;
+#endif
+
+void sampleLight(in LightSource light,
+ in vec3 pos,
+ out vec3 wi,
+ out vec3 opAmbient,
+ out vec3 opDiffuse,
+ out vec3 opSpecular)
+{
+ float att = 1.0;
+ if (light.position.w == 0.0) // directional light
+ {
+ wi = normalize(light.position.xyz);
+#if QT3DS_ENABLE_SSM
+ if ( light.shadowIdx >= 0 )
+ att *= sampleOrthographic( shadowMaps[light.shadowIdx], light.shadowControls, light.shadowView, pos, vec2(1.0, light.shadowControls.z) );
+#endif
+ }
+ else if (light.width > 0.01 && light.height > 0.01) // area light
+ {
+ // This approach is based on the 1994 Tech Report by James Arvo --
+ // The Irradiance Jacobian for Partially Occluded Polyhedral Sources
+ // The nice thing about this approach is that it extends to arbitrary geometry (if we choose to support it),
+ // and accounts for distance & geometric attenuation automatically.
+ // Downsides -- only really works for diffuse reflection, does not account properly for an area light that
+ // intersects its receiver, in which case it illuminates as if the light source is two-sided Lambertian emitter.
+ vec3 v0 = light.position.xyz - (light.right.xyz * light.width * 0.5) - (light.up.xyz * light.height * 0.5);
+ vec3 v1 = light.position.xyz - (light.right.xyz * light.width * 0.5) + (light.up.xyz * light.height * 0.5);
+ vec3 v2 = light.position.xyz + (light.right.xyz * light.width * 0.5) + (light.up.xyz * light.height * 0.5);
+ vec3 v3 = light.position.xyz + (light.right.xyz * light.width * 0.5) - (light.up.xyz * light.height * 0.5);
+
+ v0 = normalize( v0 - pos ); v1 = normalize( v1 - pos ); v2 = normalize( v2 - pos ); v3 = normalize( v3 - pos );
+
+ float a01 = acos( clamp( dot(v0, v1), -1.0, 1.0 ) );
+ float a12 = acos( clamp( dot(v1, v2), -1.0, 1.0 ) );
+ float a23 = acos( clamp( dot(v2, v3), -1.0, 1.0 ) );
+ float a30 = acos( clamp( dot(v3, v0), -1.0, 1.0 ) );
+
+ wi = vec3( 0.0 );
+ wi -= normalize(cross( v0, v1 )) * a01;
+ wi -= normalize(cross( v1, v2 )) * a12;
+ wi -= normalize(cross( v2, v3 )) * a23;
+ wi -= normalize(cross( v3, v0 )) * a30;
+
+ att = length(wi) * 0.15915494309; // solid angle / 2*pi
+ wi = normalize(wi);
+ att *= clamp( dot( pos - light.position.xyz, light.direction.xyz ), 0.0, 1.0 );
+#if QT3DS_ENABLE_SSM
+ if ( light.shadowIdx >= 0 )
+ att *= sampleCubemap( shadowCubes[light.shadowIdx], light.shadowControls, light.shadowView, light.position.xyz, pos, vec2(1.0, light.shadowControls.z) );
+#endif
+ }
+ else // point or spot light
+ {
+ wi = light.position.xyz - pos;
+ float dist = length(wi);
+ wi = wi / dist; // == normalize(wi);
+ att = 1.0 / (light.constantAttenuation + (light.linearAttenuation + light.quadraticAttenuation * dist) * dist);
+ /*
+ if (light.spotCutoff < 180.0) // spot light
+ {
+ float spot = max(0.0, dot(wi, -light.direction.xyz));
+ att *= (spot >= cos(light.spotCutoff * PI / 180.0)) ? pow(spot, light.spotExponent) : 0.0;
+ }
+ */
+#if QT3DS_ENABLE_SSM
+ if ( light.shadowIdx >= 0 )
+ att *= sampleCubemap( shadowCubes[light.shadowIdx], light.shadowControls, light.shadowView, light.position.xyz, pos, vec2(1.0, light.shadowControls.z) );
+#endif
+ }
+ float shadow = customMaterialShadow( -light.direction.xyz, pos );
+ opAmbient = att * light.ambient.xyz;
+ opDiffuse = att * shadow * light.diffuse.xyz;
+ opSpecular = att * shadow * light.specular.xyz;
+}
+
+#include "sampleArea.glsllib"
+
+#endif