const int MAX_LIGHTS = 4; 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; FP float att = 1.0; if ( lights[0].type != TYPE_DIRECTIONAL ) { s = tangentMatrix * ( 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 ); if ( lights[0].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle) att = 0.0; } } else { s = normalize( tangentMatrix * -lights[0].direction ); } 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( 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 += att * specular; // 1 if (lightCount < 2) return; att = 1.0; if ( lights[1].type != TYPE_DIRECTIONAL ) { s = tangentMatrix * ( 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 ); if ( lights[1].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle) att = 0.0; } } else { s = normalize( tangentMatrix * -lights[1].direction ); } diffuse = max( dot( s, n ), 0.0 ); specular = 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; specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); } diffuseColor += att * lights[1].intensity * diffuse * lights[1].color; specularColor += att * specular; // 2 if (lightCount < 3) return; att = 1.0; if ( lights[2].type != TYPE_DIRECTIONAL ) { s = tangentMatrix * ( 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 ); if ( lights[2].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[2].direction))) ) > lights[2].cutOffAngle) att = 0.0; } } else { s = normalize( tangentMatrix * -lights[2].direction ); } diffuse = max( dot( s, n ), 0.0 ); specular = 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; specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); } diffuseColor += att * lights[2].intensity * diffuse * lights[2].color; specularColor += att * specular; // 3 if (lightCount < 4) return; att = 1.0; if ( lights[3].type != TYPE_DIRECTIONAL ) { s = tangentMatrix * ( lights[3].position - vpos ); if (length( lights[3].attenuation ) != 0.0) { FP float dist = length(s); att = 1.0 / (lights[3].attenuation.x + lights[3].attenuation.y * dist + lights[3].attenuation.z * dist * dist); } s = normalize( s ); if ( lights[3].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[3].direction))) ) > lights[3].cutOffAngle) att = 0.0; } } else { s = normalize( tangentMatrix * -lights[3].direction ); } diffuse = max( dot( s, n ), 0.0 ); specular = 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; specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); } diffuseColor += att * lights[3].intensity * diffuse * lights[3].color; specularColor += att * 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; 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 ); if ( lights[0].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle) att = 0.0; } } else { s = normalize( -lights[0].direction ); } 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 * lights[0].intensity * diffuse * lights[0].color; specularColor += att * specular; // 1 if (lightCount < 2) return; 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 ); if ( lights[1].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle) att = 0.0; } } else { s = normalize( -lights[1].direction ); } diffuse = max( dot( s, n ), 0.0 ); 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 * lights[1].intensity * diffuse * lights[1].color; specularColor += att * specular; // 2 if (lightCount < 3) return; 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 ); if ( lights[2].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[2].direction))) ) > lights[2].cutOffAngle) att = 0.0; } } else { s = normalize( -lights[2].direction ); } diffuse = max( dot( s, n ), 0.0 ); 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 * lights[2].intensity * diffuse * lights[2].color; specularColor += att * specular; // 3 if (lightCount < 4) return; att = 1.0; if ( lights[3].type != TYPE_DIRECTIONAL ) { s = lights[3].position - vpos; if (length( lights[3].attenuation ) != 0.0) { FP float dist = length(s); att = 1.0 / (lights[3].attenuation.x + lights[3].attenuation.y * dist + lights[3].attenuation.z * dist * dist); } s = normalize( s ); if ( lights[3].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[3].direction))) ) > lights[3].cutOffAngle) att = 0.0; } } else { s = normalize( -lights[3].direction ); } diffuse = max( dot( s, n ), 0.0 ); 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 * lights[3].intensity * diffuse * lights[3].color; specularColor += att * 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; 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 ); if ( lights[0].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle) att = 0.0; } } else { s = normalize( -lights[0].direction ); } FP float diffuse = max( dot( s, n ), 0.0 ); diffuseColor += att * lights[0].intensity * diffuse * lights[0].color; // 1 if (lightCount < 2) return; 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 ); if ( lights[1].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle) att = 0.0; } } else { s = normalize( -lights[1].direction ); } diffuse = max( dot( s, n ), 0.0 ); diffuseColor += att * lights[1].intensity * diffuse * lights[1].color; // 2 if (lightCount < 3) return; 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 ); if ( lights[2].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[2].direction))) ) > lights[2].cutOffAngle) att = 0.0; } } else { s = normalize( -lights[2].direction ); } diffuse = max( dot( s, n ), 0.0 ); diffuseColor += att * lights[2].intensity * diffuse * lights[2].color; // 3 if (lightCount < 4) return; att = 1.0; if ( lights[3].type != TYPE_DIRECTIONAL ) { s = lights[3].position - vpos; if (length( lights[3].attenuation ) != 0.0) { FP float dist = length(s); att = 1.0 / (lights[3].attenuation.x + lights[3].attenuation.y * dist + lights[3].attenuation.z * dist * dist); } s = normalize( s ); if ( lights[3].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[3].direction))) ) > lights[3].cutOffAngle) att = 0.0; } } else { s = normalize( -lights[3].direction ); } diffuse = max( dot( s, n ), 0.0 ); diffuseColor += att * lights[3].intensity * diffuse * lights[3].color; }