#version 100 precision mediump int; precision highp float; uniform vec3 ambient; uniform vec3 lightDif0; uniform vec4 lightPos0; uniform vec4 lightAtt0; uniform vec3 lightSpec0; uniform vec3 lightDif1; uniform vec4 lightPos1; uniform vec4 lightAtt1; uniform vec3 lightSpec1; uniform vec3 lightDif2; uniform vec4 lightPos2; uniform vec4 lightAtt2; uniform vec3 lightSpec2; uniform vec3 camPos; uniform vec4 matAmb; uniform vec4 matEmissive; uniform vec4 matDif; uniform vec4 matSpec; uniform float matShininess; uniform vec4 invSMSize; uniform vec4 spotlightParams0; uniform vec4 spotlightParams1; uniform vec4 spotlightParams2; uniform mat4 iTWMat; uniform float normalMul; uniform float reflectivity; uniform float fresnelMul; uniform float fresnelPow; uniform sampler2D diffuseMap; uniform sampler2D specMap; uniform sampler2D normalMap; uniform samplerCube reflectMap; varying vec3 oNorm; varying vec3 oTang; varying vec3 oBinormal; varying vec3 oSpDir0; varying vec3 oSpDir1; varying vec3 oSpDir2; varying vec4 oWp; varying vec4 oUv0; highp mat3 transposeMat3(in highp mat3 inMatrix) { highp vec3 i0 = inMatrix[0]; highp vec3 i1 = inMatrix[1]; highp vec3 i2 = inMatrix[2]; highp mat3 outMatrix = mat3( vec3(i0.x, i1.x, i2.x), vec3(i0.y, i1.y, i2.y), vec3(i0.z, i1.z, i2.z) ); return outMatrix;} void main() { vec3 normalTex = texture2D(normalMap, oUv0.zw).xyz; mat3 tbn = mat3(oTang.x * normalMul, oBinormal.x * normalMul, oNorm.x, oTang.y * normalMul, oBinormal.y * normalMul, oNorm.y, oTang.z * normalMul, oBinormal.z * normalMul, oNorm.z); vec3 normal = transposeMat3(tbn) * ((normalTex.xyz - vec3(0.5)) * vec3(2.0)); // to object space normal = normalize(mat3(iTWMat) * normal); vec3 ld0 = normalize(lightPos0.xyz - (vec3(lightPos0.w) * oWp.xyz)); vec3 ld1 = normalize(lightPos1.xyz - (vec3(lightPos1.w) * oWp.xyz)); vec3 ld2 = normalize(lightPos2.xyz - (vec3(lightPos2.w) * oWp.xyz)); // attenuation float lightDist = length(lightPos0.xyz - oWp.xyz) / (lightAtt0.x / lightAtt0.x); float la0 = 1.0; float ila = 0.0; if(lightAtt0.a > 0.0) { ila = lightDist * lightDist; // quadratic falloff la0 = 1.0 / (lightAtt0.g + lightAtt0.b * lightDist + lightAtt0.a * ila); } // attenuation lightDist = length(lightPos1.xyz - oWp.xyz) / (lightAtt1.x / lightAtt1.x); float la1 = 1.0; if(lightAtt1.a > 0.0) { ila = lightDist * lightDist; // quadratic falloff la1 = 1.0 / (lightAtt1.g + lightAtt1.b * lightDist + lightAtt1.a * ila); } // attenuation lightDist = length(lightPos2.xyz - oWp.xyz) / (lightAtt2.x / lightAtt2.x); float la2 = 1.0; if(lightAtt2.a > 0.0) { ila = lightDist * lightDist; // quadratic falloff la2 = 1.0 / (lightAtt2.g + lightAtt2.b * lightDist + lightAtt2.a * ila); } vec3 diffuse0 = vec3(max(dot(normal, ld0), 0.0)) * lightDif0; vec3 diffuse1 = vec3(max(dot(normal, ld1), 0.0)) * lightDif1; vec3 diffuse2 = vec3(max(dot(normal, ld2), 0.0)) * lightDif2; // calculate the spotlight effect float spot0 = ((spotlightParams0.w == 0.0) ? 1.0 : // if so, then it's not a spot light clamp(((dot(normalize(-oSpDir0), ld0) - spotlightParams0.y) / (spotlightParams0.x - spotlightParams0.y)), 0.0, 1.0)); float spot1 = ((spotlightParams1.w == 0.0) ? 1.0 : // if so, then it's not a spot light clamp(((dot(normalize(-oSpDir1), ld1) - spotlightParams1.y) / (spotlightParams1.x - spotlightParams1.y)), 0.0, 1.0)); float spot2 = ((spotlightParams2.w == 0.0) ? 1.0 : // if so, then it's not a spot light clamp(((dot(normalize(-oSpDir2), ld2) - spotlightParams2.y) / (spotlightParams2.x - spotlightParams2.y)), 0.0, 1.0)); vec3 camDir = normalize(camPos - oWp.xyz); vec3 halfVec = normalize(ld0 + camDir); vec3 specularLight = pow(vec3(max(dot(normal, halfVec), 0.0)), vec3(matShininess)) * lightSpec0; halfVec = normalize(ld1 + camDir); specularLight += pow(vec3(max(dot(normal, halfVec), 0.0)), vec3(matShininess)) * lightSpec1; halfVec = normalize(ld2 + camDir); specularLight += pow(vec3(max(dot(normal, halfVec), 0.0)), vec3(matShininess)) * lightSpec2; vec3 diffuseLight = (diffuse0 * vec3(spot0 * la0)) + (diffuse1 * vec3(spot1 * la1)) + (diffuse2 * vec3(spot2 * la2)); vec3 ambientColor = max(matEmissive.xyz, ambient * matAmb.xyz); vec3 diffuseContrib = matDif.xyz; vec4 diffuseTex = texture2D(diffuseMap, oUv0.xy); ambientColor *= diffuseTex.xyz; diffuseContrib *= diffuseTex.xyz; vec3 specularContrib = specularLight * matSpec.xyz; vec4 specTex = texture2D(specMap, oUv0.zw); specularContrib *= specTex.xyz; vec3 light0C = ambientColor + (diffuseLight * diffuseContrib) + specularContrib; float alpha = matDif.a; alpha *= diffuseTex.a; vec3 refVec = -reflect(camDir, normal); refVec.z = -refVec.z; vec4 reflecTex = textureCube(reflectMap, refVec); float fresnel = fresnelMul * reflectivity * pow(1.0 + dot(-camDir, normal), fresnelPow - (reflectivity * fresnelMul)); vec4 reflecVal = reflecTex * fresnel; vec3 reflectColor = reflecVal.xyz * (1.0 - light0C); gl_FragColor = vec4(light0C + reflectColor, alpha); }