In the previous post a colored cube with a fader effect has been set. However there was a spot of black pixels in one of the corner of the cube. This post tries to show why it happens and how to fix it to see the cube in full color.
Let’s start from the fragment shader to see how the color is assigned to a pixel
1#version 330
2
3out vec4 outColor;
4in vec3 posObj;
5uniform float uTime;
6uniform float uTimeFreq;
7
8void main() {
9 outColor = vec4(posObj * abs(sin(uTime * uTimeFreq)), 1);
10}and focus on the first part of line 9 outColor = vec4(posObj ...)
posObj cames from the vertex shader, is a vec3 (line 4) which contains, for each coordinate, a value in the range [-0.5, 0.5] and is marked with the storage qualifier in.
outColor is the pixel color value and is a vec4 because it specify the color with R,G,B (red, green, blue) values and a further value in the range [0-1] that set the pixel transparency (the alpha channel). In the line the last value 1 means full opaque, while 0 is full transparency and any value between 0 and 1 results in a blend between the pixel value and the rasterized pixel just behind the one being rasterized.
Assigning posObj to the vertex color means to set the RED value as the value of the X coordinate, the GREEN value as value of the Y coordinate and the BLUE value to the Z coordinate value.
Let’s use the debugging features of SHADERed to see, for a particular pixel picked on the final rendered image, what is the value of the posObj value

In the screenshot you can see that at line 8 there is a breakpoint where the fragment program execution must stop. Then the rendering has been paused (with the pause button) and the point marked as 1 has been clicked.
The Pixel Inspect window on the right (2) shows the pixel value, but the most interesting part is the value of the posObj variable (3).
The debugger shows the value -0.409 -0.074 -0.500 because this is the position of the 3D coordinate of the cube corresponding to the that pixel values.
Where does the value -0.409 -0.074 -0.500 come from ? As previously said the value for each coordinate range from from -0.5 to -0.5. Each vertex of the cube can have only the value -0.5 or 0.5, since there are 3 vertices, the combination gives 8 values.
Let’s start from the Z coordinate. In the pixel Inspect windows there are the coordinates of the triangle with vertices -0.50, 0.50, -0.50 , 0.50, 0.50, -0.50 and -0.50, -0.50, -0.50 . The Z coordinate is the same for all three vertices, so this is the triangle in the face, formed by two triangles, that goes towards the “viewer” in the right coordinate system (as briefly discussed in the previous post), so it is natural that posObj has the Z coordinate equal to -0.500.
The X and Y values are instead interpolated among the 3 different vertices values of the triangles.
The X coordinate takes a value interpolated between the X coordinate Vertex 1 and Vertex 0, which is, respectively, 0.5 and -0.5. The pixel value in object is nearer to vertex 0, so a value near -0.5 is expected and as a matter of fact its value is -0.409.
The same reasoning is valid for the Y coordinate, -0.074 , interpolated between Vertex 0 and Vertex 2; it is halfway between them but nearer to Vertex 2 with the result of -0.074.
The negative values in the pixel value are clipped to 0 and that’s why every pixel fragment with all negative coordinates is completely black, which is the color with RGB values (0,0,0)
I hope now its' clearer why there are two faces of the cube where a quarter of each face is completely black.
How can we fix it ?
It is possible to take always a positive value from posObj by using abs
1#version 330
2
3out vec4 outColor;
4in vec3 posObj;
5uniform float uTime;
6uniform float uTimeFreq;
7
8void main() {
9 outColor = vec4(abs(posObj) * abs(sin(uTime * uTimeFreq)), 1);
10}resulting in a simmetric colorisation of the cube
![]()
but to see the whole range of colors it is better to pass the posObj values in the range [0,1] instead of [-0.5, 0.5] and to do that the vertex shader must be changed to add 0.5 to the output variable
1#version 330
2
3uniform mat4 matVP;
4uniform mat4 matGeo;
5
6layout (location = 0) in vec3 pos;
7out vec3 posObj;
8
9void main() {
10 gl_Position = matVP * matGeo * vec4(pos, 1);
11 posObj = pos + 0.5;
12}The video shows a brighter version of the fading colored cube:
The next post will give you a brief explanation on how the animation is produced.