Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Two cool shaders.

edited June 2013 in Code Sharing Posts: 1,976

Here's how it starts with everything I make; I get an idea, and make it the next day. Yesterday, I came up with ideas for two cool shaders. Here they are now.

Using the code from the Shaders example, I coded two shaders. One can detect color in a photo and remove it (Which can look really cool and freak!), and the other can blend images together. Both are very simple, but have cool effects. Here's the code:

-- Use this function to perform your initial setup
displayMode(STANDARD)

function setup()
    saveProjectInfo("Description", "Two cool shaders I threw together. By SkyTheCoder.")
    saveProjectInfo("Author", "SkyTheCoder")
    saveProjectInfo("Version", "1.0")

    parameter.integer("Texture",1,5,2)
    parameter.integer("BlendImagesTexture",1,5,2)

    allTextures = {
                    CAMERA,
                    "Cargo Bot:Codea Icon",
                    "Small World:Store Extra Large",
                    "Small World:Windmill",
                    "Tyrian Remastered:Boss D",
                  }

    cameraSource(CAMERA_FRONT)

    m = mesh()
    m.texture = allTextures[Texture]
    m.shader = shader(ShaderTests.testForColor.vertexShader, ShaderTests.testForColor.fragmentShader)

    currentShader = 1

    parameter.action("Front Camera", function() cameraSource(CAMERA_FRONT) Texture = 1 end)
    parameter.action("Back Camera", function() cameraSource(CAMERA_BACK) Texture = 1 end)
    parameter.action("Color Detection shader", function() m.shader = shader(ShaderTests.testForColor.vertexShader, ShaderTests.testForColor.fragmentShader) currentShader = 1 end)
    parameter.action("Blend Images shader", function() m.shader = shader(ShaderTests.blendImages.vertexShader, ShaderTests.blendImages.fragmentShader) currentShader = 2 end)
    parameter.number("rgb", 0, 1, 0)
    parameter.number("r", 0, 1, 0)
    parameter.number("g", 0, 1, 0)
    parameter.number("b", 0, 1, 0)
    parameter.number("a", 0, 1, 1)
    parameter.number("flexibility", 0, 1, 0)
    parameter.number("alphaFlexibility", 0, 1, 0)
    m.shader.rgb = 0
    m.shader.r = 0
    m.shader.g = 0
    m.shader.b = 0
    m.shader.a = 0
    m.shader.flexibility = 0
    m.shader.alphaFlexibility = 0

    rIdx = m:addRect(0, 0, 0, 0)
    --m:setRectColor(i, 255,0,0)
end

-- This function gets called once every frame
function draw()
    if currentShader == 1 then
        m.shader.rgb = rgb
        m.shader.r = r
        m.shader.g = g
        m.shader.b = b
        m.shader.a = a
        m.shader.flexibility = flexibility
        m.shader.alphaFlexibility = alphaFlexibility
    end

    if currentShader == 2 then
        m.shader.image = allTextures[BlendImagesTexture]
    end

    -- This sets a dark background color
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)

    -- Here we set up the rect texture and size
    m.texture = allTextures[Texture]
    local cw,ch = spriteSize(allTextures[Texture])
    m:setRect(rIdx, WIDTH/2, HEIGHT/2, cw, ch)

    -- Configure out custom uniforms for the ripple shader
    --m.shader.time = ElapsedTime
    --m.shader.freq = Freq

    -- Draw the mesh
    m:draw()
end

ShaderTests = class()

-- Color detection shader
ShaderTests.testForColor = {
vertexShader = [[
//
// A basic vertex shader
//

//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;

//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;

//This is an output variable that will be passed to the fragment shader
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;

void main()
{
    //Pass the mesh color to the fragment shader
    vColor = color;
    vTexCoord = texCoord;

    //Multiply the vertex position by our combined transform
    gl_Position = modelViewProjection * position;
}
]],
fragmentShader = [[
//
// A basic fragment shader
//

//Default precision qualifier
precision highp float;

//This represents the current texture on the mesh
uniform lowp sampler2D texture;

//The interpolated vertex color for this fragment
varying lowp vec4 vColor;

//The interpolated texture coordinate for this fragment
varying highp vec2 vTexCoord;

uniform float rgb;
uniform float r;
uniform float g;
uniform float b;
uniform float a;
uniform float flexibility;
uniform float alphaFlexibility;

void main()
{
    lowp vec4 pixel = texture2D(texture, vTexCoord);

    if (pixel.r >= (r + rgb) - flexibility && pixel.g >= (g + rgb) - flexibility && pixel.b >= (b + rgb) - flexibility && pixel.a >= a - alphaFlexibility && pixel.r <= (r + rgb) + flexibility && pixel.g <= (g + rgb) + flexibility && pixel.b <= (b + rgb) + flexibility && pixel.a <= a + alphaFlexibility) {
        discard;
    }

    //Sample the texture at the interpolated coordinate
    lowp vec4 col = texture2D( texture, vTexCoord ) * vColor;

    //Set the output color to the texture color
    gl_FragColor = col;
}
]]
}

-- Blend Images shader
ShaderTests.blendImages = {
vertexShader = [[
//
// A basic vertex shader
//

//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;

//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;

//This is an output variable that will be passed to the fragment shader
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;

void main()
{
    //Pass the mesh color to the fragment shader
    vColor = color;
    vTexCoord = texCoord;

    //Multiply the vertex position by our combined transform
    gl_Position = modelViewProjection * position;
}
]],
fragmentShader = [[
//
// A basic fragment shader
//

//Default precision qualifier
precision highp float;

//This represents the current texture on the mesh
uniform lowp sampler2D texture;
uniform lowp sampler2D image;

//The interpolated vertex color for this fragment
varying lowp vec4 vColor;

//The interpolated texture coordinate for this fragment
varying highp vec2 vTexCoord;

void main()
{
    //Sample the texture at the interpolated coordinate
    lowp vec4 col = texture2D( texture, vTexCoord );

    lowp vec4 iColor = texture2D(image, vTexCoord);

    vec4 even = vec4(0.5, 0.5, 0.5, 1.0);

    //Set the output color to the texture color
    gl_FragColor = (col - even) + (iColor - even);
}

]]
}

Just put that in a project, and have fun blending images and filtering out colors. Here are some images I took of my cat to show off the shaders... Color filter: http://i.imgur.com/Lluwae6.jpg Blend images: http://i.imgur.com/8phqHEc.jpg

Comments

  • IgnatzIgnatz Mod
    edited June 2013 Posts: 5,396

    Ok, SkyTheCoder, we get the idea. You're VERY fast . 'Nuff now. In this forum, we let our code do the talking.

    What matters is you're having fun and sharing, and that's great. And you're building shaders, and that's cool. I agree that shaders are amazing. You should look at the code of the built in examples in the Shader Lab, there is an image blender there, too, very similar to yours.

    I've been sharing some shaders, too. I just posted about the shader I think is the best I've seen, for tiling images across large meshes, with just one change to the fragment shader. This is incredibly useful for 3D modelling (credit to spacemonkey). Here - http://coolcodea.wordpress.com/2013/06/06/78-shaders-tiling-images/

    The colour removal shader is nice, is that your own algorithm or did you get it from the net? I'm just wondering if there's a way to cut down on all those if tests in the fragment shader. I found a nice explanation of the three methods used in Gimp, here.
    http://www.johndcook.com/blog/2009/08/24/algorithms-convert-color-grayscale/

  • edited August 2014 Posts: 1,976

    [Removed]

    I didn't even think to check if there was an image blender already, I just made it... And yes, that is my own algorithm. I just used the default template. And sorry if it seemed like I was showing off when I said I was fast. I'm only eleven, please forgive me if I say or do the wrong thing.

  • edited June 2013 Posts: 1,976

    Derp, there it is. A blend images filter already built in... Fail.

    Wow, GLSL shaders even have a built in way of blending textures... My code takes the RGB values of the two images, mixes them together to make a new set of RGB values, and then draws that to the screen, whereas the example can just mix the pixels using built-in stuff...

  • IgnatzIgnatz Mod
    edited June 2013 Posts: 5,396

    That's cool, yours was a good effort. I'd like to see you using those Gimp algorithms to see which is better, maybe, or maybe offering a choice of algorithm. But that's up to you.

    (What you will find, though, is that someone has always thought of a good way to do these things. My problem is usually trying to understand it!).

    Many of the built in shaders are based on difficult mathematics, but I found the brick shader interesting, because the code was fairly simple, and it shows you can pass information like xyz position from the vertex shader to the fragment shader, which I hadn't realised.

Sign In or Register to comment.