summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/render/backend/renderview.cpp1
-rw-r--r--src/render/materialsystem/qshaderprogram.cpp11
-rw-r--r--src/render/render.qrc1
-rw-r--r--src/render/shaders/es2/light.inc.frag116
-rw-r--r--src/render/shaders/es2/light.inc.frag100257
5 files changed, 331 insertions, 55 deletions
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index fa02447b3..6c1f4b4e9 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -784,7 +784,6 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass,
}
}
- // Shaders without dynamic indexing will not have lightCount
if (uniformNames.contains(LIGHT_COUNT_NAME))
setUniformValue(command->m_uniforms, LIGHT_COUNT_NAME, qMax(1, lightIdx));
diff --git a/src/render/materialsystem/qshaderprogram.cpp b/src/render/materialsystem/qshaderprogram.cpp
index 2dff5856f..51faac661 100644
--- a/src/render/materialsystem/qshaderprogram.cpp
+++ b/src/render/materialsystem/qshaderprogram.cpp
@@ -241,9 +241,16 @@ static QByteArray deincludify(const QString &filePath)
const QByteArray includeDirective = QByteArrayLiteral("#pragma include");
for (int i = 0; i < lines.count(); ++i) {
if (lines[i].startsWith(includeDirective)) {
- QByteArray includeFileName = lines[i].mid(includeDirective.count() + 1);
+ QString includeFileName = QFileInfo(filePath).absolutePath()
+ + QStringLiteral("/")
+ + QString::fromUtf8(lines[i].mid(includeDirective.count() + 1));
+ if (qEnvironmentVariableIsSet("QT3D_GLSL100_WORKAROUND")) {
+ QString candidate = includeFileName + QStringLiteral("100");
+ if (QFile::exists(candidate))
+ includeFileName = candidate;
+ }
lines.removeAt(i);
- QByteArray includedContents = deincludify(QFileInfo(filePath).absolutePath() + QStringLiteral("/") + QString::fromUtf8(includeFileName));
+ QByteArray includedContents = deincludify(includeFileName);
lines.insert(i, includedContents);
QString lineDirective = QString(QStringLiteral("#line %1")).arg(i + 2);
lines.insert(i + 1, lineDirective.toUtf8());
diff --git a/src/render/render.qrc b/src/render/render.qrc
index d479e5ef0..0cf54286b 100644
--- a/src/render/render.qrc
+++ b/src/render/render.qrc
@@ -2,6 +2,7 @@
<qresource prefix="/">
<file>shaders/gl3/light.inc.frag</file>
<file>shaders/es2/light.inc.frag</file>
+ <file>shaders/es2/light.inc.frag100</file>
<file>shaders/gl3/phong.vert</file>
<file>shaders/gl3/phong.frag</file>
<file>shaders/es2/phong.vert</file>
diff --git a/src/render/shaders/es2/light.inc.frag b/src/render/shaders/es2/light.inc.frag
index e4ab11938..bf8e3ff90 100644
--- a/src/render/shaders/es2/light.inc.frag
+++ b/src/render/shaders/es2/light.inc.frag
@@ -23,30 +23,34 @@ void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const
FP vec3 n = normalize( vnormal );
- // TODO dynamic indexing may not be supported with GLSL 1.00 so take only the first light into account
- FP vec3 s = -lights[0].direction;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = lights[0].position - vpos;
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ int i;
+ FP vec3 s;
+ for (i = 0; i < lightCount; ++i) {
+ FP float att = 1.0;
+ if ( lights[i].type != TYPE_DIRECTIONAL ) {
+ s = 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);
+ }
+ } else {
+ s = -lights[i].direction;
}
- }
- s = normalize( tangentMatrix * s );
- FP float diffuse = max( dot( s, n ), 0.0 );
+ 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) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
- specularColor += specular;
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ specularColor += specular;
+ }
}
void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
@@ -57,30 +61,34 @@ void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3
FP vec3 n = normalize( vnormal );
- // TODO dynamic indexing may not be supported with GLSL 1.00 so take only the first light into account
- FP vec3 s = -lights[0].direction;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = lights[0].position - vpos;
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ int i;
+ FP vec3 s;
+ for (i = 0; i < lightCount; ++i) {
+ FP float att = 1.0;
+ if ( lights[i].type != TYPE_DIRECTIONAL ) {
+ s = 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);
+ }
+ } else {
+ s = -lights[i].direction;
}
- }
- s = normalize( s );
- FP float diffuse = max( dot( s, n ), 0.0 );
+ s = normalize( s );
+ FP float diffuse = max( dot( s, n ), 0.0 );
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( eye - vpos );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( eye - vpos );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
- specularColor += specular;
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ specularColor += specular;
+ }
}
void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor)
@@ -89,19 +97,23 @@ void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffus
FP vec3 n = normalize( vnormal );
- // TODO dynamic indexing may not be supported with GLSL 1.00 so take only the first light into account
- FP vec3 s = -lights[0].direction;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = lights[0].position - vpos;
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ int i;
+ FP vec3 s;
+ for (i = 0; i < lightCount; ++i) {
+ FP float att = 1.0;
+ if ( lights[i].type != TYPE_DIRECTIONAL ) {
+ s = 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);
+ }
+ } else {
+ s = -lights[i].direction;
}
- }
- s = normalize( s );
- FP float diffuse = max( dot( s, n ), 0.0 );
+ s = normalize( s );
+ FP float diffuse = max( dot( s, n ), 0.0 );
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ }
}
diff --git a/src/render/shaders/es2/light.inc.frag100 b/src/render/shaders/es2/light.inc.frag100
new file mode 100644
index 000000000..830b7e8b0
--- /dev/null
+++ b/src/render/shaders/es2/light.inc.frag100
@@ -0,0 +1,257 @@
+const int MAX_LIGHTS = 3;
+const int TYPE_POINT = 0;
+const int TYPE_DIRECTIONAL = 1;
+const int TYPE_SPOT = 2;
+struct Light {
+ int type;
+ FP vec3 position;
+ FP vec3 color;
+ FP float intensity;
+ FP vec3 direction;
+ FP vec3 attenuation;
+// FP float cutOffAngle;
+};
+uniform Light lights[MAX_LIGHTS];
+uniform int lightCount;
+
+void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
+ const in FP mat3 tangentMatrix,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ // 0
+ if (lightCount < 1)
+ return;
+ FP vec3 s = -lights[0].direction;
+ FP float att = 1.0;
+ if ( lights[0].type != TYPE_DIRECTIONAL ) {
+ s = lights[0].position - vpos;
+ if (length( lights[0].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ }
+ }
+
+ 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) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
+ specularColor += specular;
+
+ // 1
+ if (lightCount < 2)
+ return;
+ s = -lights[1].direction;
+ att = 1.0;
+ if ( lights[1].type != TYPE_DIRECTIONAL ) {
+ s = lights[1].position - vpos;
+ if (length( lights[1].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
+ }
+ }
+
+ s = normalize( tangentMatrix * s );
+ diffuse = max( dot( s, n ), 0.0 );
+
+ specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
+ specularColor += specular;
+
+ // 2
+ if (lightCount < 3)
+ return;
+ s = -lights[2].direction;
+ att = 1.0;
+ if ( lights[2].type != TYPE_DIRECTIONAL ) {
+ s = lights[2].position - vpos;
+ if (length( lights[2].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[2].attenuation.x + lights[2].attenuation.y * dist + lights[2].attenuation.z * dist * dist);
+ }
+ }
+
+ s = normalize( tangentMatrix * s );
+ diffuse = max( dot( s, n ), 0.0 );
+
+ specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[2].intensity * diffuse * lights[2].color;
+ specularColor += specular;
+}
+
+void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ // 0
+ if (lightCount < 1)
+ return;
+ FP vec3 s = -lights[0].direction;
+ FP float att = 1.0;
+ if ( lights[0].type != TYPE_DIRECTIONAL ) {
+ s = lights[0].position - vpos;
+ if (length( lights[0].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ }
+ }
+
+ s = normalize( s );
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( eye - vpos );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
+ specularColor += specular;
+
+ // 1
+ if (lightCount < 2)
+ return;
+ s = -lights[1].direction;
+ att = 1.0;
+ if ( lights[1].type != TYPE_DIRECTIONAL ) {
+ s = lights[1].position - vpos;
+ if (length( lights[1].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
+ }
+ }
+
+ s = normalize( s );
+ diffuse = max( dot( s, n ), 0.0 );
+
+ specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( eye - vpos );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
+ specularColor += specular;
+
+ // 2
+ if (lightCount < 3)
+ return;
+ s = -lights[2].direction;
+ att = 1.0;
+ if ( lights[2].type != TYPE_DIRECTIONAL ) {
+ s = lights[2].position - vpos;
+ if (length( lights[2].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[2].attenuation.x + lights[2].attenuation.y * dist + lights[2].attenuation.z * dist * dist);
+ }
+ }
+
+ s = normalize( s );
+ diffuse = max( dot( s, n ), 0.0 );
+
+ specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( eye - vpos );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[2].intensity * diffuse * lights[2].color;
+ specularColor += specular;
+}
+
+void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor)
+{
+ diffuseColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ // 0
+ if (lightCount < 1)
+ return;
+ FP vec3 s = -lights[0].direction;
+ FP float att = 1.0;
+ if ( lights[0].type != TYPE_DIRECTIONAL ) {
+ s = lights[0].position - vpos;
+ if (length( lights[0].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ }
+ }
+
+ s = normalize( s );
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
+
+ // 1
+ if (lightCount < 2)
+ return;
+ s = -lights[1].direction;
+ att = 1.0;
+ if ( lights[1].type != TYPE_DIRECTIONAL ) {
+ s = lights[1].position - vpos;
+ if (length( lights[1].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
+ }
+ }
+
+ s = normalize( s );
+ diffuse = max( dot( s, n ), 0.0 );
+
+ diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
+
+ // 2
+ if (lightCount < 3)
+ return;
+ s = -lights[2].direction;
+ att = 1.0;
+ if ( lights[2].type != TYPE_DIRECTIONAL ) {
+ s = lights[2].position - vpos;
+ if (length( lights[2].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[2].attenuation.x + lights[2].attenuation.y * dist + lights[2].attenuation.z * dist * dist);
+ }
+ }
+
+ s = normalize( s );
+ diffuse = max( dot( s, n ), 0.0 );
+
+ diffuseColor += att * lights[2].intensity * diffuse * lights[2].color;
+}