#version 150 compatibility uniform bool local_viewer = false; uniform int lights_enabled[gl_MaxLights]; // tells about the state of the lights (whether they are enabled or not) /** * Computes the lighting calculations for a directional light. * * \param lightSource the light source for which to do the lighting * \param lightModelProduct the light product for the light source * \param normal the surface normal for the fragment * \param ambient the ambient factor in which to write the new ambient factor * \param diffuse the diffuse factor in which to write the new diffuse factor * \param specular the specular factor in which to write the new specular factor */ void computeDirectionalLight(in gl_LightSourceParameters lightSource, in gl_LightProducts lightProduct, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { float diffuseFactor = max(dot(normal, normalize(vec3(lightSource.position))), 0.0); float specularFactor = 0.0; if (diffuseFactor > 0.0) { specularFactor = max(dot(normal, vec3(lightSource.halfVector)), 0.0); specularFactor = pow(specularFactor, gl_FrontMaterial.shininess); } ambient += lightProduct.ambient; diffuse += lightSource.diffuse * diffuseFactor; specular += lightProduct.specular * specularFactor; } /** * Computes the lighting calculations for a directional light in the Phong illumination modell. * * \param lightSource the light source for which to do the lighting * \param lightModelProduct the light product for the light source * \param normal the surface normal for the fragment * \param ambient the ambient factor in which to write the new ambient factor * \param diffuse the diffuse factor in which to write the new diffuse factor * \param specular the specular factor in which to write the new specular factor */ void computeDirectionalLightPhong(in gl_LightSourceParameters lightSource, in gl_LightProducts lightProduct, in vec3 viewVector, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { vec3 lightVector = normalize(vec3(lightSource.position)); float diffuseFactor = max(dot(normal, lightVector), 0.0); float specularFactor = 0.0; if (diffuseFactor > 0.0) { vec3 reflectVector = 2.0*dot(normal,lightVector)*normal - lightVector; specularFactor = max(dot(reflectVector, viewVector), 0.0); specularFactor = pow(specularFactor, gl_FrontMaterial.shininess); } ambient += lightProduct.ambient; diffuse += lightSource.diffuse * diffuseFactor; specular += lightProduct.specular * specularFactor; } /** * Computes the lighting calculations for a point light. * * \param lightSource the light source for which to do the lighting * \param lightModelProduct the light product for the light source * \param viewVector the viewing vector * \param position the position of the fragment in eye coordinate space * \param normal the surface normal for the fragment * \param ambient the ambient factor in which to write the new ambient factor * \param diffuse the diffuse factor in which to write the new diffuse factor * \param specular the specular factor in which to write the new specular factor */ void computePointLight(in gl_LightSourceParameters lightSource, in gl_LightProducts lightProduct, in vec3 viewVector, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { vec3 lightVec = lightSource.position.xyz / lightSource.position.w - position; // vector from fragment to light source float distance = length(lightVec); // distance between surface and light position lightVec = normalize(lightVec); // attenuation factor float attenuation = 1.0 / (lightSource.constantAttenuation + lightSource.linearAttenuation * distance + lightSource.quadraticAttenuation * distance * distance); float diffuseFactor = max(dot(normal, lightVec), 0.0); float specularFactor = 0.0; if (diffuseFactor > 0.0) { vec3 halfVector = normalize(lightVec + viewVector); specularFactor = max(dot(normal, halfVector), 0.0); specularFactor = pow(specularFactor, gl_FrontMaterial.shininess); } ambient += lightProduct.ambient * attenuation; diffuse += lightSource.diffuse * diffuseFactor * attenuation; specular += lightProduct.specular * specularFactor * attenuation; } /** * Computes the lighting calculations for a point light. * * \param lightSource the light source for which to do the lighting * \param lightModelProduct the light product for the light source * \param viewVector the viewing vector * \param position the position of the fragment in eye coordinate space * \param normal the surface normal for the fragment * \param ambient the ambient factor in which to write the new ambient factor * \param diffuse the diffuse factor in which to write the new diffuse factor * \param specular the specular factor in which to write the new specular factor */ void computePointLightPhong(in gl_LightSourceParameters lightSource, in gl_LightProducts lightProduct, in vec3 viewVector, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { vec3 lightVec = lightSource.position.xyz / lightSource.position.w - position; // vector from fragment to light source float distance = length(lightVec); // distance between surface and light position lightVec = normalize(lightVec); // attenuation factor float attenuation = 1.0 / (lightSource.constantAttenuation + lightSource.linearAttenuation * distance + lightSource.quadraticAttenuation * distance * distance); float diffuseFactor = max(dot(normal, lightVec), 0.0); float specularFactor = 0.0; if (diffuseFactor > 0.0) { vec3 reflectVector = 2.0*dot(normal,lightVec)*normal - lightVec; specularFactor = max(dot(reflectVector, viewVector), 0.0); specularFactor = pow(specularFactor, gl_FrontMaterial.shininess); } ambient += lightProduct.ambient * attenuation; diffuse += lightSource.diffuse * diffuseFactor * attenuation; specular += lightProduct.specular * specularFactor * attenuation; } /** * Computes the lighting calculations for a spot light. * * \param lightSource the light source for which to do the lighting * \param lightModelProduct the light product for the light source * \param viewVector the viewing vector * \param position the position of the fragment in eye coordinate space * \param normal the surface normal for the fragment * \param ambient the ambient factor in which to write the new ambient factor * \param diffuse the diffuse factor in which to write the new diffuse factor * \param specular the specular factor in which to write the new specular factor */ void computeSpotLight(in gl_LightSourceParameters lightSource, in gl_LightProducts lightProduct, in vec3 viewVector, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { vec3 lightVec = lightSource.position.xyz / lightSource.position.w - position; // vector from fragment to light source float distance = length(lightVec); // distance between surface and light position lightVec = normalize(lightVec); // see if point on surface is inside cone of illumination float spotDot = dot(-lightVec, normalize(lightSource.spotDirection)); if (spotDot >= lightSource.spotCosCutoff) { // light adds contribution // attenuation factor float attenuation = 1.0 / (lightSource.constantAttenuation + lightSource.linearAttenuation * distance + lightSource.quadraticAttenuation * distance * distance); // combine the spotlight and distance attenuation if (lightSource.spotExponent != 0.0) attenuation *= pow(spotDot, lightSource.spotExponent); float diffuseFactor = max(0.0, dot(normal, lightVec)); float specularFactor = 0.0; if (diffuseFactor > 0.0) { vec3 halfVector = normalize(lightVec + viewVector); specularFactor = max(0.0, dot(normal, halfVector)); specularFactor = pow(specularFactor, gl_FrontMaterial.shininess); } ambient += lightProduct.ambient * attenuation; diffuse += lightSource.diffuse * diffuseFactor * attenuation; specular += lightProduct.specular * specularFactor * attenuation; } } /** * Computes the lighting calculations for a spot light. * * \param lightSource the light source for which to do the lighting * \param lightModelProduct the light product for the light source * \param viewVector the viewing vector * \param position the position of the fragment in eye coordinate space * \param normal the surface normal for the fragment * \param ambient the ambient factor in which to write the new ambient factor * \param diffuse the diffuse factor in which to write the new diffuse factor * \param specular the specular factor in which to write the new specular factor */ void computeSpotLightPhong(in gl_LightSourceParameters lightSource, in gl_LightProducts lightProduct, in vec3 viewVector, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { vec3 lightVec = lightSource.position.xyz / lightSource.position.w - position; // vector from fragment to light source float distance = length(lightVec); // distance between surface and light position lightVec = normalize(lightVec); // see if point on surface is inside cone of illumination float spotDot = dot(-lightVec, normalize(lightSource.spotDirection)); if (spotDot >= lightSource.spotCosCutoff) { // light adds contribution // attenuation factor float attenuation = 1.0 / (lightSource.constantAttenuation + lightSource.linearAttenuation * distance + lightSource.quadraticAttenuation * distance * distance); // combine the spotlight and distance attenuation if (lightSource.spotExponent != 0.0) attenuation *= pow(spotDot, lightSource.spotExponent); float diffuseFactor = max(0.0, dot(normal, lightVec)); float specularFactor = 0.0; if (diffuseFactor > 0.0) { vec3 reflectVector = 2.0*dot(normal,lightVec)*normal - lightVec; specularFactor = max(dot(reflectVector, viewVector), 0.0); specularFactor = pow(specularFactor, gl_FrontMaterial.shininess); } ambient += lightProduct.ambient * attenuation; diffuse += lightSource.diffuse * diffuseFactor * attenuation; specular += lightProduct.specular * specularFactor * attenuation; } } /** * Does the lighting calculation. * * \param position the position of the fragment in eye coordinates * \param normal the normal of the fragment in eye coordinates * \param diffuseMaterial the diffuse material color * \return the fragment color resulting from illumination computations */ vec4 doTwoSidedLighting(vec3 position, vec3 normal, vec4 diffuseMaterial, int side) { // http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml normal = normalize(normal); // if GL_NORMALIZE is enabled (Page 217); makes no sense here // normal = normal * gl_NormalScale; // if GL_RESCALE_NORMAL is enabled (Page 217); makes no sense here // http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml vec3 viewVector = vec3(0.0, 0.0, 1.0); // not local viewer if (local_viewer) viewVector = -normalize(position); // if GL_LIGHT_MODEL_LOCAL_VIEWER is set to != 0 (Page 222) vec4 ambient = vec4(0.0); // ambient color (variant 1) / factor (variant 2) vec4 diffuse = vec4(0.0); // diffuse color (variant 1) / factor (variant 2) vec4 specular = vec4(0.0); // specular color (variant 1) / factor (variant 2) for (int i = 0; i < gl_MaxLights; i++) { //if (enabled[i] == 1) if (lights_enabled[i] == 1) { if (gl_LightSource[i].position.w == 0.0) computeDirectionalLight(gl_LightSource[i], side == 1 ? gl_FrontLightProduct[i] : gl_BackLightProduct[i], normal, ambient, diffuse, specular); else if (gl_LightSource[i].spotCutoff == 180.0) computePointLight(gl_LightSource[i], side == 1 ? gl_FrontLightProduct[i] : gl_BackLightProduct[i], viewVector, position, normal, ambient, diffuse, specular); else computeSpotLight(gl_LightSource[i], side == 1 ? gl_FrontLightProduct[i] : gl_BackLightProduct[i], viewVector, position, normal, ambient, diffuse, specular); } } // sceneColor = Ecm + Acm * Acs // 'Ecm' == gl_FrontMaterial.emission // 'Acm' == gl_FrontMaterial.ambient // 'Acs' = ambient color of scene (set through 'glLightModelfv(GL_LIGHT_MODEL_AMBIENT, sceneAmbient);') return (side == 1 ? gl_FrontLightModelProduct.sceneColor : gl_BackLightModelProduct.sceneColor) + ambient + diffuseMaterial * diffuse + specular; } /** * Does the lighting calculation. * * \param position the position of the fragment in eye coordinates * \param normal the normal of the fragment in eye coordinates * \param diffuseMaterial the diffuse material color * \return the fragment color resulting from illumination computations */ vec4 doLightingAmb(vec3 position, vec3 normal, vec4 ambientMaterial, vec4 diffuseMaterial) { // http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml normal = normalize(normal); // if GL_NORMALIZE is enabled (Page 217); makes no sense here // normal = normal * gl_NormalScale; // if GL_RESCALE_NORMAL is enabled (Page 217); makes no sense here // http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml vec3 viewVector = vec3(0.0, 0.0, 1.0); // not local viewer if (local_viewer) viewVector = -normalize(position); // if GL_LIGHT_MODEL_LOCAL_VIEWER is set to != 0 (Page 222) vec4 ambient = vec4(0.0); // ambient color (variant 1) / factor (variant 2) vec4 diffuse = vec4(0.0); // diffuse color (variant 1) / factor (variant 2) vec4 specular = vec4(0.0); // specular color (variant 1) / factor (variant 2) for (int i = 0; i < gl_MaxLights; i++) { //if (enabled[i] == 1) if (lights_enabled[i] == 1) { if (gl_LightSource[i].position.w == 0.0) computeDirectionalLight(gl_LightSource[i], gl_FrontLightProduct[i], normal, ambient, diffuse, specular); else if (gl_LightSource[i].spotCutoff == 180.0) computePointLight(gl_LightSource[i], gl_FrontLightProduct[i], viewVector, position, normal, ambient, diffuse, specular); else computeSpotLight(gl_LightSource[i], gl_FrontLightProduct[i], viewVector, position, normal, ambient, diffuse, specular); } } // sceneColor = Ecm + Acm * Acs // 'Ecm' == gl_FrontMaterial.emission // 'Acm' == gl_FrontMaterial.ambient // 'Acs' = ambient color of scene (set through 'glLightModelfv(GL_LIGHT_MODEL_AMBIENT, sceneAmbient);') return gl_FrontLightModelProduct.sceneColor + ambientMaterial * ambient + diffuseMaterial * diffuse + specular; } vec4 doLighting(vec3 position, vec3 normal, vec4 diffuseMaterial) { // http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml normal = normalize(normal); // if GL_NORMALIZE is enabled (Page 217); makes no sense here // normal = normal * gl_NormalScale; // if GL_RESCALE_NORMAL is enabled (Page 217); makes no sense here // http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml vec3 viewVector = vec3(0.0, 0.0, 1.0); // not local viewer if (local_viewer) viewVector = -normalize(position); // if GL_LIGHT_MODEL_LOCAL_VIEWER is set to != 0 (Page 222) vec4 ambient = vec4(0.0); // ambient color (variant 1) / factor (variant 2) vec4 diffuse = vec4(0.0); // diffuse color (variant 1) / factor (variant 2) vec4 specular = vec4(0.0); // specular color (variant 1) / factor (variant 2) for (int i = 0; i < gl_MaxLights; i++) { //if (enabled[i] == 1) if (lights_enabled[i] == 1) { if (gl_LightSource[i].position.w == 0.0) computeDirectionalLight(gl_LightSource[i], gl_FrontLightProduct[i], normal, ambient, diffuse, specular); else if (gl_LightSource[i].spotCutoff == 180.0) computePointLight(gl_LightSource[i], gl_FrontLightProduct[i], viewVector, position, normal, ambient, diffuse, specular); else computeSpotLight(gl_LightSource[i], gl_FrontLightProduct[i], viewVector, position, normal, ambient, diffuse, specular); } } // sceneColor = Ecm + Acm * Acs // 'Ecm' == gl_FrontMaterial.emission // 'Acm' == gl_FrontMaterial.ambient // 'Acs' = ambient color of scene (set through 'glLightModelfv(GL_LIGHT_MODEL_AMBIENT, sceneAmbient);') return gl_FrontLightModelProduct.sceneColor + ambient + diffuseMaterial * diffuse + specular; } /** * Does the lighting calculation with the Phong Illumination model. * * \param position the position of the fragment in eye coordinates * \param normal the normal of the fragment in eye coordinates * \param diffuseMaterial the diffuse material color * \return the fragment color resulting from illumination computations */ vec4 doPhongLighting(vec3 position, vec3 normal, vec4 diffuseMaterial) { // http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml normal = normalize(normal); // if GL_NORMALIZE is enabled (Page 217); makes no sense here // normal = normal * gl_NormalScale; // if GL_RESCALE_NORMAL is enabled (Page 217); makes no sense here // http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml vec3 viewVector = vec3(0.0, 0.0, 1.0); // not local viewer if (local_viewer) viewVector = -normalize(position); // if GL_LIGHT_MODEL_LOCAL_VIEWER is set to != 0 (Page 222) vec4 ambient = vec4(0.0); // ambient color (variant 1) / factor (variant 2) vec4 diffuse = vec4(0.0); // diffuse color (variant 1) / factor (variant 2) vec4 specular = vec4(0.0); // specular color (variant 1) / factor (variant 2) for (int i = 0; i < gl_MaxLights; i++) { //if (enabled[i] == 1) if (lights_enabled[i] == 1) { if (gl_LightSource[i].position.w == 0.0) computeDirectionalLightPhong(gl_LightSource[i], gl_FrontLightProduct[i], viewVector, normal, ambient, diffuse, specular); else if (gl_LightSource[i].spotCutoff == 180.0) computePointLightPhong(gl_LightSource[i], gl_FrontLightProduct[i], viewVector, position, normal, ambient, diffuse, specular); else computeSpotLightPhong(gl_LightSource[i], gl_FrontLightProduct[i], viewVector, position, normal, ambient, diffuse, specular); } } // sceneColor = Ecm + Acm * Acs // 'Ecm' == gl_FrontMaterial.emission // 'Acm' == gl_FrontMaterial.ambient // 'Acs' = ambient color of scene (set through 'glLightModelfv(GL_LIGHT_MODEL_AMBIENT, sceneAmbient);') return gl_FrontLightModelProduct.sceneColor + ambient + diffuseMaterial * diffuse + specular; }