I've to rasterize a line taking into account not only the background color of the screen, which is white, but also the color of other objects in the scene. In my case, I've just another object, a sphere, which is actually visualized using a ray tracing technique.
So far the code that I have seems only to consider the white background color of the screen and not also the color of the sphere.
So here's the code:
// ray tracing of the sphere
// here we initialize the z-buffer's elements to -1.0 zBuffer that you find below
...
//
// rasterize a line
//
// line from p1 to p2 in LOCAL coordinates
Point3d p1 (-1.0, 0.0, 0.0);
Point3d p2 ( 1.0, 0.0, 0.0);
// transformations...
Matrix4d S = Matrix4d::scaling (5.0, 1.0, 1.0);
Matrix4d R1 = Matrix4d::rotation (0.5,'z');
Matrix4d R2 = Matrix4d::rotation (tau,'x');
Matrix4d T = Matrix4d::translation (0.0, 0.0, 8.0);
Matrix4d M = T*R2*R1*S;
p1 = M*p1;
p2 = M*p2;
// screen coordinates
double x1 = ( X + p1.x()/p1.z() ) / s - 0.5;
double y1 = ( Y - p1.y()/p1.z() ) / s - 0.5;
double x2 = ( X + p2.x()/p2.z() ) / s - 0.5;
double y2 = ( Y - p2.y()/p2.z() ) / s - 0.5;
//
// line rasterization algorithm with anti-aliasing and z-test
// (for lines with slope between -1 and 1)
//
int x = round(x1);
int y = round(y1);
double I0 = 1.0;
double m = (y2-y1) / (x2-x1);
bool up = true;
if (y2 < y1) {
m = -m;
I0 = 0.0;
up = false;
}
int nextY;
double z;
for ( ; x<=x2; x++) {
if (up)
nextY = y+1;
else
nextY = y-1;
// barycentric coordinates of the current point: (1-lambda, lambda),
// i.e.: x = (1-lambda) x1 + lambda x2
double lambda = (x-x1) / (x2-x1);
// perspectively correct linear interpolation of z-values
z = p1.z()*p2.z() / ( (1.0-lambda)*p2.z() + lambda*p1.z() );
if ( (zBuffer[x+y*w] < 0) || z < zBuffer[x+y*w] ) {
int I = (int) 255*I0;
image->setPixel( x, y, qRgb( 255-I, 255, 255-I ) );
image->setPixel( x, nextY, qRgb( I, 255, I ) );
}
if (m > I0) {
y = nextY;
I0 += 1.0;
}
I0 -= m;
}
// repaint canvas
repaint();
}
Now the output is not as expected, because one of the pixels of the lines on the sphere is coloured white. Of course we notice this immediately! The idea is to make a smoother line that considers not only the colour of the background but also the colour of the sphere.
I thought I need to interpolate colours, but I'm not sure which ones and how to do it. I know that the basic idea of interpolation is to find an intermediate colour between two (or more) colours ($C_1, C_2$) using a formula as follows:
$$(1 - \alpha) C_1 + \alpha * C_2$$
Now the problem is that I don't know what's exactly $\alpha$ and which colours would be $C_1$ and $C_2$. I thought $\alpha$ could be the lambda
variable in the code above, but this is more than a guess than a conclusion after a logical reasoning.
Moreover, I guessed that the colours $C_1$ and $C_2$ are respectively the color of the pixel before the rasterization of the line (i.e. in the ray tracing part), which can also be the color of the sphere, if that pixel is covered by the sphere, or the background color, i.e. white in my case.
Any help is appreciated.
To give you an idea, this is the wrong output:
and this should be the correct one:
Note (if you zoom in) that the line in the first picture is not that smooth over the sphere, because one of the pixels (at least) is colored for the background color white.