1 /* 2 Copyright (c) 2008 Seneca College 3 Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/) 4 */ 5 6 // 7 c3dl.light_vs = 8 9 10 11 // We need to create our own light structure since we can't access 12 // the light() function in the 2.0 context. 13 "struct Light" + 14 "{" + 15 16 // figure out culling/light bug 17 //" int isOn;" + 18 " bool isOn;" + 19 " int type;" + 20 21 " vec3 ambient;" + 22 " vec3 diffuse;" + 23 " vec3 specular;" + 24 " vec4 position;" + 25 26 // Used if the light is a spotlight 27 " vec3 spotDirection;" + 28 " float spotExponent;" + 29 " float spotCutoff;" + 30 31 // Not used in calculations if the light is directional, since directional 32 // lights do not attenuate. 33 " float attenuation1;" + 34 " float attenuation2;" + 35 " float attenuation3;" + 36 "};" + 37 38 "uniform vec3 ambientLightColor;" + 39 40 // global lighting state, if this is off, no light calculations 41 // are computed. 42 "uniform bool lightingOn;" + 43 44 // 45 "const int C3DL_MAX_LIGHTS = 7;" + 46 47 // custom light structures needed, we can't access opengl light states. 48 "uniform Light lights[C3DL_MAX_LIGHTS];" + 49 50 51 /* 52 A Spotlight is a positional light with a constraint which prevents light from radiating from 53 all directions from the point light. Instead a cone of light is created which lights up objects. 54 55 Light light - the light in viewspace 56 vec3 normal - transformed normal 57 vec3 eye - 58 vec3 ecPos - vertex in eye coordinate space. 59 vec3 ambient - 60 vec3 diffuse - 61 vec3 specular - 62 float shininess - 63 */ 64 "void c3dl_SpotLight( in Light light, in vec3 normal, in vec3 eye, in vec3 ecPos, " + 65 " inout vec3 ambient, inout vec3 diffuse, inout vec3 specular, " + 66 " float shininess)" + 67 "{" + 68 " float nDotVP; " + 69 " float nDotHV; " + 70 " float spotDot; " + 71 " float spotAttenuation;" + 72 " float attenuation;" + 73 " float d;" + 74 " vec3 VP;" + 75 " float pf;" + 76 " vec3 halfVector;" + 77 78 // calculate the vector from the current vertex to the light. 79 " VP = vec3(light.position) - ecPos; " + 80 81 " vec3 ldir = normalize(light.spotDirection);" + 82 83 " d = length(VP);" + 84 " VP = normalize(VP);" + 85 86 " attenuation = 1.0 / (light.attenuation1 + (light.attenuation2 * d) + (light.attenuation3 * d * d));" + 87 88 // dot product of the vector from vertex to light and light direction. 89 " spotDot = dot(-VP, ldir);" + 90 91 // if the vertex falls inside the cone 92 " if(spotDot > cos(radians(light.spotCutoff)))" + 93 " {" + 94 " spotAttenuation = pow(spotDot, light.spotExponent);" + 95 " }" + 96 " else{" + 97 " spotAttenuation = 0.0;" + 98 " }" + 99 100 101 " attenuation *= spotAttenuation;" + 102 103 " halfVector = normalize(VP + eye);" + 104 105 " nDotVP = max(0.0, dot(normal, VP));" + 106 " nDotHV = max(0.0, dot(normal, halfVector));" + 107 108 // 109 " if(nDotVP == 0.0){" + 110 " pf = 0.0;" + 111 " }" + 112 " else{"+ 113 " pf = pow(nDotHV, shininess);" + 114 " }" + 115 116 " ambient += light.ambient * attenuation;" + 117 " diffuse += light.diffuse * nDotVP * attenuation; " + 118 " specular += light.specular * pf * attenuation;" + 119 "}" + 120 121 122 123 124 /* 125 A point light is similar to a lightbulb in that light rays radiate out in all directions. 126 Unlike directional lights, point lights attenuate with distance. 127 128 Light light - the light in view space 129 vec3 normal - 130 vec3 eye - 131 vec3 ecPos - 132 vec3 ambient - 133 vec3 diffuse - 134 vec3 specular - 135 float shininess - 136 */ 137 "void c3dl_PointLight( in Light light, in vec3 normal, in vec3 eye, in vec3 ecPos, " + 138 " inout vec3 ambient, inout vec3 diffuse, inout vec3 specular, " + 139 " float shininess)" + 140 "{" + 141 // get the vector from the current vertex to the light's position. 142 " vec3 VP = vec3(light.position) - ecPos;" + 143 144 // amount of shininess 145 " float pf;" + 146 147 // vector midway between VP and eye 148 " vec3 halfVector = normalize(VP + eye);" + 149 150 // get the distance from the current vector to the light position 151 " float d = length(VP); " + 152 153 // normalize the light so it can be used in the dot product operation. 154 " VP = normalize(VP);" + 155 156 // calculate the attenuation 157 " float attenuation = 1.0 / (light.attenuation1 + (light.attenuation2 * d) + (light.attenuation3 * d * d));" + 158 159 " float nDotVP = max(0.0, dot(normal, VP));"+ 160 " float nDotHV = max(0.0, dot(normal, halfVector));" + 161 162 // 163 " if(nDotVP == 0.0){" + 164 " pf = 0.0;" + 165 " }" + 166 " else{"+ 167 " pf = pow(nDotHV, shininess);" + 168 " }" + 169 170 // similar to the directional light, except we apply attenuation. 171 " ambient += light.ambient * attenuation;" + 172 " diffuse += light.diffuse * nDotVP * attenuation;" + 173 " specular += light.specular * pf * attenuation;" + 174 "}" + 175 176 177 /* 178 Light light - the light in view space 179 vec3 normal - 180 vec3 ambient - 181 vec3 diffuse - 182 vec3 specular - 183 float shininess - 184 */ 185 "void c3dl_DirectionalLight(in Light light, in vec3 normal, " + 186 " inout vec3 ambient, inout vec3 diffuse, inout vec3 specular," + 187 " float shininess)" + 188 "{" + 189 190 // we have to flip the direction because the script tells the shader 191 // where the light is coming FROM. We have to specify what direction the light 192 // is infinately towards. 193 " vec3 VP = normalize(vec3(-light.position));" + 194 195 " float powerfactor;" + 196 197 " float nDotVP = max(0.0, dot(normal, VP));" + 198 " float nDotHV = nDotVP;" + 199 200 " if(nDotVP == 0.0){" + 201 " powerfactor = 0.0;" + 202 " }" + 203 " else{"+ 204 " powerfactor = pow(nDotHV, shininess);" + 205 " }" + 206 207 " ambient += light.ambient;" + 208 " diffuse += light.diffuse * nDotVP;" + 209 " specular += light.specular * powerfactor;" + 210 "} "; 211