Share a Shader!

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
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Re: Share a Shader!

Post by retrotails »

Ref, You might be able to render a checkered sphere...
but can you do other things at the same time?

How can you say you hardly know how shaders work if you've done so much? Those are some awesome shaders.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Just another fun shader I adapted to Love.
Attachments
pacman.love
Original can be found on GLSL Sandbox
(1.54 KiB) Downloaded 288 times
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

I know, not much interest but thought I'd share a rather neat shader I adapted to Love.
Attachments
fire.love
Small size because shader has for loop
(1.37 KiB) Downloaded 334 times
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Share a Shader!

Post by Robin »

I don't see anything in the last one.
Help us help you: attach a .love.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Makes me worry about using shaders in a game since it appears that the performance of certant aspects of a shader appears to be computer dependent - probably some features are not supported (sure would be nice to know which ones).
Down loaded fire.love from site and confirmed that it runs on my Windows 7 computer.
Anyone else having problems?
How about these two?
Attachments
swirl.love
(1.66 KiB) Downloaded 260 times
balls.love
Shader interacting with mouse
(1.21 KiB) Downloaded 248 times
User avatar
bramblez
Citizen
Posts: 50
Joined: Sun Jul 29, 2012 1:21 pm
Location: Russia, Moscow

Re: Share a Shader!

Post by bramblez »

60 fps on both, no problems
scutheotaku
Party member
Posts: 235
Joined: Sat Dec 15, 2012 6:54 am

Re: Share a Shader!

Post by scutheotaku »

slime wrote:Bloom.

Code: Select all

local math, love = math, love

local function FindSmallestPO2(num)
	return 2 ^ math.ceil(math.log(num)/math.log(2))
end

local function ScaleToPO2(xsize, ysize)
	if love.graphics.isSupported("npot") then return xsize, ysize end
	return FindSmallestPO2(xsize), FindSmallestPO2(ysize)
end

-- i've found xsize and ysize of 1/2 - 1/4 the screen resolution to be nice
-- smaller values make the bloom more apparent and give much better performance, but can make it look bad if too small
function CreateBloomEffect(xsize, ysize) 
	if not love.graphics.newPixelEffect
	or not love.graphics.isSupported
	or not love.graphics.isSupported("pixeleffect")
	or not love.graphics.isSupported("canvas") then
		return
	end
	
	local function newPixelEffect(code)
		local success, result = pcall(love.graphics.newPixelEffect, code)
		if success then
			return result
		else
			print("Error compiling shader!\n"..result)
		end
	end
	
	local bloom = {}
	
	local shaders = {
		blur_vert = [[
			extern number canvas_h = 256.0;
			
			const number offset_1 = 1.3846153846;
			const number offset_2 = 3.2307692308;
			
			const number weight_0 = 0.2270270270;
			const number weight_1 = 0.3162162162;
			const number weight_2 = 0.0702702703;
			
			vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords)
			{
				vec4 texcolor = Texel(texture, texture_coords);
				vec3 tc = texcolor.rgb * weight_0;
				
				tc += Texel(texture, texture_coords + vec2(0.0, offset_1)/canvas_h).rgb * weight_1;
				tc += Texel(texture, texture_coords - vec2(0.0, offset_1)/canvas_h).rgb * weight_1;
				
				tc += Texel(texture, texture_coords + vec2(0.0, offset_2)/canvas_h).rgb * weight_2;
				tc += Texel(texture, texture_coords - vec2(0.0, offset_2)/canvas_h).rgb * weight_2;
				
				return color * vec4(tc, 1.0);
			}
		]],
		blur_horiz = [[
			extern number canvas_w = 256.0;

			const number offset_1 = 1.3846153846;
			const number offset_2 = 3.2307692308;
			
			const number weight_0 = 0.2270270270;
			const number weight_1 = 0.3162162162;
			const number weight_2 = 0.0702702703;

			vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords)
			{
				vec4 texcolor = Texel(texture, texture_coords);
				vec3 tc = texcolor.rgb * weight_0;
				
				tc += Texel(texture, texture_coords + vec2(offset_1, 0.0)/canvas_w).rgb * weight_1;
				tc += Texel(texture, texture_coords - vec2(offset_1, 0.0)/canvas_w).rgb * weight_1;
				
				tc += Texel(texture, texture_coords + vec2(offset_2, 0.0)/canvas_w).rgb * weight_2;
				tc += Texel(texture, texture_coords - vec2(offset_2, 0.0)/canvas_w).rgb * weight_2;
				
				return color * vec4(tc, 1.0);
			}
		]],
		bloom = [[
			extern number threshold = 1.0;
			
			float luminance(vec3 color)
			{
				// numbers make 'true grey' on most monitors, apparently
				return (0.212671 * color.r) + (0.715160 * color.g) + (0.072169 * color.b);
			}
			
			vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords)
			{
				vec4 texcolor = Texel(texture, texture_coords);
				
				vec3 extract = smoothstep(threshold * 0.7, threshold, luminance(texcolor.rgb)) * texcolor.rgb;
				return vec4(extract, 1.0);
			}
		]],
		
		combine = [[
			extern Image bloomtex;
			
			extern number basesaturation = 1.0;
			extern number bloomsaturation = 1.0;
			
			extern number baseintensity = 1.0;
			extern number bloomintensity = 1.0;
			
			vec3 AdjustSaturation(vec3 color, number saturation)
			{
    			vec3 grey = vec3(dot(color, vec3(0.212671, 0.715160, 0.072169)));
    			return mix(grey, color, saturation);
			}
		
			vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords)
			{
				vec4 basecolor = Texel(texture, texture_coords);
				vec4 bloomcolor = Texel(bloomtex, texture_coords);
				
				bloomcolor.rgb = AdjustSaturation(bloomcolor.rgb, bloomsaturation) * bloomintensity;
				basecolor.rgb = AdjustSaturation(basecolor.rgb, basesaturation) * baseintensity;
				
				basecolor.rgb *= (1.0 - clamp(bloomcolor.rgb, 0.0, 1.0));
				
				bloomcolor.a = 0.0;
				
				return clamp(basecolor + bloomcolor, 0.0, 1.0);
			}
		]]
	}
	
	for k,v in pairs(shaders) do
		local shader = newPixelEffect(v)
		if shader then
			shaders[k] = shader
		else
			return
		end
	end
	
	if not shaders.blur_vert or not shaders.blur_horiz or not shaders.bloom or not shaders.combine then
		return
	end

	
	local intensity_base, intensity_bloom = 1, 1
	local saturation_base, saturation_bloom = 1, 1
	local threshold_bloom = 0.5
	
	local debugdraw = false
	
	function bloom:refresh(xs, ys)
		xs, ys = math.floor(xs+0.5), math.floor(ys+0.5)
		
		local renderingtoscene = false

		self.xsize, self.ysize = xs, ys
		
		self.po2xsize, self.po2ysize = ScaleToPO2(self.xsize, self.ysize) -- scales x and y to next power of 2 if npot is false
		
		self.xres, self.yres = love.graphics.getWidth(), love.graphics.getHeight()
		self.po2xres, self.po2yres = ScaleToPO2(self.xres, self.yres)

	
		self.quad = love.graphics.newQuad(0, 0, self.xsize, self.ysize, self.po2xsize, self.po2ysize)
		self.scenequad = love.graphics.newQuad(0, 0, self.xres, self.yres, self.po2xres, self.po2yres)
	
		self.canvas = {
			bloom = love.graphics.newCanvas(self.po2xsize, self.po2ysize),
			blur_horiz = love.graphics.newCanvas(self.po2xsize, self.po2ysize),
			blur_vert = love.graphics.newCanvas(self.po2xsize, self.po2ysize),
			scene = love.graphics.newCanvas(self.po2xres, self.po2yres),
			bloomscene = love.graphics.newCanvas(self.po2xres, self.po2yres),
		}
				
		for k,v in pairs(self.canvas) do
			v:clear()
		end
		
		shaders.blur_horiz:send("canvas_w", self.po2xsize)
		shaders.blur_vert:send("canvas_h", self.po2ysize)
		self:setThreshold(self:getThreshold())
		self:setIntensity(self:getIntensity())
		self:setSaturation(self:getSaturation())
		
		if renderingtoscene then
			love.graphics.setCanvas(self.canvas.scene)
		end
		
		collectgarbage("collect")
	end
	
	function bloom:debugDraw(shoulddebugdraw)
		debugdraw = not not shoulddebugdraw
	end
	
	function bloom:setIntensity(ibase, ibloom)
		intensity_base = ibase
		intensity_bloom = ibloom
		
		shaders.combine:send("baseintensity", ibase)
		shaders.combine:send("bloomintensity", ibloom)
	end
	function bloom:getIntensity()
		return intensity_base, intensity_bloom
	end
	
	function bloom:setSaturation(sbase, sbloom)
		saturation_base = sbase
		saturation_bloom = sbloom
		
		shaders.combine:send("basesaturation", sbase)
		shaders.combine:send("bloomsaturation", sbloom)
	end
	function bloom:getSaturation()
		return saturation_base, saturation_bloom
	end
	
	function bloom:setThreshold(threshold)
		threshold_bloom = threshold
		
		shaders.bloom:send("threshold", threshold)
	end
	function bloom:getThreshold()
		return threshold_bloom
	end
	
	
	-- call right before drawing the stuff you want bloomed
	function bloom:predraw()
		for k,v in pairs(self.canvas) do
			v:clear()
		end
		love.graphics.setCanvas(self.canvas.scene)
		
		self.drawing = true
	end
	
	function bloom:enabledrawtobloom()
		love.graphics.setCanvas(self.canvas.bloomscene)
	end
	
	-- call after drawing the stuff you want bloomed
	function bloom:postdraw()			
		love.graphics.setColor(255, 255, 255)
		local blendmode = love.graphics.getBlendMode()
		love.graphics.setBlendMode("premultiplied")
		
		love.graphics.push()
		love.graphics.scale(self.po2xsize/self.po2xres, self.po2ysize/self.po2yres)
		
		-- apply bloom extract shader
		love.graphics.setCanvas(self.canvas.bloom)
		love.graphics.setPixelEffect(shaders.bloom)
		love.graphics.drawq(self.canvas.bloomscene, self.scenequad, 0, 0)
		
		love.graphics.pop()
					
		-- apply horizontal blur shader to extracted bloom
		love.graphics.setCanvas(self.canvas.blur_horiz)
		love.graphics.setPixelEffect(shaders.blur_horiz)
		love.graphics.drawq(self.canvas.bloom, self.quad, 0, 0)
		
		-- apply vertical blur shader to blurred bloom
		love.graphics.setCanvas(self.canvas.blur_vert)
		love.graphics.setPixelEffect(shaders.blur_vert)
		love.graphics.drawq(self.canvas.blur_horiz, self.quad, 0, 0)
		
		-- render final scene combined with bloom canvas
		love.graphics.setCanvas()
		shaders.combine:send("bloomtex", self.canvas.blur_vert)
		love.graphics.setPixelEffect(shaders.combine)
		love.graphics.drawq(self.canvas.scene, self.scenequad, 0, 0)
		
		love.graphics.setPixelEffect()
		
		if debugdraw then
			-- love.graphics.setColor(255, 255, 255, 128)
			love.graphics.draw(self.canvas.bloom, 0, 0)
			love.graphics.draw(self.canvas.blur_horiz, self.po2xsize+4, 0)
			love.graphics.draw(self.canvas.blur_vert, self.po2xsize*2+8, 0)
			-- love.graphics.draw(self.canvas.blur_vert, 0, 0, 0, self.po2xres/self.po2xsize, self.po2yres/self.po2ysize)
		end
		
		love.graphics.setBlendMode(blendmode)
		
		self.drawing = false
	end
	
	function bloom:isDrawing()
		return not not self.drawing
	end
	
	bloom:refresh(xsize, ysize)
	
	bloom:setIntensity(1, 1)
	bloom:setSaturation(1, 1)
	bloom:setThreshold(0.35)
	
	return bloom
end
Like some others here, I'm having trouble getting this script to work. I'm not getting any errors: it's just simply not working.
Here's what I'm doing:
I require bloom.lua (obviously)
I place this in love.load():

Code: Select all

bloom = CreateBloomEffect(400, 300) 
Then, in love.draw(), I place this right before the things I am drawing that I want affected:

Code: Select all

bloom:predraw()
...and this right after those things:

Code: Select all

bloom:postdraw() 
But, it does nothing. I haven't had any problems with any other shaders, so I don't think it's my computer.

Thanks!
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Not too helpful but all your shaders checkout OK at this end (pretty straight forward stuff.)
Problem is elsewhere in your code - just haven't found it - lots going on.
Good luck.
scutheotaku
Party member
Posts: 235
Joined: Sat Dec 15, 2012 6:54 am

Re: Share a Shader!

Post by scutheotaku »

Ref wrote:Not too helpful but all your shaders checkout OK at this end (pretty straight forward stuff.)
Problem is elsewhere in your code - just haven't found it - lots going on.
Good luck.
I'm not sure if you were talking to me, but, if you were, thanks :D

I've tried using the bloom shader in a very simple example, and it doesn't work there, so I don't think it's any of my other code that's causing an issue. I'm pretty sure that I'm just missing something really obvious :D It's just funny, because I haven't had any other issue using the other shaders, or even modifying them.

Here's my little example:
https://dl.dropboxusercontent.com/u/17269775/bloom.love

Or, if you don't want to download the LOVE file, here is my code:

Code: Select all

require "bloom"

function love.load()
	bloom = CreateBloomEffect(400, 300) 

	love.graphics.setBackgroundColor(0,0,80)

	rectangle = {x = 64, y = 64, w = 32, h = 32, speed = 150}
end

function love.update(dt)
	if love.keyboard.isDown("right") then
		rectangle.x = rectangle.x + rectangle.speed * dt
	elseif love.keyboard.isDown("up") then
		rectangle.y = rectangle.y - rectangle.speed * dt
	elseif love.keyboard.isDown("left") then
		rectangle.x = rectangle.x - rectangle.speed * dt
	elseif love.keyboard.isDown("down") then
		rectangle.y = rectangle.y + rectangle.speed * dt
	end

	if love.keyboard.isDown("w") then
		rectangle.w = rectangle.w + 75 * dt
		rectangle.h = rectangle.h + 75 * dt
	elseif love.keyboard.isDown("s") then
		rectangle.w = rectangle.w - 75 * dt
		rectangle.h = rectangle.h - 75 * dt
	end
end

function love.draw()
	love.graphics.print("Bloom?",4,4)
	love.graphics.print("Arrow keys to move",4,18)
	love.graphics.print("W key to grow, S key to shrink",4,32)

	bloom:predraw()

	love.graphics.setColor(255,0,0)
	love.graphics.rectangle("fill",rectangle.x,rectangle.y,rectangle.w,rectangle.h)
	love.graphics.setColor(255,255,255)

	bloom:postdraw() 
end
And here's what it looks like (at least on my computer):
Image

I have tried different colors (background and foreground), I've tried sprites, etc..., and nothing has worked. So I'm pretty sure there's a setting I have to set or something...?
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Try the attached demo (just something I stuck together from your code.).
The left image is created with bloom.
I think that this is the effect your are attempting???
Attachments
bloom.love
Just to see if bloom will work for you.
(67.71 KiB) Downloaded 324 times
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 71 guests