Page 1 of 2

Optimizing parallax star background

Posted: Sun Jan 02, 2011 1:09 pm
by slime
I have a parallax star background in my game, but drawing it takes a significant chunk of resources (I get 55% more FPS when I don't draw it).

Is there a more efficient way to do this, or some way to better optimize my code? I made it have random depths (and sizes) because I think it looks a lot nicer than a small number of static depths, but I'll sacrifice it if absolutely necessary. :(

(http://pastebin.com/kRrkUan0)

Code: Select all

local starimage = love.graphics.newImage("images/star.png")

Background = class()

function Background:init(numstars) -- 120 stars normally
	self.numstars = numstars
	self.parallax = {}
	self.colors = {
		[1] = {255, 192, 192}, -- red
		[2] = {255, 255, 255}, -- normal
		[3] = {255, 255, 192}, -- yellow
		[4] = {192, 192, 255}, -- blue
	}
	
	-- create stars
	for i = 1, numstars do
		local x, y = math.random(0, xres*1.2), math.random(0, yres*1.2)
		local depth = math.random(50, 90)/100
		local color = math.random(#self.colors)
		local size = math.random(3,6)/10
		table.insert(self.parallax, {x, y, depth=depth, color=color, size=size})
	end
	
end

function Background:draw()
	-- local variables = faster!
	local starimage = starimage
	local campos = camera.pos
	local xres, yres = xres, yres
	local xarea, yarea = xres*1.2, yres*1.2 -- want slightly larger area than screen so it's harder to notice repeated stars
	
	for i, star in ipairs(self.parallax) do
		-- calculate new positions
		local x = (star[1]-campos.x*star.depth) % xarea
		local y = (star[2]-campos.y*star.depth) % yarea
		if x >= 0 and x <= xres and y >= 0 and y <= yres then
			-- only draw if actually onscreen
			local color = self.colors[star.color]
			love.graphics.setColor(color[1], color[2], color[3], 128)
			love.graphics.draw(starimage, x, y, 0, star.size, star.size, 4, 4)
		end
	end
end

Re: Optimizing parallax star background

Posted: Sun Jan 02, 2011 2:53 pm
by kikito
One possible option is creating a framebuffer, and drawing the stars there, instead of storing them on an array.

Then you just have to draw one thing, instead of making individual draw calls per star. You would essentially be changing speed for memory.

A slower option would be using a spritebatch. That will be less fast, but consume less memory.

Re: Optimizing parallax star background

Posted: Sun Jan 02, 2011 3:32 pm
by slime
I looked into those, but I'm not sure how to implement them so that they'll work with my stars which move at varying speeds and "wrap around" the screen.

Re: Optimizing parallax star background

Posted: Sun Jan 02, 2011 3:38 pm
by kikito
Oh. You have different depth per star? Then there isn't much you can do.

One possible way out is arranging your stars on several planes - any number bigger than 5 will make it difficult to see the pattern. Then use one framebuffer / spritebatch per plane. It'll still be much faster than drawing the stars individually.

Re: Optimizing parallax star background

Posted: Sun Jan 02, 2011 4:00 pm
by slime
How would I go about making the stars loop back to create an 'infinite starfield' using those methods?

Re: Optimizing parallax star background

Posted: Sun Jan 02, 2011 4:46 pm
by kikito
Well, I guess you could make the framebuffers 4 times as big as the screen, and print the stars 4 times on them, instead of just one. But that would start complicating things, I think.

Re: Optimizing parallax star background

Posted: Sun Jan 02, 2011 5:05 pm
by slime
I don't think I want framebuffers that big. ;)

Gah, spritebatches don't let you set the color of stuff you add to them. Lame. :/

Re: Optimizing parallax star background

Posted: Mon Jan 03, 2011 4:37 pm
by ghostwriter
So you want to have stars that appear in random positions, that have random sizes, different colours, and random velocities? Why not just use a single Particle System?

Re: Optimizing parallax star background

Posted: Mon Jan 03, 2011 4:49 pm
by kikito
kikito wrote:Well, I guess you could make the framebuffers 4 times as big as the screen, and print the stars 4 times on them, instead of just one. But that would start complicating things, I think.
I've just realized that you don't need to make the framebuffers 4 times bigger. Just make them screen-sized and draw them 1,2 or 4 times when needed.

Re: Optimizing parallax star background

Posted: Mon Jan 03, 2011 5:00 pm
by ghostwriter
kikito wrote:Just make them screen-sized and draw them 1,2 or 4 times when needed.
I think the pattern repetition would be quite noticeable... though if each tile layer is moving at a different speed that might work.