diff options
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/backend/renderview.cpp | 1 | ||||
-rw-r--r-- | src/render/materialsystem/qshaderprogram.cpp | 11 | ||||
-rw-r--r-- | src/render/render.qrc | 1 | ||||
-rw-r--r-- | src/render/shaders/es2/light.inc.frag | 116 | ||||
-rw-r--r-- | src/render/shaders/es2/light.inc.frag100 | 257 |
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; +} |