Sending Canvases to a Shader - Flipping Y

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
Revolg
Prole
Posts: 5
Joined: Sat Nov 09, 2013 9:17 am

Sending Canvases to a Shader - Flipping Y

Post by Revolg »

Hi there,

I'm having problems with my blue color and y coordinate getting inverted when I send a canvas to a shader. You can see the effect here:
x0nvLgc.jpg
x0nvLgc.jpg (94.19 KiB) Viewed 231 times
On the left is what the image looks like, on the right is whats happening when its drawn to a canvas and the canvas is sent to a shader. Here is the code:

Code: Select all


local gr, mg, ky, tm, ev	= love.graphics, love.image, love.keyboard, love.timer, love.event


love.graphics.setMode(800,600)

function love.load()
 canvas = love.graphics.newCanvas(300, 225)
	gr.setCaption( "Pixel Effect Lighting" )
	image = gr.newImage( 'MyTest1.jpg' )
	dif = gr.newImage( 'diffuse.png' )
	nor = gr.newImage( 'normal.png' )
	load_effect()
	loc, dia = { 0.5, 0.5 }, 1.0
	effect:send( 'dia', dia )
	effect:send( 'pos', loc )
	effect:send( 'u_texture', dif )
	effect:send( 'u_normals', nor )

	end

function love.draw()

love.graphics.setCanvas(canvas)
        canvas:clear()

		gr.draw( dif )
				
    love.graphics.setCanvas()
	
	effect:send( 'u_texture', canvas	)

	gr.setColor( 255, 255, 255, 255 )
	gr.setPixelEffect( effect )
		gr.draw( canvas )
		gr.setPixelEffect( )
	gr.setColor( 255, 255, 0, 255 )
	gr.print( 'fps: '..tm.getFPS( ), 10,  520 )
	gr.print( 'spot diameter: '..dia, 10, 540 )
	gr.print( 'move spotlight with arrow keys', 10, 560 )
	gr.print( 'change spot diameter with <s> & <d> keys', 10, 580 )
	

	end

function love.update(dt)

	if ky.isDown( 'up' )	then loc[2] = loc[2]<1	and loc[2]+dt	or 1.0	effect:send( 'pos', loc ) end
	if ky.isDown( 'down' )	then loc[2] = loc[2]>0	and loc[2]-dt	or 0.0	effect:send( 'pos', loc ) end
	if ky.isDown('right')	then loc[1] = loc[1]<1	and loc[1]+dt	or 1.0	effect:send( 'pos', loc ) end
	if ky.isDown('left')	then loc[1] = loc[1]>0	and loc[1]-dt	or 0.0	effect:send( 'pos', loc ) end
	if ky.isDown('d') 		then dia = dia < 3.0	and dia + dt	or 3,0	effect:send( 'dia', dia ) end
	if ky.isDown('s') 		then dia = dia > 0.1	and dia - dt	or 0.1	effect:send( 'dia', dia ) end
	end

function love.keypressed( key )
	if key == 'escape'	then ev.push( 'quit' )	end
	end

function load_effect()
	effect = love.graphics.newPixelEffect
		[[
		
		//our texture samplers
		extern Image u_texture;   //diffuse map
		extern Image u_normals;   //normal map	
		
		extern float dia;
		extern vec2 pos;
		vec4 effect(vec4 color, Image texture, vec2 tc, vec2 pixel_coords)
		{
			
			vec2 Resolution = vec2(800.0,600.0);
			vec3 LightPos = vec3(pos,.1);
			vec4 LightColor = vec4(1.0, 0.8, 0.6, 1);
			vec4 AmbientColor = vec4(0.6, 0.6, 1.0, 0.2);
			vec3 Falloff = vec3(0.4, 3.0, 20.0);
			
			//RGBA of our diffuse color
			vec4 DiffuseColor = Texel( u_texture, tc );
	
			//RGB of our normal map
			vec3 NormalMap = Texel(u_normals, tc).rgb;
			
			
			//The delta position of light
			vec3 LightDir = vec3(LightPos.xy - (pixel_coords.xy / Resolution.xy), LightPos.z);
			
			//Correct for aspect ratio
			LightDir.x *= Resolution.x / Resolution.y;
	
			//Determine distance (used for attenuation) BEFORE we normalize our LightDir
			float D = length(LightDir);
	
			//normalize our vectors
			vec3 N = normalize(NormalMap * 2.0 - 1.0);
			vec3 L = normalize(LightDir);
			
			//Pre-multiply light color with intensity
			//Then perform "N dot L" to determine our diffuse term
			//vec3 Diffuse = (LightColor.rgb * LightColor.a) * max(dot(N, L), 0.0);
			vec3 Diffuse = (LightColor.rgb * LightColor.a);
			
			//pre-multiply ambient color with intensity
			vec3 Ambient = AmbientColor.rgb * AmbientColor.a;
			
			//calculate attenuation
			float Attenuation = 1.0 / ( Falloff.x + (Falloff.y*D) + (Falloff.z*D*D) );
			
			//the calculation which brings it all together
			vec3 Intensity = Ambient + Diffuse * Attenuation;
			vec3 FinalColor = DiffuseColor.rgb * Intensity;
			return vec4(FinalColor, DiffuseColor.a);
			
			
			
			//the following can be ignored:
			//the following can be ignored:
			//the following can be ignored:
			vec4 pixel	= Texel( texture, tc );
			float d2 	= clamp(dia,0,10);
			float root	= sqrt((pos[0]-tc.x)*(pos[0]-tc.x)+(pos[1]-tc.y)*(pos[1]-tc.y))/d2;
			pixel.r		= pixel.r - root;
			pixel.g		= pixel.g - root;
			pixel.b		= pixel.b - root;
			if (pixel.a > 0.0 ) { pixel.a = 1 - root; }
			//return  pixel;
			}
		]]
	end


I would love any help you could provide.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Sending Canvases to a Shader - Flipping Y

Post by bartbes »

Indeed this is a long-standing bug.
Revolg
Prole
Posts: 5
Joined: Sat Nov 09, 2013 9:17 am

Re: Sending Canvases to a Shader - Flipping Y

Post by Revolg »

Is there anything I can do to get the blue back when I send the canvas to shader? I can flip the Y easy but the color loss is not so simple.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Sending Canvases to a Shader - Flipping Y

Post by bartbes »

Oh, I meant the flipping is known. The color thing might be because you're not using the right blendmode.. maybe?
Revolg
Prole
Posts: 5
Joined: Sat Nov 09, 2013 9:17 am

Re: Sending Canvases to a Shader - Flipping Y

Post by Revolg »

I'm not using any blend modes. Out of curiosity though, I tried drawing the canvas with all the different blend modes and it didn't make a difference.

I don't understand what could be the problem as my shader works perfectly with an image, but when you supply it a canvas it breaks the blue channel.
User avatar
spynaz
Party member
Posts: 152
Joined: Thu Feb 28, 2013 5:49 am

Re: Sending Canvases to a Shader - Flipping Y

Post by spynaz »

I still don't get how to script shaders. D:
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 36 guests