#define MAX_LIGHTS 8 /* Attributes */ attribute vec3 inVertexPosition; attribute vec3 inVertexNormal; attribute vec4 inVertexColor; attribute vec2 inTexCoord0; attribute vec2 inTexCoord1; /* Uniforms */ uniform mat4 uWVPMatrix; uniform mat4 uWVMatrix; uniform mat4 uNMatrix; uniform vec4 uGlobalAmbient; uniform vec4 uMaterialAmbient; uniform vec4 uMaterialDiffuse; uniform vec4 uMaterialEmissive; uniform vec4 uMaterialSpecular; uniform float uMaterialShininess; uniform int uLightCount; uniform int uLightType[MAX_LIGHTS]; uniform vec3 uLightPosition[MAX_LIGHTS]; uniform vec3 uLightDirection[MAX_LIGHTS]; uniform vec3 uLightAttenuation[MAX_LIGHTS]; uniform vec4 uLightAmbient[MAX_LIGHTS]; uniform vec4 uLightDiffuse[MAX_LIGHTS]; uniform vec4 uLightSpecular[MAX_LIGHTS]; uniform float uThickness; /* Varyings */ varying vec2 vTextureCoord0; varying vec4 vVertexColor; varying vec4 vSpecularColor; varying float vFogCoord; void dirLight(in int index, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { vec3 L = normalize(-(uNMatrix * vec4(uLightDirection[index], 0.0)).xyz); ambient += uLightAmbient[index]; float NdotL = dot(normal, L); if (NdotL > 0.0) { diffuse += uLightDiffuse[index] * NdotL; vec3 E = normalize(-position); vec3 HalfVector = normalize(L + E); float NdotH = max(0.0, dot(normal, HalfVector)); float SpecularFactor = pow(NdotH, uMaterialShininess); specular += uLightSpecular[index] * SpecularFactor; } } void pointLight(in int index, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { vec3 L = uLightPosition[index] - position; float D = length(L); L = normalize(L); float Attenuation = 1.0 / (uLightAttenuation[index].x + uLightAttenuation[index].y * D + uLightAttenuation[index].z * D * D); ambient += uLightAmbient[index] * Attenuation; float NdotL = dot(normal, L); if (NdotL > 0.0) { diffuse += uLightDiffuse[index] * NdotL * Attenuation; vec3 E = normalize(-position); vec3 HalfVector = normalize(L + E); float NdotH = max(0.0, dot(normal, HalfVector)); float SpecularFactor = pow(NdotH, uMaterialShininess); specular += uLightSpecular[index] * SpecularFactor * Attenuation; } } void spotLight(in int index, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { // TO-DO } void main() { gl_Position = uWVPMatrix * vec4(inVertexPosition, 1.0); gl_PointSize = uThickness; vec3 Position = (uWVMatrix * vec4(inVertexPosition, 1.0)).xyz; vec3 P = normalize(Position); vec3 N = normalize(vec4(uNMatrix * vec4(inVertexNormal, 0.0)).xyz); vec3 R = reflect(P, N); float V = 2.0 * sqrt(R.x*R.x + R.y*R.y + (R.z+1.0)*(R.z+1.0)); vTextureCoord0 = vec2(R.x/V + 0.5, R.y/V + 0.5); vVertexColor = inVertexColor.bgra; vSpecularColor = vec4(0.0, 0.0, 0.0, 0.0); if (uLightCount > 0) { vec3 Normal = normalize((uNMatrix * vec4(inVertexNormal, 0.0)).xyz); vec4 Ambient = vec4(0.0, 0.0, 0.0, 0.0); vec4 Diffuse = vec4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < int(MAX_LIGHTS); i++) { if( i >= uLightCount ) // can't use uniform as loop-counter directly in glsl break; if (uLightType[i] == 0) pointLight(i, Position, Normal, Ambient, Diffuse, vSpecularColor); } for (int i = 0; i < int(MAX_LIGHTS); i++) { if( i >= uLightCount ) break; if (uLightType[i] == 1) spotLight(i, Position, Normal, Ambient, Diffuse, vSpecularColor); } for (int i = 0; i < int(MAX_LIGHTS); i++) { if( i >= uLightCount ) break; if (uLightType[i] == 2) dirLight(i, Position, Normal, Ambient, Diffuse, vSpecularColor); } vec4 LightColor = Ambient * uMaterialAmbient + Diffuse * uMaterialDiffuse; LightColor = clamp(LightColor, 0.0, 1.0); LightColor.w = 1.0; vVertexColor *= LightColor; vVertexColor += uMaterialEmissive; vVertexColor += uGlobalAmbient * uMaterialAmbient; vVertexColor = clamp(vVertexColor, 0.0, 1.0); vSpecularColor *= uMaterialSpecular; } vFogCoord = length(Position); }