@@ -60,8 +60,10 @@ var LightLayer = new Class({
6060 vec3 position;
6161 vec3 color;
6262 float attenuation;
63+ float radius;
6364 };
6465
66+ uniform vec4 uCamera; /* x, y, rotation, zoom */
6567 uniform vec2 uResolution;
6668 uniform sampler2D uMainTexture;
6769 uniform sampler2D uNormTexture;
@@ -78,16 +80,17 @@ var LightLayer = new Class({
7880 vec4 spriteColor = texture2D(uMainTexture, v_tex_coord) * vec4(v_color, v_alpha);
7981 vec3 spriteNormal = texture2D(uNormTexture, v_tex_coord).rgb;
8082 vec3 normal = normalize(vec3(spriteNormal * 2.0 - 1.0));
83+ vec2 res = vec2(min(uResolution.x, uResolution.y)) * uCamera.w;
8184
8285 for (int index = 0; index < ` + Const . MAX_LIGHTS + `; ++index)
8386 {
8487 Light light = uLights[index];
85- float lightY = uResolution.y - light.position.y;
86- vec3 lightDir = vec3((vec2(light.position.x, lightY) / uResolution) - (gl_FragCoord.xy / uResolution), light.position.z);
88+ vec3 lightDir = vec3((light.position.xy / res) - (gl_FragCoord.xy / res), light.position.z);
8789 vec3 lightNormal = normalize(lightDir);
88- float distToSurf = length(lightDir);
90+ float distToSurf = length(lightDir) * uCamera.w ;
8991 float diffuseFactor = max(dot(normal, lightNormal), 0.0);
90- float attenuation = 1.0 / (1.0 + light.attenuation * (distToSurf * distToSurf));
92+ float radius = (light.radius / res.x * uCamera.w) * uCamera.w;
93+ float attenuation = clamp(1.0 - distToSurf * distToSurf / (radius * radius), 0.0, 1.0);
9194 vec3 diffuse = light.color * spriteColor.rgb * diffuseFactor;
9295 finalColor += attenuation * diffuse;
9396 }
@@ -99,6 +102,7 @@ var LightLayer = new Class({
99102 this . uMainTextureLoc = this . passShader . getUniformLocation ( 'uMainTexture' ) ;
100103 this . uNormTextureLoc = this . passShader . getUniformLocation ( 'uNormTexture' ) ;
101104 this . uResolutionLoc = this . passShader . getUniformLocation ( 'uResolution' ) ;
105+ this . uCameraLoc = this . passShader . getUniformLocation ( 'uCamera' ) ;
102106
103107 this . passShader . setConstantInt1 ( this . uMainTextureLoc , 0 ) ;
104108 this . passShader . setConstantInt1 ( this . uNormTextureLoc , 1 ) ;
@@ -108,7 +112,8 @@ var LightLayer = new Class({
108112 this . lightsLocations [ index ] = {
109113 position : this . passShader . getUniformLocation ( 'uLights[' + index + '].position' ) ,
110114 color : this . passShader . getUniformLocation ( 'uLights[' + index + '].color' ) ,
111- attenuation : this . passShader . getUniformLocation ( 'uLights[' + index + '].attenuation' )
115+ attenuation : this . passShader . getUniformLocation ( 'uLights[' + index + '].attenuation' ) ,
116+ radius : this . passShader . getUniformLocation ( 'uLights[' + index + '].radius' )
112117 } ;
113118 }
114119 }
@@ -121,7 +126,6 @@ var LightLayer = new Class({
121126
122127 precision mediump float;
123128
124- uniform vec2 uResolution;
125129 uniform sampler2D uMainTexture;
126130 uniform sampler2D uNormTexture;
127131
@@ -155,8 +159,10 @@ var LightLayer = new Class({
155159 vec3 position;
156160 vec3 color;
157161 float attenuation;
162+ float radius;
158163 };
159164
165+ uniform vec4 uCamera; /* x, y, rotation, zoom */
160166 uniform vec2 uResolution;
161167 uniform sampler2D uGbufferColor;
162168 uniform sampler2D uGbufferNormal;
@@ -170,16 +176,17 @@ var LightLayer = new Class({
170176 vec4 gbColor = texture2D(uGbufferColor, uv);
171177 vec3 gbNormal = texture2D(uGbufferNormal, uv).rgb;
172178 vec3 normal = normalize(vec3(gbNormal * 2.0 - 1.0));
179+ vec2 res = vec2(min(uResolution.x, uResolution.y)) * uCamera.w;
173180
174181 for (int index = 0; index < ` + Const . MAX_LIGHTS + `; ++index)
175- {
182+ {
176183 Light light = uLights[index];
177- float lightY = uResolution.y - light.position.y;
178- vec3 lightDir = vec3((vec2(light.position.x, lightY) / uResolution) - uv, light.position.z);
184+ vec3 lightDir = vec3((light.position.xy / res) - (gl_FragCoord.xy / res), light.position.z);
179185 vec3 lightNormal = normalize(lightDir);
180- float distToSurf = length(lightDir);
186+ float distToSurf = length(lightDir) * uCamera.w ;
181187 float diffuseFactor = max(dot(normal, lightNormal), 0.0);
182- float attenuation = 1.0 / (1.0 + light.attenuation * (distToSurf * distToSurf));
188+ float radius = (light.radius / res.x * uCamera.w) * uCamera.w;
189+ float attenuation = clamp(1.0 - distToSurf * distToSurf / (radius * radius), 0.0, 1.0);
183190 vec3 diffuse = light.color * gbColor.rgb * diffuseFactor;
184191 finalColor += attenuation * diffuse;
185192 }
@@ -201,6 +208,7 @@ var LightLayer = new Class({
201208 this . uResolutionLoc = this . lightPassShader . getUniformLocation ( 'uResolution' ) ;
202209 this . uGbufferColorLoc = this . lightPassShader . getUniformLocation ( 'uGbufferColor' ) ;
203210 this . uGbufferNormalLoc = this . lightPassShader . getUniformLocation ( 'uGbufferNormal' ) ;
211+ this . uCameraLoc = this . lightPassShader . getUniformLocation ( 'uCamera' ) ;
204212
205213 this . lightPassShader . setConstantInt1 ( this . uGbufferColorLoc , 0 ) ;
206214 this . lightPassShader . setConstantInt1 ( this . uGbufferNormalLoc , 1 ) ;
@@ -215,7 +223,8 @@ var LightLayer = new Class({
215223 this . lightsLocations [ index ] = {
216224 position : this . lightPassShader . getUniformLocation ( 'uLights[' + index + '].position' ) ,
217225 color : this . lightPassShader . getUniformLocation ( 'uLights[' + index + '].color' ) ,
218- attenuation : this . lightPassShader . getUniformLocation ( 'uLights[' + index + '].attenuation' )
226+ attenuation : this . lightPassShader . getUniformLocation ( 'uLights[' + index + '].attenuation' ) ,
227+ radius : this . lightPassShader . getUniformLocation ( 'uLights[' + index + '].radius' )
219228 } ;
220229 }
221230
@@ -263,6 +272,20 @@ var LightLayer = new Class({
263272 this . setOrigin ( 0 , 0 ) ;
264273 } ,
265274
275+ forEachLight : function ( callback )
276+ {
277+ if ( ! callback )
278+ return ;
279+
280+ var lights = this . lights ;
281+ var length = lights . length ;
282+
283+ for ( var index = 0 ; index < length ; ++ index )
284+ {
285+ callback ( lights [ index ] ) ;
286+ }
287+ } ,
288+
266289 get z ( )
267290 {
268291 return this . _z ;
@@ -328,19 +351,19 @@ var LightLayer = new Class({
328351 return sprite ;
329352 } ,
330353
331- addLight : function ( x , y , z , r , g , b , attenuation )
354+ addLight : function ( x , y , z , radius , r , g , b , attenuation )
332355 {
333356 if ( this . lights . length < Const . MAX_LIGHTS )
334357 {
335358 var light = null ;
336359 if ( this . lightPool . length > 0 )
337360 {
338361 light = this . lightPool . pop ( ) ;
339- light . set ( x , y , z , r , g , b , attenuation ) ;
362+ light . set ( x , y , z , radius , r , g , b , attenuation ) ;
340363 }
341364 else
342365 {
343- light = new Light ( x , y , z , r , g , b , attenuation ) ;
366+ light = new Light ( x , y , z , radius , r , g , b , attenuation ) ;
344367 }
345368 this . lights . push ( light ) ;
346369 return light ;
@@ -368,19 +391,20 @@ var LightLayer = new Class({
368391 var length = lights . length ;
369392 var gl = this . gl ;
370393 var point = { x : 0 , y : 0 } ;
371-
394+ var height = renderer . height ;
395+ var cameraMatrix = camera . matrix ;
396+ shader . setConstantFloat4 ( this . uCameraLoc , camera . x , camera . y , camera . rotation , camera . zoom ) ;
372397 shader . setConstantFloat2 ( this . uResolutionLoc , renderer . width , renderer . height ) ;
373398 shader . setConstantFloat3 ( this . ambientLightColorLoc , this . ambientLightColorR , this . ambientLightColorG , this . ambientLightColorB ) ;
374399
375- TempMatrix . applyITRS ( camera . x , camera . y , camera . rotation , camera . zoom , camera . zoom ) ;
376-
377400 for ( var index = 0 ; index < length ; ++ index )
378401 {
379402 var light = lights [ index ] ;
380- TempMatrix . transformPoint ( light . x , light . y , point ) ;
381- shader . setConstantFloat3 ( locations [ index ] . position , point . x - ( camera . scrollX * light . scrollFactorX ) , point . y - ( camera . scrollY * light . scrollFactorY ) , light . z ) ;
403+ cameraMatrix . transformPoint ( light . x , light . y , point ) ;
404+ shader . setConstantFloat3 ( locations [ index ] . position , point . x - ( camera . scrollX * light . scrollFactorX * camera . zoom ) , height - ( point . y - ( camera . scrollY * light . scrollFactorY ) * camera . zoom ) , light . z ) ;
382405 shader . setConstantFloat3 ( locations [ index ] . color , light . r , light . g , light . b ) ;
383406 shader . setConstantFloat1 ( locations [ index ] . attenuation , light . attenuation ) ;
407+ shader . setConstantFloat1 ( locations [ index ] . radius , light . radius ) ;
384408 }
385409 }
386410 }
0 commit comments