Optimizing parallax star background

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
slime
Solid Snayke
Posts: 3132
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Optimizing parallax star background

Post 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
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Optimizing parallax star background

Post 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.
When I write def I mean function.
User avatar
slime
Solid Snayke
Posts: 3132
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Optimizing parallax star background

Post 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.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Optimizing parallax star background

Post 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.
When I write def I mean function.
User avatar
slime
Solid Snayke
Posts: 3132
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Optimizing parallax star background

Post by slime »

How would I go about making the stars loop back to create an 'infinite starfield' using those methods?
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Optimizing parallax star background

Post 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.
When I write def I mean function.
User avatar
slime
Solid Snayke
Posts: 3132
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Optimizing parallax star background

Post 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. :/
User avatar
ghostwriter
Prole
Posts: 38
Joined: Sat Dec 11, 2010 11:08 pm

Re: Optimizing parallax star background

Post 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?
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Optimizing parallax star background

Post 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.
When I write def I mean function.
User avatar
ghostwriter
Prole
Posts: 38
Joined: Sat Dec 11, 2010 11:08 pm

Re: Optimizing parallax star background

Post 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.
Post Reply

Who is online

Users browsing this forum: No registered users and 164 guests