Hey everyone!
I’ve been working on the newest version of my drawing app, and I just finished a quick (actually not so quick) test for my color picker! I somehow managed to figure out the shader code, and I am quite happy with how it turned out! So far I haven’t found anything similar on the forum—using shaders at least—so I thought it might be useful to share!
--# Main
-- HSV Shader
function setup()
m = mesh()
m:addRect(WIDTH/2,HEIGHT/2,200,200)
m.shader = shader(vertex,fragment)
hue = 0
ring = mesh()
res = 180
local v = {}
local c = {}
for i = 1,res do
local v1 = vec2(0,200):rotate((i-1)*math.pi*2/-res)
local v2 = vec2(0,200):rotate(i*math.pi*2/-res)
local v3 = vec2(0,150):rotate(i*math.pi*2/-res)
local v4 = vec2(0,150):rotate((i-1)*math.pi*2/-res)
local r,g,b
r,g,b = hsvToRgb((i-1)/res,1,1)
local c1 = color(r,g,b,255)
r,g,b = hsvToRgb(i/res,1,1)
local c2 = color(r,g,b,255)
for i,vv in pairs({v1,v2,v3,v3,v4,v1}) do table.insert(v,vv) end
for i,cc in pairs({c1,c2,c2,c2,c1,c1}) do table.insert(c,cc) end
end
ring.vertices = v
ring.colors = c
end
function draw()
background(40, 40, 50)
pushMatrix()
translate(WIDTH/2,HEIGHT/2)
-- scale(3)
ring:draw()
popMatrix()
hue = hue + DeltaTime/5
if hue > 1 then hue = hue - 1 end
m.shader.h = hue
m:draw()
end
function hsvToRgb(h,s,v)
local r,g,b
local i = math.floor(h * 6);
local f = h * 6 - i;
local p = v * (1 - s);
local q = v * (1 - f * s);
local t = v * (1 - (1 - f) * s);
i = i % 6
if i == 0 then r, g, b = v, t, p
elseif i == 1 then r, g, b = q, v, p
elseif i == 2 then r, g, b = p, v, t
elseif i == 3 then r, g, b = p, q, v
elseif i == 4 then r, g, b = t, p, v
elseif i == 5 then r, g, b = v, p, q
end
return r * 255, g * 255, b * 255
end
vertex = [[
//
// 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;
}
]]
fragment = [[
//
// A basic fragment shader
//
//Default precision qualifier
precision highp float;
//This represents the current texture on the mesh
uniform lowp sampler2D texture;
uniform float h;
//The interpolated vertex color for this fragment
varying lowp vec4 vColor;
//The interpolated texture coordinate for this fragment
varying highp vec2 vTexCoord;
void main()
{
// float h = 0.7;
float s = vTexCoord.x;
float v = vTexCoord.y;
float r,g,b;
float i = h*6.0;
i = floor(i);
float f = h * 6. - i;
float p = v * (1. - s);
float q = v * (1. - f * s);
float t = v * (1. - (1. - f) * s);
if (i == 0.) r=v,g=t,b=p;
if (i == 1.) r=q,g=v,b=p;
if (i == 2.) r=p,g=v,b=t;
if (i == 3.) r=p,g=q,b=v;
if (i == 4.) r=t,g=p,b=v;
if (i == 5.) r=v,g=p,b=q;
highp vec4 col = vec4(r,g,b,1.0);
gl_FragColor = col;
}
]]
EDIT: I added a fancy color wheel