Skip to content

Commit 5f5ccd0

Browse files
committed
Lights work with camera zoom and also added support for light radius
1 parent 40952d6 commit 5f5ccd0

3 files changed

Lines changed: 69 additions & 31 deletions

File tree

v3/src/gameobjects/lightlayer/Light.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ var Light = new Class({
44

55
initialize:
66

7-
function Light (x, y, z, r, g, b, attenuation)
7+
function Light (x, y, z, radius, r, g, b, attenuation)
88
{
99
this.x = x;
1010
this.y = y;
1111
this.z = z;
12+
this.radius = radius;
1213
this.r = r;
1314
this.g = g;
1415
this.b = b;
@@ -17,11 +18,12 @@ var Light = new Class({
1718
this.scrollFactorY = 1.0;
1819
},
1920

20-
set: function (x, y, z, r, g, b, attenuation)
21+
set: function (x, y, z, radius, r, g, b, attenuation)
2122
{
2223
this.x = x;
2324
this.y = y;
2425
this.z = z;
26+
this.radius = radius;
2527
this.r = r;
2628
this.g = g;
2729
this.b = b;

v3/src/gameobjects/lightlayer/LightLayer.js

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

v3/src/renderer/webgl/ResourceManager.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ var ResourceManager = new Class({
149149
{
150150
throw new Error('Vertex Shader Compilation Error. Shader name: ' + shaderName + '.\n' + error + '\n\n Shader source:\n' + shaderSources.vert);
151151
}
152-
else if (error && error.length > 0)
152+
else if (error && error.length > 10)
153153
{
154154
console.warn('Vertex Shader Compilation Warning. Shader name: ' + shaderName + '.\n' + error + '\n\n Shader source:\n' + shaderSources.vert);
155155
}
@@ -165,7 +165,7 @@ var ResourceManager = new Class({
165165
{
166166
throw new Error('Fragment Shader Compilation Error. Shader name: ' + shaderName + '.\n' + error + '\n\n Shader source:\n' + shaderSources.frag);
167167
}
168-
else if (error && error.length > 0)
168+
else if (error && error.length > 10)
169169
{
170170
console.warn('Fragment Shader Compilation Warning. Shader name: ' + shaderName + '.\n' + error + '\n\n Shader source:\n' + shaderSources.frag);
171171
}
@@ -176,22 +176,34 @@ var ResourceManager = new Class({
176176
gl.linkProgram(program);
177177
gl.validateProgram(program);
178178

179-
error = gl.getProgramParameter(program, gl.LINK_STATUS);
179+
error = gl.getProgramInfoLog(program);
180+
status = gl.getProgramParameter(program, gl.LINK_STATUS);
180181

181-
if (error === 0)
182+
if (!status && error && error.length > 0)
182183
{
183-
error = gl.getProgramInfoLog(program);
184-
185184
throw new Error('Program Linking Error. Shader name: ' + shaderName + '.\n' + error);
186185
}
186+
else if (error && error.length > 0)
187+
{
188+
console.warn('Program Linking Warning. Shader name: ' + shaderName + '.\n' + error);
189+
}
190+
191+
if (!error)
192+
{
193+
194+
}
187195

188-
error = gl.getProgramParameter(program, gl.VALIDATE_STATUS);
196+
error = gl.getProgramInfoLog(program);
197+
status = gl.getProgramParameter(program, gl.VALIDATE_STATUS);
189198

190-
if (error === 0)
199+
if (!status && error && error.length > 0)
191200
{
192-
error = gl.getProgramInfoLog(program);
193201
throw new Error('Program Validation Error. Shader name: ' + shaderName + '.\n' + error);
194202
}
203+
else if (error && error.length > 0)
204+
{
205+
console.warn('Program Validation Warning. Shader name: ' + shaderName + '.\n' + error);
206+
}
195207

196208
shader = new Resources.Shader(shaderName, gl, program, vertShader, fragShader);
197209

0 commit comments

Comments
 (0)