Recently I noticed that my 2D lightmap rendering has an issue - lighted area is getting rendered as far from the actual light source as the world coordinate of the light source grows. E.g. when world coordinate of the light source is (100,100) and the world size is about 2000x2000, lightmap looks fine. However, with coordinates like (500,500) lighted area is not rendered correctly on the screen.

I think that the main problem is in the coordinates I am using to generate lightmap. I calculate tiles' and light sources' vectors like this:

val x = it.x / worldWidth * 2 - 1
val y = it.y / worldHeight * 2 - 1
Vector2f(x, y)

I saw the examples with usage of the screen coordinates in above formula, however I don't get why should I use them, since my world is bigger than the screen and I need to know distances between tiles and light sources in the world.

Then, when rendering the texture to FBO, I create a texture of the world size to cover the whole world with the lightmap. This is when I also get confused. Which dimensions should I use, screen or world?

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, worldWidth, worldHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)
... // create fbo and bind texture to it
glViewport(0, 0, worldWidth, worldHeight) // viewport for FBO
glViewport(0, 0, screenWidth.toInt() * 2, screenHeight.toInt() * 2) 
glBindFramebuffer(GL_FRAMEBUFFER, 0)
// 2 multiplier is needed to correctly represent full screen on Mac with Retina display

After creating the lightmap texture, I start rendering it and I scale the texture dimensions like this (when using world dimensions, resulting textured object gets too big):

width = screenWidth * (screenWidth / originalLightMapWidthWhichIsVerySmall)
height = screenHeight * (screenHeight / originalLightMapHeightWhichIsVerySmall)

This is what I get:

  1. when coordinates are close to the start of the world
  1. when vertical coordinate is far from world start
  1. when horizontal coordinate is far from world start

EDIT: I made sure that tiles' positions calculation is right, as well as light sources' positions.

  • \$\begingroup\$ Do I understand correctly? you want a circular lightmap to be displayed on the whole screen whatever the camera position? If so you just need to send as in a second pass a square mesh having the screen xy coordinates and with uv 0..1, used alpha blending and your lightmap texture. I think this can be done in a single pass as well if you calculate uv coordinate based on the camera position - mesh position converted to screen coordinates. Something like that. Should work for any resolution. \$\endgroup\$
    – philB
    Commented May 28 at 9:19

1 Answer 1


Turned out the problem occurred when the lightmap got scaled up. For some reason, the height of the lightmap was bigger than the world height. On the other hand, the width was less than the world width.

I did not apply any tweaks to light intensity calculating formula, as well as to vectors and texture generating.

I simply resized the map to fit in the dimensions of the game world.

xSize = approximateWidth * 1.1f,
ySize = approximateHeight / 1.35f,

It may not be the perfect solution, moreover it is hacky and possibly not suitable for different screen sizes. However as a temporarily fix it does the trick.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .