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.
aranasaurus
Prole
Posts: 1
Joined: Fri Oct 10, 2014 5:28 am

Re: Share a Shader!

Post by aranasaurus »

For those wanting to use slime's Bloom shader in 0.9.1 I've updated it to work as such:

Code: Select all

-- source: https://love2d.org/forums/viewtopic.php?f=4&t=3733#p38666
-- Modified to work with löve 0.9.1
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.newShader
   or not love.graphics.isSupported
   or not love.graphics.isSupported("shader")
   or not love.graphics.isSupported("canvas") then
      return
   end
   
   local function newShader(code)
      local success, result = pcall(love.graphics.newShader, code)
      if success then
         return result
      else
         print("Error compiling shader!\n"..result)
      end
   end
   
   local bloom = {}
   
   local shaders = {}
   local shaders_src = {
      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_src) do
      local shader = newShader(v)
      if shader then
         shaders[k] = shader
      else
          print("poop")
         return
      end
   end
   
   if not shaders.blur_vert or not shaders.blur_horiz or not shaders.bloom or not shaders.combine then
       print( "didn't get all the shaders" )
      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.setShader(shaders.bloom)
      love.graphics.draw(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.setShader(shaders.blur_horiz)
      love.graphics.draw(self.canvas.bloom, self.quad, 0, 0)
      
      -- apply vertical blur shader to blurred bloom
      love.graphics.setCanvas(self.canvas.blur_vert)
      love.graphics.setShader(shaders.blur_vert)
      love.graphics.draw(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.setShader(shaders.combine)
      love.graphics.draw(self.canvas.scene, self.scenequad, 0, 0)
      
      love.graphics.setShader()
      
      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
To use it:

Code: Select all

require "bloom"

function love.load()
   bloom = CreateNewBloomEffect( W/2, H/2 ) -- adjust these params to your liking
end

function love.draw()
   bloom:predraw()
   bloom:enabledrawtobloom()

   -- Draw the things you want to be bloomed

   bloom:postdraw()
end
It should be noted that I am fairly noob in all things involved here, but this works for me and I saw a couple other people trying to make this work so I thought I'd share it!
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Share a Shader!

Post by Ref »

Just another funky shader.
Probably best describer as a gradient stencil?
Attachments
pulse.love
Simple gradient shader
(454.49 KiB) Downloaded 909 times
Mystical
Prole
Posts: 7
Joined: Sun Mar 15, 2015 4:39 pm

Re: Share a Shader!

Post by Mystical »

I did a voxelcaster with GLSL akin to Commanche, an old DOS game.

It's quite slow and I've got no idea how to optimize it further.
Attachments
GLSL voxelcaster.love
2.5D Voxel Raycaster
(524.84 KiB) Downloaded 556 times
User avatar
Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

Re: Share a Shader!

Post by Ranguna259 »

Two dimensional Black Holes :D

Press tab to switch between images, this shader also works on Android and iOS and supports multi-touch (best used in landscape mode).
Image
Attachments
blackHole.love
(1.23 MiB) Downloaded 660 times
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping :D

Check out my twitter.
User avatar
zorg
Party member
Posts: 3435
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Share a Shader!

Post by zorg »

Ranguna259 wrote:Two dimensional Black Holes :D
Really nice! Although, shouldn't it distort the space "inwards", instead of outwards like how it creates a bulge around the event horizon?
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

Re: Share a Shader!

Post by Ranguna259 »

zorg wrote:Really nice! Although, shouldn't it distort the space "inwards", instead of outwards like how it creates a bulge around the event horizon?
Thanks :)
The think is, a black hole doesn't exist in a 2D plane, the only way to render a black hole is in a three dimensional space because what you see around the event horizon is no what's behind the black hole but it's actually what is all around it, if you're in the right position you might even see yourself right next to the black hole but this only happens in 3D.
Take a look at this pic:
Image
As you can see the light travels around the black hole in three dimensional space and this is impossible to reproduce in 2D because the visible space in a 2D universe is a stright line and not a top down view of a plane ( see Flatland for more details on visualisation of a 2D universe)
Because of all this I simply have no way of rendering a black hole and so I simply mimicked images of black hole that I saw on google like this one:
Image
(As I explained before, what is being distorted in that image is not the space that is behinde the black hole but it's actually what is around it)

TL;DR
There's no way to effectively mimic a black hole in 2D because they only exist in three dimensional space and so I only tried to mimic images of black holes like the one above.

I think I got it pretty close ;)
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping :D

Check out my twitter.
User avatar
FlattenedTesseract
Prole
Posts: 14
Joined: Mon Jul 27, 2015 9:01 am
Location: Bucharest, Romania

Re: Share a Shader!

Post by FlattenedTesseract »

Here's a kingdom(the game)-like water reflection thingy:

Use the left and right arrows to move left and right.
Attachments
kingdom_water.love
(32.92 KiB) Downloaded 939 times
User avatar
Ulydev
Party member
Posts: 445
Joined: Mon Nov 10, 2014 10:46 pm
Location: Paris
Contact:

Re: Share a Shader!

Post by Ulydev »

FlattenedTesseract wrote:Here's a kingdom(the game)-like water reflection thingy:

Use the left and right arrows to move left and right.
Nice! :nyu:
binaryeye
Prole
Posts: 8
Joined: Wed Feb 03, 2016 2:58 pm

Re: Share a Shader!

Post by binaryeye »

This may be the wrong thread because I don't know if this shader actually works.

I'm trying to convert a CRT shader found on Shadertoy to LÖVE. It runs without errors, but I get a black screen. I don't know if this is because the shader isn't working or because my system doesn't support it. I'm not exactly sure what I should be passing to the iChannel variable (it seems to want an image, so I'm drawing to a buffer and passing that), nor what the first variable should be in iResolution, so those could also be problems.

I've attached a .love. If anyone could run it and let me know what happens, I'd appreciate it. There should be a white circle in the center of the screen. Thanks!
Attachments
crt_shader_test.love
(2.62 KiB) Downloaded 483 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 »

binaryeye wrote:I've attached a .love. If anyone could run it and let me know what happens, I'd appreciate it. There should be a white circle in the center of the screen. Thanks!
I get a black screen as well. :(
Help us help you: attach a .love.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 20 guests