A question about glsl code

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.
Post Reply
User avatar
Qcode
Party member
Posts: 170
Joined: Tue Jan 10, 2012 1:35 am

A question about glsl code

Post by Qcode »

So I've been trying to learn how to write some glsl code, trying to make a lighting system for my new project. I've been running into a problem setting up multiple torches though.
My current code is like this:

Code: Select all

	haveshaders = love.graphics.isSupported("pixeleffect")
	if haveshaders then
		pixeleffect = love.graphics.newPixelEffect [[
			extern vec2 pos;
			extern number tilesize;
			//extern number width;
			vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen)
			{
				vec4 pixel = Texel(texture, texture_coords)*color;
				number distance = distance(pos, screen);

				pixel = (pixel/(distance*tilesize));
				return pixel;
			}
		]]
	end
This code worked fine when I was using the character as a light source while testing around. However now I need it to work with multiple torches lighting up the area.
What I've been having trouble with is figuring out how to send torch data to the shader. I'll need to send a different amount of torches each time depending on which are on screen. So I can't set up something like a vec4, because I don't always know I'll have 4 torches.
Any help on this would be greatly appreciated, I really just want to know how I can send a table of varying size to the shader.
I can supply a .love later if necessary, I'm just not sure if this is a simple question that can be fixed without it.
User avatar
OmarShehata
Party member
Posts: 259
Joined: Tue May 29, 2012 6:46 pm
Location: Egypt
Contact:

Re: A question about glsl code

Post by OmarShehata »

I ran into the same problem. First I tried to make this array, and set it to have a size of 20 elements (and have dummy 0 values for ones that aren't used, or I think it works even if you don't send all 20 values) and it worked, but that meant having a limit on the maximum number of lights on screen (and setting it to something like 100 would make the shader not even run on some computers for some reason)

But then I realized something, and I think that's how most people do it: since the code you're writing right now is running on the GPU, and the GPU is made to be optimized for graphics, then why aren't you communicating with it graphically, instead of numerically?

You want to put your light/torch data inside of a texture/Image, and send that Image to the shader. So that regardless of how many lights you have, you would send a fixed amount of Images (or 'buffers') containing the light data.

What I did for my project was draw the lights as circles. The circle radius was the distance factor of the light, and the color of the circle was the color of the light (and the alpha was the intensity). So I just drew the lights on this Canvas, and sent it to the shader.
User avatar
Qcode
Party member
Posts: 170
Joined: Tue Jan 10, 2012 1:35 am

Re: A question about glsl code

Post by Qcode »

Thanks a ton for your help, but I'm not entirely sure I understand what I should have the shader do once it receives the canvas. The canvas looks like this:

Code: Select all

function addlighttocannvas()
	local lightcanvas = love.graphics.newCanvas(mapwidth, screenheight)
	local addlight = function()
		for i = 1, #torches do
			love.graphics.circle("fill", torches[i].x, torches[i].y, 64*scale)
		end
	end

	lightcanvas:renderTo(addlight)



	return lightcanvas
end
The function is called once per load of each level, then I have the shader receiving the lightcanvas via "extern sampler2D torches;" each frame.
Am I doing this correctly? Should I be finding points in the canvas, form a vec2 with x and y, then use a distance function? That just seems to me like it's not using the "communicate with it graphically" aspect that you were explaining to me.
Again, thanks so much for your help. Please excuse me if the solution is obvious; I'm completely new to writing shaders and GLSL code, I have looked through some other examples, but I've yet to find an example I could base my code on.
User avatar
OmarShehata
Party member
Posts: 259
Joined: Tue May 29, 2012 6:46 pm
Location: Egypt
Contact:

Re: A question about glsl code

Post by OmarShehata »

Sorry for the super late reply! Haven't checked the forum here in a while. I'm not sure if you've solved it or not yet.
Qcode wrote: Again, thanks so much for your help. Please excuse me if the solution is obvious; I'm completely new to writing shaders and GLSL code, I have looked through some other examples, but I've yet to find an example I could base my code on.
Don't worry, shaders can be pretty confusing. I had to go look up what I did for the sake of this post :P

So basically, in your example here, you have a canvas with all the torches as circles. Imagine this being superimposed on your screen. One thing I forgot to mention, is that the torches/circles should be radial gradients on your canvas. (I do this with another shader that blends together colors, and fades the color away from the center of each circle). So now, at any point on your screen, you have the final color and intensity (alpha) of the light reaching it. This should be all you need to calculate your lights.

This way, you don't need to calculate any distances later on, you only do it once when creating all your lights and setting them to the canvas. Does that make sense?
User avatar
T-Bone
Inner party member
Posts: 1492
Joined: Thu Jun 09, 2011 9:03 am

Re: A question about glsl code

Post by T-Bone »

Just wanted to say that creating a 128 array of vec2s, and also sending an integer telling the shader how many lights there are in the scene works just fine too. I have yet to see a computer that can run shaders but can't store 256 floats in them.
User avatar
slime
Solid Snayke
Posts: 3132
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: A question about glsl code

Post by slime »

T-Bone wrote:Just wanted to say that creating a 128 array of vec2s, and also sending an integer telling the shader how many lights there are in the scene works just fine too. I have yet to see a computer that can run shaders but can't store 256 floats in them.
Indeed: http://feedback.wildfiregames.com/repor ... ONENTS_ARB

The tl;dr of that page is that almost any system which can run LÖVE shaders will be able to handle an array of 1024 extern floats (or 512 extern vec2's, or 256 extern vec4's), if not more. The very very small minority which can't handle 1024 can handle 512.

That's not to say it's necessarily the best idea to have that many extern values (instead of using some other method), just that it's possible. ;)
Post Reply

Who is online

Users browsing this forum: No registered users and 88 guests