Howdy, Stranger!

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

Visual Illusion

I saw on Twitter an artist using blocks of different colors to achieve an interesting illusion effect, and I tried to implement it with code on codea:

function setup()
    displayMode(OVERLAY)
    print("Welcome to GrayZone!")
    move = false
    zone = mesh()
    zonei = zone:addRect(WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
    zone.shader = shader(fx.vs, fx.fs)
    zone.shader.resolution = vec2(2*WIDTH,2*HEIGHT)    
    cavas = image(WIDTH,HEIGHT)
    setContext(cavas)
    zone:draw()    
    setContext()    
    local sw,sh = 100,100
    s = cavas:copy(WIDTH/2-sw/2,HEIGHT/2+sh/2,sw,sh)   
    x,y = WIDTH/2-sw/2,HEIGHT/2
end

function draw()
    sprite(cavas,WIDTH/2,HEIGHT/2)
    -- rect(0,HEIGHT-200,WIDTH,200)
    sprite(s,60,HEIGHT-60)
    sprite(s,WIDTH-60,HEIGHT-60)
    -- sprite(s,WIDTH-60-100,HEIGHT-60)
    -- sprite(s,WIDTH-60-200,HEIGHT-60)

    if move then sprite(s, x,y) end

    fill(64, 255, 0, 255)
    local g = string.format("g.xyz: %.2f || %.2f || %.2f",Gravity.x,Gravity.y,Gravity.z)
    text(g, WIDTH/2,HEIGHT-30)
    -- 屏幕垂直地面时,Gravity.x 控制左右移动,Gravity.y控制前后移动
    sprite(s, (x+Gravity.x*1000),y-100-Gravity.z*1000)
end

function touched(touch)
    if touch.state == BEGAN or touch.state == MOVING then
        move = true
        x,y = touch.x, touch.y
    end

    if touch.state == ENDED then
        move = false
    end
end

fx = {
vs = [[
uniform mat4 modelViewProjection;

attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;

varying lowp vec4 vColor;
varying highp vec2 vTexCoord;

void main()
{
    vColor = color;
    vTexCoord = texCoord;

    gl_Position = modelViewProjection * position;
}
]],

fs = [[
precision highp float;

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

//This texture will be rendered atop the first
uniform lowp sampler2D texture2;

//This is the amount to mix the two textures
uniform float mixAmount;

uniform vec2 resolution;
uniform float size;

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

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

void main()
{
    vec2 position = ( gl_FragCoord.xy);

    vec3 color = vec3(0.0);

    float col = position.x/resolution.x;

    color = vec3(col, col , col);

    gl_FragColor = vec4( color, 1.0 );
}
]]
}

Touch the screen and move your finger. Enjoy it! :)

Tagged:

Comments

  • SimeonSimeon Admin Mod
    Posts: 5,054

    Interesting, is this based on one of those illusions where you see two shades of grey that look very different but are actually the same?

  • Posts: 104

    @Simeon Yeah! You got it.
    These rectangular blocks are exactly the same, but they look quite different against different grayscale backgrounds.

  • dave1707dave1707 Mod
    Posts: 7,872

    @binaryblues Your code was interesting. I thought I'd try something a little different. Drag your finger anywhere on the screen to move the center rectangle. You can modify the grey value or change the color of the rectangles. If any of the red, green, or blue values are greater than 0 then the color is used and the grey value ignored.

    function setup()
        parameter.integer("red",0,255)
        parameter.integer("green",0,255)
        parameter.integer("blue",0,255)
        parameter.integer("grey",0,255,100)
        rectMode(CENTER)
        noSmooth()
        c=0
        d=256/WIDTH
        strokeWidth(1)
        img=image(WIDTH,HEIGHT)
        setContext(img)
        for x=0,WIDTH do
            stroke(c)
            line(x,0,x,HEIGHT/2)
            stroke(c,255,0)
            line(x,HEIGHT/2,x,HEIGHT)
            c=c+d
        end  
        setContext() 
        dx,dy=WIDTH/2,HEIGHT/2
    end
    
    function draw()
        sprite(img,WIDTH/2,HEIGHT/2)
        if red+green+blue>0 then
            stroke(red,green,blue)
            fill(red,green,blue)
        else
            stroke(grey)
            fill(grey)
        end
        rect(WIDTH-100,HEIGHT/2+80,100,100)
        rect(WIDTH-100,HEIGHT/2-80,100,100)
        rect(100,HEIGHT/2+80,100,100)
        rect(100,HEIGHT/2-80,100,100)
        rect(dx,dy,100,120)
    end
    
    function touched(t)
        if t.state==MOVING then
            dx=dx+t.deltaX
            dy=dy+t.deltaY
        end
    end
    
  • edited July 28 Posts: 104

    @dave1707 Good job! You have done what I am going to do.

  • Posts: 31

    I like both examples very much. Dave’s code is how I would have gone about it. Binaryblue’s code I am still staring at trying to learn from....

Sign In or Register to comment.