How to optimize light engine?

Way I have thought of and attempted:
Having prerendered light so i only calculate it every 2 frames instead of 1
I have thought about using a shader to do all of the calculation but not sure how to

Here is my code

		try {
			if (ENABLED) {
				// This calculation works out where to render the tiles by culling all of the others
				int camX = (int) (camera.position.x + (MasterTile.TILE_WIDTH / 2) - camera.viewportWidth / 2) / MasterTile.TILE_WIDTH;
				int camY = (int) (camera.position.y + (MasterTile.TILE_HEIGHT / 2) - camera.viewportHeight / 2) / MasterTile.TILE_HEIGHT;
				int camZoomFixX = (int) (((camera.zoom - 1) * 100) / (MasterTile.TILE_WIDTH / 10));
				int camZoomFixY = (int) (((camera.zoom - 1) * 100) / (MasterTile.TILE_WIDTH / 10));
				int offset = 1;

				if (camZoomFixX < 0)
					camZoomFixX = 0;
				if (camZoomFixY < 0)
					camZoomFixY = 0;

				int startX = camX - (camZoomFixX + offset);
				int toX = (camX + TileRenderer.AMOUNT_WIDTH) + (camZoomFixX + offset);
				int startY = camY - (camZoomFixY + offset);
				int toY = (camY + TileRenderer.AMOUNT_HEIGHT) + (camZoomFixY + offset);

				// This is the beginning of the light calculation
				// It works by going through each tile and each tile will loop over every light and
				// use an equation which will add to the tile brightness and will work out the final result
				{

					for (int x = startX; x < toX; x++) {
						for (int y = startY; y < toY; y++) {
							if (x < 0 || x > TileRenderer.map.getWidth() - 1 || y < 0 || y > TileRenderer.map.getHeight() - 1)
								continue;

							float tileBrightness = 0;

							for (int i = 0; i < lights.size; i++) {

								MasterTile tile = lights.get(i);
								if (tile == null)
									continue;
								float distance = Vector2.dst(tile.getX() / MasterTile.TILE_WIDTH, tile.getY() / MasterTile.TILE_HEIGHT, x, y);
								tileBrightness += Math.max(0, 1 - distance / MAX_DISTANCE); // Linear equation

							}
							float defaultAlpha = ambientColour.a;
							tempColor.set(0, 0, 0, ambient);
							tempColor.lerp(ambientColour, tileBrightness);

							ambientColour.a = 1.0f - tileBrightness;

							spriteBatch.setColor(tempColor);
							spriteBatch.draw(pixelTexture, x * MasterTile.TILE_WIDTH, y * MasterTile.TILE_HEIGHT, MasterTile.TILE_WIDTH, MasterTile.TILE_HEIGHT);

							ambientColour.a = defaultAlpha;

						}
					}
				}
			}
		} catch (NullPointerException e) {
			System.err.println("Light was not loaded!");
			System.err.println(e.getMessage());
		}
		// Resets colour to white
		spriteBatch.setColor(Color.WHITE);

You haven’t even stated what’s required to optimize the engine. Is it too slow as you add more lights, does rendering the lights lag, etc…

It’d be helpful if you had some testing data.

Okay well in the screen currently there is about 20 x 15 tiles these are the tiles currently in the scene and being drawn
now the lighting will be a few more tiles extra

When i change all the tiles in the scene to lights it lowers the fps… mainly on android though

The reason why I want to make this faster because i am having some stopping lag when I am moving the player around

Test Data?

When I meant testing data I meant some benchmarks of how long it takes to render a frame or lighting update. I was too vague; sorry.

You said it’s mainly on Android it has some framerate issues. I can see that every time you render a tile for lighting, you’re doing a distance check (which involves a slow square root), not to mention you’re iterating through every lighting per tile and doing said distance check.

I would suggest you have some sort of lighting update where it would calculate all the tiles’ brightnesses so that you don’t have to do it on-the-fly per frame.

What do you mean by [quote]I would suggest you have some sort of lighting update where it would calculate all the tiles’ brightnesses so that you don’t have to do it on-the-fly per frame.
[/quote]
Do you mean make a pre calculated light at the start of the game…? if so i have tried that but as it is a dynamic world it doesnt work well?
or do you mean for every torch I place calculate the whole map lighting?

Could you elaborate please?

For every torch you place you can re-calculate the nearby light sources. Doing the entire map is pretty unnecessary.

Calculating the lighting at the start for a dynamic world is pretty useless ::slight_smile:

What I did was made a method called scheduleLightingUpdate which would set an internal flag to true. Every render, I would check if the flag is true. If it is I would re-calculate the nearby lighting. If not I only rendered the lights without calculating.

You could calculate your lightning in the beginning, then only re-render when there was change.
I’d let the light sources handle those updates.

You can use this method to make your life easier when your game has something like a moving light source (e.g. holding a torch and moving):

  • Simply take the existing light values and shift them by the factor your source moves.

Don’t know if this is any help for you since you’d have to start from scratch but maybe it gives you some ideas.