diff options
author | Oleg Evseev <ev.mipt@gmail.com> | 2017-05-12 12:35:08 +0300 |
---|---|---|
committer | Jani Heikkinen <jani.heikkinen@qt.io> | 2017-05-16 10:02:09 +0000 |
commit | 7261606116768d563c0e49a23ca60ab367a4cab5 (patch) | |
tree | d30e93a3fa5abd67c878cd7f1fda0005e23a9b32 | |
parent | c9dbd1025cf31ca512ff29a169970275b76752dc (diff) |
Fix speed regressions in ES2 shaders
The GLSL ES specification (up to at least 3.0) does not mandate support of
dynamic indexing of uniform block arrays. For that reason loops in ES2
shaders were unrolled by calling separate functions, but it had leaded to
rendering speed regressions. This patch reverts loops unrolling using
separate functions and replaces dynamic indexing in place instead.
Task-number: QTBUG-60183
Task-number: QTBUG-54994
Change-Id: Ieb036f442922de312b2941a0b8c511c0b4b3ec5a
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Reviewed-by: Oleg Evseev <ev.mipt@gmail.com>
-rw-r--r-- | src/extras/shaders/es2/light.inc.frag | 310 |
1 files changed, 137 insertions, 173 deletions
diff --git a/src/extras/shaders/es2/light.inc.frag b/src/extras/shaders/es2/light.inc.frag index 726340d7e..074af5799 100644 --- a/src/extras/shaders/es2/light.inc.frag +++ b/src/extras/shaders/es2/light.inc.frag @@ -14,215 +14,179 @@ struct Light { uniform Light lights[MAX_LIGHTS]; uniform int lightCount; -void addLightAdsModelNormalMapped(const in FP vec3 vpos, - const in FP vec3 n, - const in FP vec3 eye, - const in FP float shininess, - const in FP mat3 tangentMatrix, - const in Light light, - inout FP vec3 diffuseColor, - inout FP vec3 specularColor) -{ - FP vec3 snormal = normalize( vec3( tangentMatrix[0][2], tangentMatrix[1][2], tangentMatrix[2][2] ) ); - - FP vec3 s, ts; - FP float att = 1.0; - if ( light.type != TYPE_DIRECTIONAL ) { - s = light.position - vpos; - if ( dot(snormal, s) < 0.0 ) - att = 0.0; - else { - ts = normalize( tangentMatrix * s ); - if (length( light.attenuation ) != 0.0) { - FP float dist = length(s); - att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); - } - s = normalize( s ); - if ( light.type == TYPE_SPOT ) { - if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) - att = 0.0; - } - } - } else { - if ( dot(snormal, -light.direction) > 0.0 ) - s = normalize( tangentMatrix * -light.direction ); - else - att = 0.0; - } - - FP float diffuse = max( dot( ts, n ), 0.0 ); - - FP float specular = 0.0; - if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { - FP vec3 r = reflect( -ts, 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 * light.intensity * diffuse * light.color; - specularColor += att * light.intensity * specular * light.color; -} - 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); - if (lightCount < 1) return; - FP vec3 n = normalize( vnormal ); - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[0], diffuseColor, specularColor); - if (lightCount < 2) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[1], diffuseColor, specularColor); - if (lightCount < 3) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[2], diffuseColor, specularColor); - if (lightCount < 4) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[3], diffuseColor, specularColor); - if (lightCount < 5) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[4], diffuseColor, specularColor); - if (lightCount < 6) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[5], diffuseColor, specularColor); - if (lightCount < 7) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[6], diffuseColor, specularColor); - if (lightCount < 8) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[7], diffuseColor, specularColor); -} + FP vec3 snormal = normalize( vec3( tangentMatrix[0][2], tangentMatrix[1][2], tangentMatrix[2][2] ) ); -void addLightAdsModel(const in FP vec3 vpos, - const in FP vec3 n, - const in FP vec3 eye, - const in FP float shininess, - const in Light light, - inout FP vec3 diffuseColor, - inout FP vec3 specularColor) -{ - FP vec3 s; + FP vec3 n = normalize( vnormal ); - FP float att = 1.0; - if ( light.type != TYPE_DIRECTIONAL ) { - s = light.position - vpos; - if (length( light.attenuation ) != 0.0) { - FP float dist = length(s); - att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); - } - s = normalize( s ); - if ( light.type == TYPE_SPOT ) { - if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) + FP vec3 s, ts; + Light light; + for (int i = 0; i < lightCount; ++i) { + if (i == 0) + light = lights[0]; + else if (i == 1) + light = lights[1]; + else if (i == 2) + light = lights[2]; + else if (i == 3) + light = lights[3]; + else if (i == 4) + light = lights[4]; + else if (i == 5) + light = lights[5]; + else if (i == 6) + light = lights[6]; + else if (i == 7) + light = lights[7]; + + FP float att = 1.0; + if ( light.type != TYPE_DIRECTIONAL ) { + s = light.position - vpos; + if ( dot(snormal, s) < 0.0 ) + att = 0.0; + else { + ts = normalize( tangentMatrix * s ); + if (length( light.attenuation ) != 0.0) { + FP float dist = length(s); + att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); + } + s = normalize( s ); + if ( light.type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) + att = 0.0; + } + } + } else { + if ( dot(snormal, -light.direction) > 0.0 ) + s = normalize( tangentMatrix * -light.direction ); + else att = 0.0; } - } else { - s = normalize( -light.direction ); - } - FP float diffuse = max( dot( s, n ), 0.0 ); - FP float specular = 0.0; + FP float diffuse = max( dot( ts, n ), 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; - specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); - } + FP float specular = 0.0; + if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { + FP vec3 r = reflect( -ts, 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 * light.intensity * diffuse * light.color; - specularColor += att * light.intensity * specular * light.color; + diffuseColor += att * light.intensity * diffuse * light.color; + specularColor += att * light.intensity * specular * light.color; + } } - 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); - if (lightCount < 1) return; FP vec3 n = normalize( vnormal ); - addLightAdsModel(vpos, n, eye, shininess, lights[0], diffuseColor, specularColor); - if (lightCount < 2) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[1], diffuseColor, specularColor); - if (lightCount < 3) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[2], diffuseColor, specularColor); - if (lightCount < 4) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[3], diffuseColor, specularColor); - if (lightCount < 5) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[4], diffuseColor, specularColor); - if (lightCount < 6) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[5], diffuseColor, specularColor); - if (lightCount < 7) return; - addLightAdsModel(vpos, n, eye, shininess, lights[6], diffuseColor, specularColor); - if (lightCount < 8) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[7], diffuseColor, specularColor); -} - -void addLightAdModel(const in FP vec3 vpos, - const in FP vec3 n, - const in Light light, - inout FP vec3 diffuseColor) -{ FP vec3 s; - FP float att = 1.0; - if ( light.type != TYPE_DIRECTIONAL ) { - s = light.position - vpos; - if (length( light.attenuation ) != 0.0) { - FP float dist = length(s); - att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); - } - s = normalize( s ); - if ( light.type == TYPE_SPOT ) { - if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) - att = 0.0; + Light light; + for (int i = 0; i < lightCount; ++i) { + if (i == 0) + light = lights[0]; + else if (i == 1) + light = lights[1]; + else if (i == 2) + light = lights[2]; + else if (i == 3) + light = lights[3]; + else if (i == 4) + light = lights[4]; + else if (i == 5) + light = lights[5]; + else if (i == 6) + light = lights[6]; + else if (i == 7) + light = lights[7]; + + FP float att = 1.0; + if ( light.type != TYPE_DIRECTIONAL ) { + s = light.position - vpos; + if (length( light.attenuation ) != 0.0) { + FP float dist = length(s); + att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); + } + s = normalize( s ); + if ( light.type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) + att = 0.0; + } + } else { + s = normalize( -light.direction ); } - } else { - s = normalize( -light.direction ); - } - FP float diffuse = max( dot( s, n ), 0.0 ); + FP float diffuse = max( dot( s, n ), 0.0 ); + + FP float specular = 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; + specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); + } - diffuseColor += att * light.intensity * diffuse * light.color; + diffuseColor += att * light.intensity * diffuse * light.color; + specularColor += att * light.intensity * specular * light.color; + } } void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor) { diffuseColor = vec3(0.0); - if (lightCount < 1) return; FP vec3 n = normalize( vnormal ); - addLightAdModel(vpos, n, lights[0], diffuseColor); - if (lightCount < 2) return; - - addLightAdModel(vpos, n, lights[1], diffuseColor); - if (lightCount < 3) return; - addLightAdModel(vpos, n, lights[2], diffuseColor); - if (lightCount < 4) return; - - addLightAdModel(vpos, n, lights[3], diffuseColor); - if (lightCount < 5) return; - - addLightAdModel(vpos, n, lights[4], diffuseColor); - if (lightCount < 6) return; - - addLightAdModel(vpos, n, lights[5], diffuseColor); - if (lightCount < 7) return; + FP vec3 s; + Light light; + for (int i = 0; i < lightCount; ++i) { + if (i == 0) + light = lights[0]; + else if (i == 1) + light = lights[1]; + else if (i == 2) + light = lights[2]; + else if (i == 3) + light = lights[3]; + else if (i == 4) + light = lights[4]; + else if (i == 5) + light = lights[5]; + else if (i == 6) + light = lights[6]; + else if (i == 7) + light = lights[7]; + + FP float att = 1.0; + if ( light.type != TYPE_DIRECTIONAL ) { + s = light.position - vpos; + if (length( light.attenuation ) != 0.0) { + FP float dist = length(s); + att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); + } + s = normalize( s ); + if ( light.type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) + att = 0.0; + } + } else { + s = normalize( -light.direction ); + } - addLightAdModel(vpos, n, lights[6], diffuseColor); - if (lightCount < 8) return; + FP float diffuse = max( dot( s, n ), 0.0 ); - addLightAdModel(vpos, n, lights[7], diffuseColor); + diffuseColor += att * light.intensity * diffuse * light.color; + } } |