Page 28 of 33

Re: Share a Shader!

Posted: Mon Dec 15, 2014 9:30 pm
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!

Re: Share a Shader!

Posted: Sat Apr 04, 2015 3:42 pm
by Ref
Just another funky shader.
Probably best describer as a gradient stencil?

Re: Share a Shader!

Posted: Fri Nov 20, 2015 10:02 am
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.

Re: Share a Shader!

Posted: Sun Nov 22, 2015 12:47 pm
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

Re: Share a Shader!

Posted: Sun Nov 22, 2015 4:50 pm
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?

Re: Share a Shader!

Posted: Sun Nov 22, 2015 9:01 pm
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 ;)

Re: Share a Shader!

Posted: Sun Dec 06, 2015 11:23 am
by FlattenedTesseract
Here's a kingdom(the game)-like water reflection thingy:

Use the left and right arrows to move left and right.

Re: Share a Shader!

Posted: Sun Dec 06, 2015 11:42 am
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:

Re: Share a Shader!

Posted: Sat Feb 27, 2016 4:28 pm
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!

Re: Share a Shader!

Posted: Sat Feb 27, 2016 9:55 pm
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. :(