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! :slight_smile:

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?

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

@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

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

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…