NazaraEngine/src/Nazara/Renderer/Shaders/Model/compatibility.frag

226 lines
6.7 KiB
GLSL

#if FLAG_DEFERRED
#error Deferred Shading needs core profile
#endif
#define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1
#define LIGHT_SPOT 2
/********************Entrant********************/
varying mat3 vLightToWorld;
varying vec3 vNormal;
varying vec2 vTexCoord;
varying vec3 vWorldPos;
/********************Uniformes********************/
struct Light
{
int type;
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 parameters1;
vec4 parameters2;
vec2 parameters3;
};
uniform vec3 EyePosition;
uniform Light Lights[3];
uniform sampler2D MaterialAlphaMap;
uniform float MaterialAlphaThreshold;
uniform vec4 MaterialAmbient;
uniform vec4 MaterialDiffuse;
uniform sampler2D MaterialDiffuseMap;
uniform sampler2D MaterialEmissiveMap;
uniform sampler2D MaterialNormalMap;
uniform float MaterialShininess;
uniform vec4 MaterialSpecular;
uniform sampler2D MaterialSpecularMap;
uniform vec4 SceneAmbient;
/********************Fonctions********************/
void main()
{
vec4 fragmentColor = MaterialDiffuse;
#if DIFFUSE_MAPPING
fragmentColor *= texture2D(MaterialDiffuseMap, vTexCoord);
#endif
#if ALPHA_MAPPING
fragmentColor.a *= texture2D(MaterialAlphaMap, vTexCoord).r;
#endif
#if ALPHA_TEST
if (fragmentColor.a < MaterialAlphaThreshold)
discard;
#endif
#if LIGHTING
vec3 lightColor = vec3(0.0);
#if SPECULAR_MAPPING
vec3 specularColor = vec3(0.0);
#endif
#if NORMAL_MAPPING
vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture2D(MaterialNormalMap, vTexCoord)) - 1.0));
#else
vec3 normal = normalize(vNormal);
#endif
if (MaterialShininess > 0.0)
{
vec3 eyeVec = normalize(EyePosition - vWorldPos);
for (int i = 0; i < 3; ++i)
{
if (Lights[i].type == LIGHT_DIRECTIONAL)
{
vec3 lightDir = normalize(-Lights[i].parameters1.xyz);
// Ambient
lightColor += Lights[i].ambient.rgb * (MaterialAmbient.rgb + SceneAmbient.rgb);
// Diffuse
float lambert = max(dot(normal, lightDir), 0.0);
lightColor += lambert * Lights[i].diffuse.rgb * MaterialDiffuse.rgb;
// Specular
vec3 reflection = reflect(-lightDir, normal);
float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);
#if SPECULAR_MAPPING
specularColor += specular * Lights[i].specular.rgb * MaterialSpecular.rgb;
#else
lightColor += specular * Lights[i].specular.rgb * MaterialSpecular.rgb;
#endif
}
else if (Lights[i].type == LIGHT_POINT)
{
vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos;
float att = max(Lights[i].parameters1.w - Lights[i].parameters2.x*length(lightDir), 0.0);
lightDir = normalize(lightDir);
// Ambient
lightColor += att * Lights[i].ambient.rgb * (MaterialAmbient.rgb + SceneAmbient.rgb);
// Diffuse
float lambert = max(dot(normal, lightDir), 0.0);
lightColor += att * lambert * Lights[i].diffuse.rgb * MaterialDiffuse.rgb;
// Specular
vec3 reflection = reflect(-lightDir, normal);
float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);
#if SPECULAR_MAPPING
specularColor += att * specular * Lights[i].specular.rgb * MaterialSpecular.rgb;
#else
lightColor += att * specular * Lights[i].specular.rgb * MaterialSpecular.rgb;
#endif
}
else if (Lights[i].type == LIGHT_SPOT)
{
vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos;
float att = max(Lights[i].parameters1.w - Lights[i].parameters2.x*length(lightDir), 0.0);
lightDir = normalize(lightDir);
// Ambient
lightColor += att * Lights[i].ambient.rgb * (MaterialAmbient.rgb + SceneAmbient.rgb);
// Modification de l'atténuation
float curAngle = dot(Lights[i].parameters2.xyz, -lightDir);
float outerAngle = Lights[i].parameters3.y;
float innerMinusOuterAngle = Lights[i].parameters3.x - outerAngle;
float lambert = max(dot(normal, lightDir), 0.0);
att *= max((curAngle - outerAngle) / innerMinusOuterAngle, 0.0);
// Diffuse
lightColor += att * lambert * Lights[i].diffuse.rgb * MaterialDiffuse.rgb;
// Specular
vec3 reflection = reflect(-lightDir, normal);
float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);
#if SPECULAR_MAPPING
specularColor += att * specular * Lights[i].specular.rgb * MaterialSpecular.rgb;
#else
lightColor += att * specular * Lights[i].specular.rgb * MaterialSpecular.rgb;
#endif
}
}
}
else
{
for (int i = 0; i < 3; ++i)
{
if (Lights[i].type == LIGHT_DIRECTIONAL)
{
vec3 lightDir = normalize(-Lights[i].parameters1.xyz);
// Ambient
lightColor += Lights[i].ambient.rgb * (MaterialAmbient.rgb + SceneAmbient.rgb);
// Diffuse
float lambert = max(dot(normal, lightDir), 0.0);
lightColor += lambert * Lights[i].diffuse.rgb * MaterialDiffuse.rgb;
}
else if (Lights[i].type == LIGHT_POINT)
{
vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos;
float att = max(Lights[i].parameters1.w - Lights[i].parameters2.x*length(lightDir), 0.0);
lightDir = normalize(lightDir);
// Ambient
lightColor += att * Lights[i].ambient.rgb * (MaterialAmbient.rgb + SceneAmbient.rgb);
// Diffuse
float lambert = max(dot(normal, lightDir), 0.0);
lightColor += att * lambert * Lights[i].diffuse.rgb * MaterialDiffuse.rgb;
}
else if (Lights[i].type == LIGHT_SPOT)
{
vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos;
float att = max(Lights[i].parameters1.w - Lights[i].parameters2.x*length(lightDir), 0.0);
lightDir = normalize(lightDir);
// Ambient
lightColor += att * Lights[i].ambient.rgb * (MaterialAmbient.rgb + SceneAmbient.rgb);
// Modification de l'atténuation
float curAngle = dot(Lights[i].parameters2.xyz, -lightDir);
float outerAngle = Lights[i].parameters3.y;
float innerMinusOuterAngle = Lights[i].parameters3.x - outerAngle;
float lambert = max(dot(normal, lightDir), 0.0);
att *= max((curAngle - outerAngle) / innerMinusOuterAngle, 0.0);
// Diffuse
lightColor += att * lambert * Lights[i].diffuse.rgb * MaterialDiffuse.rgb;
}
}
}
fragmentColor *= vec4(lightColor, 1.0);
#if SPECULAR_MAPPING
fragmentColor *= vec4(specularColor * texture2D(MaterialSpecularMap, vTexCoord).rgb, 1.0); // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens
#endif
#if EMISSIVE_MAPPING
#if SPECULAR_MAPPING
float lightIntensity = dot(lightColor + specularColor, vec3(0.3, 0.59, 0.11));
#else
float lightIntensity = dot(lightColor, vec3(0.3, 0.59, 0.11));
#endif // SPECULAR_MAPPING
vec3 emissionColor = MaterialDiffuse.rgb * texture2D(MaterialEmissiveMap, vTexCoord).rgb;
gl_FragColor = vec4(mix(fragmentColor.rgb, emissionColor, clamp(1.0 - 3.0*lightIntensity, 0.0, 1.0)), fragmentColor.a);
#else
gl_FragColor = fragmentColor;
#endif // EMISSIVE_MAPPING
#else
gl_FragColor = fragmentColor;
#endif // LIGHTING
}