diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-12-07 14:20:01 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-12-09 13:53:23 +0000 |
commit | 94f3df1aacab5853d09e79596eb3bdae3aecae0a (patch) | |
tree | 4db06240d22462becc9ad5b499926aa11316b88d /src/render | |
parent | 3655c334b0f4a28a1487c918384da50498ef9418 (diff) |
Add support for spotlights
Change-Id: I61a4e072c1a2e00cdbcee917aa557e56fb8cb7c0
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/lights/qpointlight.cpp | 4 | ||||
-rw-r--r-- | src/render/lights/qpointlight_p.h | 2 | ||||
-rw-r--r-- | src/render/lights/qspotlight.cpp | 7 | ||||
-rw-r--r-- | src/render/lights/qspotlight.h | 4 | ||||
-rw-r--r-- | src/render/lights/qspotlight_p.h | 4 | ||||
-rw-r--r-- | src/render/shaders/es2/light.inc.frag | 36 | ||||
-rw-r--r-- | src/render/shaders/gl3/light.inc.frag | 36 |
7 files changed, 59 insertions, 34 deletions
diff --git a/src/render/lights/qpointlight.cpp b/src/render/lights/qpointlight.cpp index 05fb85676..808378c2d 100644 --- a/src/render/lights/qpointlight.cpp +++ b/src/render/lights/qpointlight.cpp @@ -62,8 +62,8 @@ namespace Qt3DRender { \class Qt3DRender::QPointLightPrivate \internal */ -QPointLightPrivate::QPointLightPrivate() - : QLightPrivate(QLight::PointLight) +QPointLightPrivate::QPointLightPrivate(QLight::Type type) + : QLightPrivate(type) , m_attenuation(0.0f, 0.0f, 0.002f) { } diff --git a/src/render/lights/qpointlight_p.h b/src/render/lights/qpointlight_p.h index 2929ffd97..b7fb561ce 100644 --- a/src/render/lights/qpointlight_p.h +++ b/src/render/lights/qpointlight_p.h @@ -59,7 +59,7 @@ class QPointLight; class QPointLightPrivate : public QLightPrivate { public: - QPointLightPrivate(); + QPointLightPrivate(QLight::Type type = QLight::PointLight); QVector3D m_attenuation; diff --git a/src/render/lights/qspotlight.cpp b/src/render/lights/qspotlight.cpp index 13c81b494..1912852ce 100644 --- a/src/render/lights/qspotlight.cpp +++ b/src/render/lights/qspotlight.cpp @@ -67,8 +67,9 @@ namespace Qt3DRender { \internal */ QSpotLightPrivate::QSpotLightPrivate() - : QLightPrivate(QLight::SpotLight) + : QPointLightPrivate(QLight::SpotLight) , m_cutOffAngle(45.0f) + , m_direction(0.0f, -1.0f, 0.0f) { } @@ -106,13 +107,13 @@ void QSpotLight::copy(const QNode *ref) Constructs a new QSpotLight with the specified \a parent. */ QSpotLight::QSpotLight(QNode *parent) - : QLight(*new QSpotLightPrivate, parent) + : QPointLight(*new QSpotLightPrivate, parent) { } /*! \internal */ QSpotLight::QSpotLight(QSpotLightPrivate &dd, QNode *parent) - : QLight(dd, parent) + : QPointLight(dd, parent) { } diff --git a/src/render/lights/qspotlight.h b/src/render/lights/qspotlight.h index edba764cc..4c3c5dd53 100644 --- a/src/render/lights/qspotlight.h +++ b/src/render/lights/qspotlight.h @@ -37,7 +37,7 @@ #ifndef QT3DRENDER_QSPOTLIGHT_H #define QT3DRENDER_QSPOTLIGHT_H -#include <Qt3DRender/qlight.h> +#include <Qt3DRender/qpointlight.h> QT_BEGIN_NAMESPACE @@ -45,7 +45,7 @@ namespace Qt3DRender { class QSpotLightPrivate; -class QT3DRENDERSHARED_EXPORT QSpotLight : public QLight +class QT3DRENDERSHARED_EXPORT QSpotLight : public QPointLight { Q_OBJECT Q_PROPERTY(QVector3D direction READ direction WRITE setDirection NOTIFY directionChanged) diff --git a/src/render/lights/qspotlight_p.h b/src/render/lights/qspotlight_p.h index 66d5dfa6d..38adcdc51 100644 --- a/src/render/lights/qspotlight_p.h +++ b/src/render/lights/qspotlight_p.h @@ -48,13 +48,13 @@ // We mean it. // -#include <private/qlight_p.h> +#include <private/qpointlight_p.h> QT_BEGIN_NAMESPACE namespace Qt3DRender { -class QSpotLightPrivate : public QLightPrivate +class QSpotLightPrivate : public QPointLightPrivate { public: QSpotLightPrivate(); diff --git a/src/render/shaders/es2/light.inc.frag b/src/render/shaders/es2/light.inc.frag index bf8e3ff90..33714afc2 100644 --- a/src/render/shaders/es2/light.inc.frag +++ b/src/render/shaders/es2/light.inc.frag @@ -9,7 +9,7 @@ struct Light { FP float intensity; FP vec3 direction; FP vec3 attenuation; -// FP float cutOffAngle; + FP float cutOffAngle; }; uniform Light lights[MAX_LIGHTS]; uniform int lightCount; @@ -28,20 +28,24 @@ void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const for (i = 0; i < lightCount; ++i) { FP float att = 1.0; if ( lights[i].type != TYPE_DIRECTIONAL ) { - s = lights[i].position - vpos; + s = tangentMatrix * ( lights[i].position - vpos ); if (length( lights[i].attenuation ) != 0.0) { FP float dist = length(s); att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist); } + s = normalize( s ); + if ( lights[i].type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) + att = 0.0; + } } else { - s = -lights[i].direction; + s = normalize( tangentMatrix * -lights[i].direction ); } - s = normalize( tangentMatrix * s ); FP float diffuse = max( dot( s, n ), 0.0 ); FP float specular = 0.0; - if (diffuse > 0.0 && shininess > 0.0) { + if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { FP vec3 r = reflect( -s, n ); FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) ); FP float normFactor = ( shininess + 2.0 ) / 2.0; @@ -49,7 +53,7 @@ void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const } diffuseColor += att * lights[i].intensity * diffuse * lights[i].color; - specularColor += specular; + specularColor += att * specular; } } @@ -71,15 +75,19 @@ void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 FP float dist = length(s); att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist); } + s = normalize( s ); + if ( lights[i].type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) + att = 0.0; + } } else { - s = -lights[i].direction; + s = normalize( -lights[i].direction ); } - s = normalize( s ); FP float diffuse = max( dot( s, n ), 0.0 ); FP float specular = 0.0; - if (diffuse > 0.0 && shininess > 0.0) { + if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { FP vec3 r = reflect( -s, n ); FP vec3 v = normalize( eye - vpos ); FP float normFactor = ( shininess + 2.0 ) / 2.0; @@ -87,7 +95,7 @@ void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 } diffuseColor += att * lights[i].intensity * diffuse * lights[i].color; - specularColor += specular; + specularColor += att * specular; } } @@ -107,11 +115,15 @@ void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffus FP float dist = length(s); att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist); } + s = normalize( s ); + if ( lights[i].type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) + att = 0.0; + } } else { - s = -lights[i].direction; + s = normalize( -lights[i].direction ); } - s = normalize( s ); FP float diffuse = max( dot( s, n ), 0.0 ); diffuseColor += att * lights[i].intensity * diffuse * lights[i].color; diff --git a/src/render/shaders/gl3/light.inc.frag b/src/render/shaders/gl3/light.inc.frag index e9fcd127a..d3cce2edc 100644 --- a/src/render/shaders/gl3/light.inc.frag +++ b/src/render/shaders/gl3/light.inc.frag @@ -9,7 +9,7 @@ struct Light { float intensity; vec3 direction; vec3 attenuation; -// float cutOffAngle; + float cutOffAngle; }; uniform Light lights[MAX_LIGHTS]; uniform int lightCount; @@ -28,20 +28,24 @@ void adsModelNormalMapped(const in vec3 vpos, const in vec3 vnormal, const in ve for (i = 0; i < lightCount; ++i) { float att = 1.0; if ( lights[i].type != TYPE_DIRECTIONAL ) { - s = lights[i].position - vpos; + s = tangentMatrix * ( lights[i].position - vpos ); if (length( lights[i].attenuation ) != 0.0) { float dist = length(s); att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist); } + s = normalize( s ); + if ( lights[i].type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) + att = 0.0; + } } else { - s = -lights[i].direction; + s = normalize( tangentMatrix * -lights[i].direction ); } - s = normalize( tangentMatrix * s ); float diffuse = max( dot( s, n ), 0.0 ); float specular = 0.0; - if (diffuse > 0.0 && shininess > 0.0) { + if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { vec3 r = reflect( -s, n ); vec3 v = normalize( tangentMatrix * ( eye - vpos ) ); float normFactor = ( shininess + 2.0 ) / 2.0; @@ -49,7 +53,7 @@ void adsModelNormalMapped(const in vec3 vpos, const in vec3 vnormal, const in ve } diffuseColor += att * lights[i].intensity * diffuse * lights[i].color; - specularColor += specular; + specularColor += att * specular; } } @@ -71,15 +75,19 @@ void adsModel(const in vec3 vpos, const in vec3 vnormal, const in vec3 eye, cons float dist = length(s); att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist); } + s = normalize( s ); + if ( lights[i].type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) + att = 0.0; + } } else { - s = -lights[i].direction; + s = normalize( -lights[i].direction ); } - s = normalize( s ); float diffuse = max( dot( s, n ), 0.0 ); float specular = 0.0; - if (diffuse > 0.0 && shininess > 0.0) { + if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { vec3 r = reflect( -s, n ); vec3 v = normalize( eye - vpos ); float normFactor = ( shininess + 2.0 ) / 2.0; @@ -87,7 +95,7 @@ void adsModel(const in vec3 vpos, const in vec3 vnormal, const in vec3 eye, cons } diffuseColor += att * lights[i].intensity * diffuse * lights[i].color; - specularColor += specular; + specularColor += att * specular; } } @@ -107,11 +115,15 @@ void adModel(const in vec3 vpos, const in vec3 vnormal, out vec3 diffuseColor) float dist = length(s); att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist); } + s = normalize( s ); + if ( lights[i].type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) + att = 0.0; + } } else { - s = -lights[i].direction; + s = normalize( -lights[i].direction ); } - s = normalize( s ); float diffuse = max( dot( s, n ), 0.0 ); diffuseColor += att * lights[i].intensity * diffuse * lights[i].color; |