@Andrew_Stacey, how would the mesh shader vertices table need to be set? is there a specific order?
The quadrilateral is specified in the table v
. Vertices 1 and 4 are opposite, as are vertices 2 and 3. So if it were a square, it would be:
3 --- 4
| |
1 --- 2
The quadrilateral is triangulated into 1-2-4
and 1-3-4
. We also pass in the table of vertices to the mesh, this is the line m.shader.vertices = v
. The colours are passed in similarly: there is an obvious correspondence between the tables of vertices and colours.
The ordering of the vertices - in case you’re interested - in the quadrilateral is using a binary encoding (offset by one since Lua tables start at 1) then splitting into coordinates. In binary, and subtracting one, the above diagram is:
10 --- 11
| |
00 --- 01
so that’s x and y coordinates, except that I’ve put them the wrong way around (not that that matters).
(I haven’t done arbitrary texCoords, it puts the texture on the mesh fitting it in the corners. I intend to extend it.)
@Andrew_Stacey hmmm my head currently doesn’t get the hang of it xo
--# GradientFill
--Project: Gradient Fill
--Author: Andrew Stacey
--Version: 1.1
--Comments: Uploaded too many tabs!
--Options:
--Tabs: GradientFill
--Dependencies:
if localise then localise("GradientFill") end
function setup()
a = mesh()
x = WIDTH/2
y = HEIGHT/2
vec = {vec2(x-100, y-100), vec2(x-100, y+100), vec2(x+100, y+100), vec2(x+100, y-100)}
col = {color(255, 255, 255, 255), color(255, 0, 0, 255), color(127, 127, 127, 255), color(0, 0, 0, 255)}
v = {}
c = {}
v[1] = vec[1] c[1] = col[1]
v[2] = vec[4] c[2] = col[1]
v[3] = vec[3] c[3] = col[1]
v[4] = vec[1] c[4] = col[1]
v[5] = vec[2] c[5] = col[1]
v[6] = vec[3] c[6] = col[1]
a.vertices = v
a.colors = c
a.shader = shaderGradientFill()
a.shader.vertices = vec
a.shader.colours = {
color(0, 0, 0, 255),
color(255, 0, 0, 255),
color(0, 50, 255, 255),
color(255, 255, 255, 255)
}
end
function draw()
background(40,40,50)
a:draw()
end
function touched(t)
end
function shaderGradientFill ()
return shader([[
//
// 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;
//This is an output variable that will be passed to the fragment shader
varying highp vec3 vPosition;
void main()
{
//Pass the mesh color to the fragment shader
vPosition = position.xyz;
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
]],[[
//
// A basic fragment shader
//
//Default precision qualifier
precision highp float;
//This represents the current texture on the mesh
uniform lowp sampler2D texture;
uniform vec3 vertices[4];
uniform vec4 colours[4];
vec3 np = cross(vertices[0]-vertices[1],vertices[0]-vertices[2]);
vec3 nx = cross(np,vertices[0] - vertices[2]);
vec3 ny = cross(np,vertices[0] - vertices[1]);
vec3 ox = (dot(nx,vertices[0]-vertices[3])*vertices[1] - dot(nx,vertices[0]-vertices[1])*vertices[3]);
float dx = dot(nx,vertices[1] - vertices[3]);
vec3 oy = (dot(ny,vertices[0]-vertices[3])*vertices[2] - dot(ny,vertices[0]-vertices[2])*vertices[3]);
float dy = dot(ny,vertices[2] - vertices[3]);
vec3 vx = (vertices[1] - vertices[0])/dot(vertices[1] - vertices[0],vertices[1] - vertices[0]);
vec3 vy = (vertices[2] - vertices[0])/dot(vertices[2] - vertices[0],vertices[2] - vertices[0]);
varying highp vec3 vPosition;
void main()
{
vec3 qx;
vec3 qy;
float x;
float y;
if (dx != 0.) {
qx = (dot(ny,dx*vertices[0] - ox)*vPosition - dot(ny, vertices[0] - vPosition) * ox)/(dot(ny,dx*vPosition - ox));
} else {
qx = vPosition + dot(ny,vertices[0] - vPosition)*(vertices[2] - vertices[0])/dot(ny,vertices[2] - vertices[0]);
}
x = dot(qx - vertices[0],vx);
if (dy != 0.) {
qy = (dot(nx,dy*vertices[0] - oy)*vPosition - dot(nx, vertices[0] - vPosition) * oy)/(dot(nx,dy*vPosition - oy));
} else {
qy = vPosition + dot(nx,vertices[0] - vPosition)*(vertices[1] - vertices[0])/dot(nx,vertices[1] - vertices[0]);
}
y = dot(qy - vertices[0],vy);
lowp vec4 tex = texture2D( texture, vec2(x,y) );
lowp vec4 col = (1.-y)*(1.-x)*colours[0] + (1.-y)*x*colours[1] + y*(1.-x)*colours[2] + y*x*colours[3];
//Set the output color to the texture color
gl_FragColor = col*tex;
}
]])
end
I could figure out the right positions
The vertices should be
vec = {vec2(x-100, y-100), vec2(x-100, y+100), vec2(x+100, y-100), vec2(x+100, y+100)}
and v[6]
should be vec[4]
@Andrew_Stacey the vertices are now correct, howerver, I don’t assign a texture, and yet it displayez ‘Made With Codea’ inside the mesh, nothing else, just that, filled with a gradient
thanks so far already
If you dn’t want to assign a texture at all, remove the lowp vec4 tex = ...
line and change the gl_FragColor to just col.
(There’s a bug whereby if you have a texture in the shader but don’t assign one then it uses one anyway.)
@Andrew_Stacey I did as you said and it now shows a blank screen
--# GradientFill
--Project: Gradient Fill
--Author: Andrew Stacey
--Version: 1.1
--Comments: Uploaded too many tabs!
--Options:
--Tabs: GradientFill
--Dependencies:
if localise then localise("GradientFill") end
function setup()
a = mesh()
x = WIDTH/2
y = HEIGHT/2
vec = {vec2(x-100, y-100), vec2(x-100, y+100), vec2(x+100, y-100), vec2(x+100, y+100)}
col = {color(255, 255, 255, 255), color(255, 0, 0, 255), color(127, 127, 127, 255), color(0, 0, 0, 255)}
v = {}
c = {}
v[1] = vec[1] c[1] = col[1]
v[2] = vec[4] c[2] = col[1]
v[3] = vec[3] c[3] = col[1]
v[4] = vec[1] c[4] = col[1]
v[5] = vec[2] c[5] = col[1]
v[6] = vec[4] c[6] = col[1]
a.vertices = v
a.colors = c
a.shader = shaderGradientFill()
a.shader.vertices = vec
a.shader.colours = {
color(0, 0, 0, 255),
color(255, 0, 0, 255),
color(0, 50, 255, 255),
color(255, 255, 255, 255)
}
end
function draw()
background(40,40,50)
a:draw()
end
function touched(t)
end
function shaderGradientFill ()
return shader([[
//
// 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;
//This is an output variable that will be passed to the fragment shader
varying highp vec3 vPosition;
void main()
{
//Pass the mesh color to the fragment shader
vPosition = position.xyz;
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
]],[[
//
// A basic fragment shader
//
//Default precision qualifier
precision highp float;
//This represents the current texture on the mesh
uniform lowp sampler2D texture;
uniform vec3 vertices[4];
uniform vec4 colours[4];
vec3 np = cross(vertices[0]-vertices[1],vertices[0]-vertices[2]);
vec3 nx = cross(np,vertices[0] - vertices[2]);
vec3 ny = cross(np,vertices[0] - vertices[1]);
vec3 ox = (dot(nx,vertices[0]-vertices[3])*vertices[1] - dot(nx,vertices[0]-vertices[1])*vertices[3]);
float dx = dot(nx,vertices[1] - vertices[3]);
vec3 oy = (dot(ny,vertices[0]-vertices[3])*vertices[2] - dot(ny,vertices[0]-vertices[2])*vertices[3]);
float dy = dot(ny,vertices[2] - vertices[3]);
vec3 vx = (vertices[1] - vertices[0])/dot(vertices[1] - vertices[0],vertices[1] - vertices[0]);
vec3 vy = (vertices[2] - vertices[0])/dot(vertices[2] - vertices[0],vertices[2] - vertices[0]);
varying highp vec3 vPosition;
void main()
{
vec3 qx;
vec3 qy;
float x;
float y;
if (dx != 0.) {
qx = (dot(ny,dx*vertices[0] - ox)*vPosition - dot(ny, vertices[0] - vPosition) * ox)/(dot(ny,dx*vPosition - ox));
} else {
qx = vPosition + dot(ny,vertices[0] - vPosition)*(vertices[2] - vertices[0])/dot(ny,vertices[2] - vertices[0]);
}
x = dot(qx - vertices[0],vx);
if (dy != 0.) {
qy = (dot(nx,dy*vertices[0] - oy)*vPosition - dot(nx, vertices[0] - vPosition) * oy)/(dot(nx,dy*vPosition - oy));
} else {
qy = vPosition + dot(nx,vertices[0] - vPosition)*(vertices[1] - vertices[0])/dot(nx,vertices[1] - vertices[0]);
}
y = dot(qy - vertices[0],vy);
lowp vec4 col = (1.-y)*(1.-x)*colours[0] + (1.-y)*x*colours[1] + y*(1.-x)*colours[2] + y*x*colours[3];
//Set the output color to the texture color
//col = col*tex;
}
]])
end
and yeah, you still gotta remove the comment of col = col*tex
I thought that what the problem because there not being a texture… commenting it out creates a funny effect tho
Sorry! I was typing late at night. I meant to change the col*tex to just col, not the whole line.
--The name of the project must match your Codea project name if dependencies are used.
--Project: Place Project Name Here
--Author:
--Version: Alpha 1.0
--Comments:
if localise then localise("steven8trGradientFill") end
function setup()
a = mesh()
x = WIDTH/2
y = HEIGHT/2
vec = {vec2(x-100, y-100), vec2(x-100, y+100), vec2(x+100, y-100), vec2(x+100, y+100)}
col = {color(255, 255, 255, 255), color(255, 0, 0, 255), color(127, 127, 127, 255), color(0, 0, 0, 255)}
v = {}
c = {}
v[1] = vec[1] c[1] = col[1]
v[2] = vec[4] c[2] = col[1]
v[3] = vec[3] c[3] = col[1]
v[4] = vec[1] c[4] = col[1]
v[5] = vec[2] c[5] = col[1]
v[6] = vec[4] c[6] = col[1]
a.vertices = v
a.colors = c
a.shader = shaderGradientFill()
a.shader.vertices = vec
a.shader.colours = {
color(0, 0, 0, 255),
color(255, 0, 0, 255),
color(0, 50, 255, 255),
color(255, 255, 255, 255)
}
end
function draw()
background(40,40,50)
a:draw()
end
function touched(t)
end
function shaderGradientFill ()
return shader([[
//
// 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;
//This is an output variable that will be passed to the fragment shader
varying highp vec3 vPosition;
void main()
{
//Pass the mesh color to the fragment shader
vPosition = position.xyz;
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
]],[[
//
// A basic fragment shader
//
//Default precision qualifier
precision highp float;
//This represents the current texture on the mesh
//uniform lowp sampler2D texture;
uniform vec3 vertices[4];
uniform vec4 colours[4];
vec3 np = cross(vertices[0]-vertices[1],vertices[0]-vertices[2]);
vec3 nx = cross(np,vertices[0] - vertices[2]);
vec3 ny = cross(np,vertices[0] - vertices[1]);
vec3 ox = (dot(nx,vertices[0]-vertices[3])*vertices[1] - dot(nx,vertices[0]-vertices[1])*vertices[3]);
float dx = dot(nx,vertices[1] - vertices[3]);
vec3 oy = (dot(ny,vertices[0]-vertices[3])*vertices[2] - dot(ny,vertices[0]-vertices[2])*vertices[3]);
float dy = dot(ny,vertices[2] - vertices[3]);
vec3 vx = (vertices[1] - vertices[0])/dot(vertices[1] - vertices[0],vertices[1] - vertices[0]);
vec3 vy = (vertices[2] - vertices[0])/dot(vertices[2] - vertices[0],vertices[2] - vertices[0]);
varying highp vec3 vPosition;
void main()
{
vec3 qx;
vec3 qy;
float x;
float y;
if (dx != 0.) {
qx = (dot(ny,dx*vertices[0] - ox)*vPosition - dot(ny, vertices[0] - vPosition) * ox)/(dot(ny,dx*vPosition - ox));
} else {
qx = vPosition + dot(ny,vertices[0] - vPosition)*(vertices[2] - vertices[0])/dot(ny,vertices[2] - vertices[0]);
}
x = dot(qx - vertices[0],vx);
if (dy != 0.) {
qy = (dot(nx,dy*vertices[0] - oy)*vPosition - dot(nx, vertices[0] - vPosition) * oy)/(dot(nx,dy*vPosition - oy));
} else {
qy = vPosition + dot(nx,vertices[0] - vPosition)*(vertices[1] - vertices[0])/dot(nx,vertices[1] - vertices[0]);
}
y = dot(qy - vertices[0],vy);
//lowp vec4 tex = texture2D( texture, vec2(x,y) );
lowp vec4 col = (1.-y)*(1.-x)*colours[0] + (1.-y)*x*colours[1] + y*(1.-x)*colours[2] + y*x*colours[3];
//Set the output color to the texture color
gl_FragColor = col; //*tex;
}
]])
end
@Andrew_Stacey thank you so much, this look so much better + I can probably understand the calculations so thank you so much I’ll work on this when I get home from school
New version on CC (will need same tweaks for non-textured meshes). Much simpler shader code.
@Andrew_Stacey thanks for all your effort in this, once I get some sleep and some time I’ll work on this class some more
I hope to get it running at 60fps for everyone
In my opinion it isn’t looking bad, but I know that noone would use this class, tho I need it for a project, so I thought I might as well share it
Edit: found it already, didn’t look it up before asking xo
Ok no more questions this time
Time for a major UPDATE
http://twolivesleft.com/Codea/CC/alpha/index.php?v=1353
It now has full power of a color picker, including alpha level selector, works with different sizes, tho I wouldn’t make it to small because of touch handling
Example included which shows 2 different-sized color pickers at work
I hope you enjoy this and that I get some critical feedback on this
any sugestions are welcome
Also, I wanna thank @Andrew_Stacey for his great help in the last major parts of color shading
Quite nice. 23Hz on ipad1: good!
@Jmv38 could you tell me in what circumstances ylu get 23Hz? Like, how many colorpickers are drawn? and how many rings/squares are you touching?
Not much to say really. Just ran the program you posted. There are 2 color pickers showing, one big and one small, and your fps counter says 23. But what is the problem? I think 23 is very good already. You could make it 60hz by putting everything in a single image and sprite it, but is it really worth the effort?
@Jmv38 ok thanks, Idk, I just always want my classes to run as good as they ever could be, but for now I’ll leave it like this, gonna work on my sprite picker first