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);