The 2nd solution: Show the value
Very well, with the experiment above, we can know the brief of the var in shader
. But the info is too simple, and it is complicated to use. We want to watch the exact value, we know we can control the whole screen with shader
, so in abstracto we can draw anything to screen include number.
Now let us make the problem simple, assume myVar
is a int and its region is [0,9], then we can get a logic:
if myVar is 1, then draw specified pixels in a specified area with specified color(draw 1);
if myVar is 2, then draw specified pixels in a specified area with specified color(draw 2);
...
if myVar is 9, then draw specified pixels in a specified area with specified color(draw 9);
if myVar is 0, then draw specified pixels in a specified area with specified color(draw 0);
It looks good, now we can make shader
output the 10 number of 1~0
. Continue to make the problem simpler, start with the easiest place, only to draw a number 1
on the screen, the code is below:
float x = vTexCoord.x;
float y = vTexCoord.y;
// debug area
if(x > 0.9 && x < 1.0 && y > 0.9 && y < 1.0) {
// background is white
gl_FragColor = vec4(1,1,1,1);
// draw 1 in a rect
if( x > 0.99 ){
// the right set green
gl_FragColor = vec4(0,1,0,1);
}
}
Ok, it works, now we can add more, for example we can add a judgement with if myVar is number 1
, if it is true
the shader
will draw a green number 1 with white background in this area.
float x = vTexCoord.x;
float y = vTexCoord.y;
// debug area
if(x > 0.9 && x < 1.0 && y > 0.9 && y < 1.0) {
// background is white
gl_FragColor = vec4(1,1,1,1);
// draw 1 in a rect
if( myVar == 1 && x > 0.99 ){
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
One by one, we can draw the number 2~0
with the same method:
float x = vTexCoord.x;
float y = vTexCoord.y;
// debug area
if(x > 0.9 && x < 1.0 && y > 0.9 && y < 1.0) {
// background is white
gl_FragColor = vec4(1,1,1,1);
// draw 1 in a rect
if( myVar == 1 && x > 0.99 ){
// set green
gl_FragColor = vec4(0,1,0,1);
}
if( myVar == 2 && (the coordinate of 2) ){
// set green
gl_FragColor = vec4(0,1,0,1);
}
...
if( myVar == 0 && (the coordinate of 0) ){
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
Optimize the code:
float x = vTexCoord.x;
float y = vTexCoord.y;
// debug area
if(x > 0.9 && x < 1.0 && y > 0.9 && y < 1.0) {
// background is white
gl_FragColor = vec4(1,1,1,1);
// draw 1 in a rect
if(( myVar == 1 && x > 0.99 ) ||
( myVar == 2 && (the coordinate of 2)) ||
...
( myVar == 0 && (the coordinate of 0))
)
{
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
It is ok, change it to a function:
// LED char
void ledChar(int n, float xa,float xb, float ya, float yb){
float x = vTexCoord.x;
float y = vTexCoord.y;
float x1 = xa;
float x2 = xa+xb;
float y1 = ya;
float y2 = ya+yb;
float ox = (x2+x1)/2.0;
float oy = (y2+y1)/2.0;
float dx = (x2-x1)/10.0;
float dy = (y2-y1)/10.0;
float b = (x2-x1)/20.0;
int num = n;
// debug area
if(x >= x1 && x <= x2 && y >= y1 && y <= y2) {
// background is blue
gl_FragColor = vec4(0,0,1,.5);
// draw 1~0 in a rect
if((num==1 && (x > x2-dx)) ||
(num==2 && ((y > y2-dy) || (x > x2-dx && y > oy-dy/2.0) || (y > oy-dy/2.0 && y < oy+dy/2.0) || (x < x1+dx && y < oy+dy/2.0) || (y < y1+dy))) ||
(num==3 && ((y > y2-dy) || (x > x2-dx) || (y > oy-dy/2.0 && y < oy+dy/2.0) || (y < y1+dy))) ||
(num==4 && ((x < x1+dx && y > oy-dy/2.0) ||(x > x2-dx) || (y > oy-dy/2.0 && y < oy+dy/2.0))) ||
(num==5 && ((y > y2-dy) || (x < x1+dx && y > oy-dy/2.0)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx && y <oy-dy/2.0) || (y<y1+dy))) ||
(num==6 && ((y > y2-dy) || (x < x1+dx)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx && y <oy-dy/2.0) || (y<y1+dy))) ||
(num==7 && ((y > y2-dy) || (x > x2-dx))) ||
(num==8 && ((y > y2-dy) || (x < x1+dx)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx) || (y<y1+dy))) ||
(num==9 && ((y > y2-dy) || (x < x1+dx && y > oy-dy/2.0)||(y > oy-dy/2.0 && y < oy+dy/2.0)|| (x>x2-dx) || (y<y1+dy))) ||
(num==0 && ((y > y2-dy) || (x < x1+dx) || (x>x2-dx) || (y<y1+dy)))
)
{
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
}
The whole shader
code is below:
myShader = {
vsBase = [[
// vertex shader
uniform mat4 modelViewProjection;
uniform vec2 uResolution;
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;
}
]],
fsBase = [[
// fragment shader
precision highp float;
uniform lowp sampler2D texture;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void ledChar(int,float,float,float,float);
void main() {
lowp vec4 col = texture2D( texture, vTexCoord ) * vColor;
// default is white
gl_FragColor = vec4(.1,.1,.1,1);
// show 1
ledChar(1, 0.9, 0.1, 0.9, 0.1);
}
// LED char
void ledChar(int n, float xa,float xb, float ya, float yb){
float x = vTexCoord.x;
float y = vTexCoord.y;
float x1 = xa;
float x2 = xa+xb;
float y1 = ya;
float y2 = ya+yb;
float ox = (x2+x1)/2.0;
float oy = (y2+y1)/2.0;
float dx = (x2-x1)/10.0;
float dy = (y2-y1)/10.0;
float b = (x2-x1)/20.0;
int num = n;
// debug area
if(x >= x1 && x <= x2 && y >= y1 && y <= y2) {
// set blue
gl_FragColor = vec4(0.2,0.2,0.8,.5);
// draw number 1~0
if((num==1 && (x > x2-dx)) ||
(num==2 && ((y > y2-dy) || (x > x2-dx && y > oy-dy/2.0) || (y > oy-dy/2.0 && y < oy+dy/2.0) || (x < x1+dx && y < oy+dy/2.0) || (y < y1+dy))) ||
(num==3 && ((y > y2-dy) || (x > x2-dx) || (y > oy-dy/2.0 && y < oy+dy/2.0) || (y < y1+dy))) ||
(num==4 && ((x < x1+dx && y > oy-dy/2.0) ||(x > x2-dx) || (y > oy-dy/2.0 && y < oy+dy/2.0))) ||
(num==5 && ((y > y2-dy) || (x < x1+dx && y > oy-dy/2.0)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx && y <oy-dy/2.0) || (y<y1+dy))) ||
(num==6 && ((y > y2-dy) || (x < x1+dx)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx && y <oy-dy/2.0) || (y<y1+dy))) ||
(num==7 && ((y > y2-dy) || (x > x2-dx))) ||
(num==8 && ((y > y2-dy) || (x < x1+dx)|| (y > oy-dy/2.0 && y < oy+dy/2.0) || (x>x2-dx) || (y<y1+dy))) ||
(num==9 && ((y > y2-dy) || (x < x1+dx && y > oy-dy/2.0)||(y > oy-dy/2.0 && y < oy+dy/2.0)|| (x>x2-dx) || (y<y1+dy))) ||
(num==0 && ((y > y2-dy) || (x < x1+dx) || (x>x2-dx) || (y<y1+dy)))
)
{
// set green
gl_FragColor = vec4(0,1,0,1);
}
}
}
]]
}
In abstracto, with the foundation code above, we can watch the var value in shader
easily, but unfortunately there is a big bug
I have not found the reason: when in one mesh run the function ledChar
twice, it will make the screen messy.
About how to display number font with shader
, I have thought of some other method, one is using vec4
or mat4
to transfer the font data , another is using the texture
. I think the last one will be esaier. I will try these ideas later.
Btw, when I have had these ideas, I thought maybe others will have the same idea, so I searched for the keywords shader debug
, then I found in StackOverflow
some programers were talking about it, one person give the answer similar with the first solution of mine, and one person gave a solution full of imagination–visualization. It looks very interesting. The article linke, I will try the visualization later.