Help with Hotline Miami 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.
Post Reply
LinusNeuman
Prole
Posts: 4
Joined: Mon Sep 28, 2015 10:39 am

Help with Hotline Miami Shader

Post by LinusNeuman »

Hello!

I am trying to make a new shader that splits up R-, G-, and B-channels into separate layers that converge, which will create an old-vcr-feel to it, like Hotline Miami has done.

The problem is that Lua Shader coding is very unintuitive.
This is the code I found in the Unity forums for a GLSL shader that does this:

Code: Select all

Shader "Custom/ChromaticAberration" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Pass
        {
       
        CGPROGRAM
        #pragma vertex vert_img
        #pragma fragment frag
        #pragma fragmentoption ARB_precision_hint_fastest
        #include "UnityCG.cginc"
 
        uniform sampler2D _MainTex;
        uniform float _AberrationOffset;
 
        float4 frag(v2f_img i) : COLOR
        {
 
            float2 coords = i.uv.xy;
           
            _AberrationOffset /= 300.0f;
           
            //Red Channel
            float4 red = tex2D(_MainTex , coords.xy - _AberrationOffset);
            //Green Channel
            float4 green = tex2D(_MainTex, coords.xy );
            //Blue Channel
            float4 blue = tex2D(_MainTex, coords.xy + _AberrationOffset);
           
            float4 finalColor = float4(red.r, green.g, blue.b, 1.0f);
            return finalColor;
       
        }
 
        ENDCG
        }
    }
}
I converted it to this:

Code: Select all

  hotlineShader = love.graphics.newShader[[
  extern Image _MainTex;
  number _AberrationOffset;

        vec4 frag(v2f_img i) : COLOR
        {
          vec2 coords = i.uv.xy;

          _AberrationOffset /= 300.0f;

          //Red Channel
          vec4 red = Texel(_MainTex , coords.xy - _AberrationOffset);
          //Green Channel
          vec4 green = Texel(_MainTex, coords.xy );
          //Blue Channel
          vec4 blue = Texel(_MainTex, coords.xy + _AberrationOffset);

          vec4 finalColor = vec4(red.r, green.g, blue.b, 1.0f);
          return finalColor;
        }

    vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){

          }

  ]]
Which gives these errors:
Image

Any help is appreciated, I have only written a bloom shader before and that was in HLSL and not in some "embedding kind of GLSL" style that Lua Löve2D has.


EDIT1:
I have made a chromaticAberration.glsl file which I load as shader and it does this:

Code: Select all

float _AberrationOffset;

vec4 effect(vec4 col, Image texture, vec2 texturePos, vec2 screenPos)
{

    vec2 coords = texturePos;

    _AberrationOffset /= 300.0f;

vec4 pixel = texture2D(texture, texturePos);
    //Red Channel
    vec4 red = texture2D(texture , coords - _AberrationOffset);
    //Green Channel
    vec4 green = texture2D(texture, coords );
    //Blue Channel
    vec4 blue = texture2D(texture, coords + _AberrationOffset);

    vec4 finalColor = vec4(red.r, green.g, blue.b, 1.0f);
    return finalColor;

}
It gives no error, however, it does not do anything.. At all..
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Help with Hotline Miami Shader

Post by s-ol »

How are you using your shader? It cannot work on primitives, it only works with a texture. Therefore you need to render everything to a canvas, then draw that canvas to the screen using the shader. Here's a working example:

Code: Select all

shader = love.graphics.newShader([[
  extern number aberration;

  vec4 effect(vec4 col, Image texture, vec2 texturePos, vec2 screenPos)
  {
    vec2 coords = texturePos;
    vec2 offset = vec2(aberration, 0);

    vec4 red = texture2D(texture , coords - offset);
    vec4 green = texture2D(texture, coords);
    vec4 blue = texture2D(texture, coords + offset);

    vec4 finalColor = vec4(red.r, green.g, blue.b, 1.0f);
    return finalColor;
  }
]], [[
  vec4 position( mat4 transform_projection, vec4 vertex_position )
  {
    return transform_projection * vertex_position;
  }
]])
shader:send("aberration", 0.003)

cvs = love.graphics.newCanvas()

function love.draw()
  love.graphics.setCanvas(cvs)
  love.graphics.setShader()
  love.graphics.setColor(255, 255, 255)
  love.graphics.circle("fill", 100, 200, 50)

  love.graphics.setColor(255, 120, 255)
  love.graphics.circle("fill", 140, 400, 50)

  love.graphics.setColor(0, 120, 130)
  love.graphics.circle("fill", 340, 200, 50)

  love.graphics.setCanvas()
  love.graphics.setShader(shader)
  love.graphics.draw(cvs)
end
I modified the shader a bit, maybe yours works too though; I didn't realize what the problem was until I had 'fixed' the shader already either.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
LinusNeuman
Prole
Posts: 4
Joined: Mon Sep 28, 2015 10:39 am

Re: Help with Hotline Miami Shader

Post by LinusNeuman »

S0lll0s wrote:How are you using your shader? It cannot work on primitives, it only works with a texture. Therefore you need to render everything to a canvas, then draw that canvas to the screen using the shader. Here's a working example:

Code: Select all

shader = love.graphics.newShader([[
  extern number aberration;

  vec4 effect(vec4 col, Image texture, vec2 texturePos, vec2 screenPos)
  {
    vec2 coords = texturePos;
    vec2 offset = vec2(aberration, 0);

    vec4 red = texture2D(texture , coords - offset);
    vec4 green = texture2D(texture, coords);
    vec4 blue = texture2D(texture, coords + offset);

    vec4 finalColor = vec4(red.r, green.g, blue.b, 1.0f);
    return finalColor;
  }
]], [[
  vec4 position( mat4 transform_projection, vec4 vertex_position )
  {
    return transform_projection * vertex_position;
  }
]])
shader:send("aberration", 0.003)

cvs = love.graphics.newCanvas()

function love.draw()
  love.graphics.setCanvas(cvs)
  love.graphics.setShader()
  love.graphics.setColor(255, 255, 255)
  love.graphics.circle("fill", 100, 200, 50)

  love.graphics.setColor(255, 120, 255)
  love.graphics.circle("fill", 140, 400, 50)

  love.graphics.setColor(0, 120, 130)
  love.graphics.circle("fill", 340, 200, 50)

  love.graphics.setCanvas()
  love.graphics.setShader(shader)
  love.graphics.draw(cvs)
end
I modified the shader a bit, maybe yours works too though; I didn't realize what the problem was until I had 'fixed' the shader already either.
Sorry for late response.
I solved it though, turns out that the shader has way too high abbrevetation, this is the shader now fully functional:

Code: Select all

uniform float _AberrationOffset;

vec4 effect(vec4 col, Image texture, vec2 texturePos, vec2 screenPos)
{
    vec2 coords = texturePos;

vec4 pixel = texture2D(texture, texturePos);
    //Red Channel
    vec4 red = texture2D(texture , coords - _AberrationOffset);
    //Green Channel
    vec4 green = texture2D(texture, coords);
    //Blue Channel
    vec4 blue = texture2D(texture, coords + _AberrationOffset);

    vec4 finalColor = vec4(red.r, green.g, blue.b, 1.0f);
    return finalColor;
}
You need to send an initial abbrevetation though:

Code: Select all

RGBShader = love.graphics.newShader("RGB.glsl")
RGBShader:send("_AberrationOffset", 0.01)
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 5 guests