@ -8,12 +8,18 @@ in vec3 fragNormal;
out vec4 f i n a l C o l o r ;
uniform sampler2D t e x t u r e 0 ;
uniform sampler2D t e x t u r e 1 ;
uniform sampler2D t e x t u r e 2 ;
uniform vec4 c o l T i n t ;
uniform vec4 c o l A m b i e n t ;
uniform vec4 c o l D i f f u s e ;
uniform vec4 c o l S p e c u l a r ;
uniform float g l o s s i n e s s ;
uniform int u s e N o r m a l ;
uniform int u s e S p e c u l a r ;
uniform mat4 m o d e l M a t r i x ;
uniform vec3 v i e w D i r ;
@ -24,7 +30,7 @@ struct Light {
vec3 d i r e c t i o n ;
vec4 d i f f u s e ;
float i n t e n s i t y ;
float a t t e n u a t i o n ;
float r a d i u s ;
float c o n e A n g l e ;
} ;
@ -32,27 +38,27 @@ const int maxLights = 8;
uniform int l i g h t s C o u n t ;
uniform Light l i g h t s [ m a x L i g h t s ] ;
vec3 CalcPointLight(Light l, vec3 n, vec3 err">v )
vec3 CalcPointLight(Light l, vec3 n, vec3 nf">v, float s )
{
vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1 ) ) ;
vec3 surfaceToLight = l.position - s u r f a c e P o s ;
// Diffuse s h a d i n g
float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0 , 1 ) ;
float diff = 1 .0 /dot(surfaceToLight/l.attenuation , s u r f a c e T o L i g h t / l . a t t e n u a t i o n ) * b r i g h t n e s s * l . i n t e n s i t y ;
float diff = 1 .0 /dot(surfaceToLight/l.radius , s u r f a c e T o L i g h t / l . r a d i u s ) * b r i g h t n e s s * l . i n t e n s i t y ;
// Specular s h a d i n g
float spec = 0 .0 ;
if (diff > 0 .0 )
{
vec3 h = normalize(-l.direction + v ) ;
spec = pow(dot(n, h), 3 + g l o s s i n e s s ) ;
spec = pow(dot(n, h), 3 + g l o s s i n e s s ) * s ;
}
return (diff*l.diffuse.rgb*colDiffuse.rgb + s p e c * c o l S p e c u l a r . r g b ) ;
}
vec3 CalcDirectionalLight(Light l, vec3 n, vec3 err">v )
vec3 CalcDirectionalLight(Light l, vec3 n, vec3 nf">v, float s )
{
vec3 lightDir = n o r m a l i z e ( - l . d i r e c t i o n ) ;
@ -64,14 +70,14 @@ vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v)
if (diff > 0 .0 )
{
vec3 h = normalize(lightDir + v ) ;
spec = pow(dot(n, h), 3 + g l o s s i n e s s ) ;
spec = pow(dot(n, h), 3 + g l o s s i n e s s ) * s ;
}
// Combine r e s u l t s
return (diff*l.intensity*l.diffuse.rgb*colDiffuse.rgb + s p e c * c o l S p e c u l a r . r g b ) ;
}
vec3 CalcSpotLight(Light l, vec3 n, vec3 err">v )
vec3 CalcSpotLight(Light l, vec3 n, vec3 nf">v, float s )
{
vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1 ) ) ;
vec3 lightToSurface = normalize(surfacePos - l . p o s i t i o n ) ;
@ -95,7 +101,7 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v)
if (diffAttenuation > 0 .0 )
{
vec3 h = normalize(lightDir + v ) ;
spec = pow(dot(n, h), 3 + g l o s s i n e s s ) ;
spec = pow(dot(n, h), 3 + g l o s s i n e s s ) * s ;
}
return falloff*(diffAttenuation*l.diffuse.rgb + s p e c * c o l S p e c u l a r . r g b ) ;
@ -104,9 +110,10 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v)
void m a i n ( )
{
// Calculate fragment normal in screen s p a c e
// NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and s c a l e )
mat3 normalMatrix = t r a n s p o s e ( i n v e r s e ( m a t 3 ( m o d e l M a t r i x ) ) ) ;
vec3 normal = n o r m a l i z e ( n o r m a l M a t r i x * f r a g N o r m a l ) ;
// Normalize normal and view direction v e c t o r s
vec3 n = n o r m a l i z e ( n o r m a l ) ;
vec3 v = n o r m a l i z e ( v i e w D i r ) ;
@ -115,6 +122,17 @@ void main()
vec4 texelColor = texture(texture0, f r a g T e x C o o r d ) ;
vec3 lighting = c o l A m b i e n t . r g b ;
// Calculate normal texture color fetching or set to maximum normal value by d e f a u l t
if(useNormal == 1 )
{
n *= texture(texture1, f r a g T e x C o o r d ) . r g b ;
n = n o r m a l i z e ( n ) ;
}
// Calculate specular texture color fetching or set to maximum specular value by d e f a u l t
float spec = 1 .0 ;
if(useSpecular == 1 ) spec *= normalize(texture(texture2, f r a g T e x C o o r d ) . r ) ;
for (int i = 0 ; i < lightsCount; i + + )
{
// Check if light is e n a b l e d
@ -123,14 +141,14 @@ void main()
// Calculate lighting based on light t y p e
switch ( l i g h t s [ i ] . t y p e )
{
case 0 : lighting += CalcPointLight(lights[i], n, v); b r e a k ;
case 1 : lighting += CalcDirectionalLight(lights[i], n, v); b r e a k ;
case 2 : lighting += CalcSpotLight(lights[i], n, v); b r e a k ;
case 0 : lighting += CalcPointLight(lights[i], n, v, spec ); b r e a k ;
case 1 : lighting += CalcDirectionalLight(lights[i], n, v, spec ); b r e a k ;
case 2 : lighting += CalcSpotLight(lights[i], n, v, spec ); b r e a k ;
default: b r e a k ;
}
}
}
// Calculate final fragment c o l o r
finalColor = vec4(texelColor.rgb*lighting, t e x e l C o l o r . a ) ;
finalColor = vec4(texelColor.rgb*lighting*colTint.rgb , t e x e l C o l o r. a * c o l T i n t . a ) ;
}