-
Gouraud Shading problem
Hi,
I've written a single module to rasterize and shade a triangle. Rasterization works fine but I get some errors when I try to bilinearly interpolate between the vertices.
The module is too big and I rather not post it (unless of course one of you wants me to).
Assuming that the vertices are in an anticlockwise arrangement:
Get length of left edge
Get length of right edge
For every scanline
Interpolate between vertex v0 and v1
Interpolate between vertex v0 and v2
for every pixel in current scaline
Interpolate between values of previous two interpolations
Colour the pixel
That is basically how I did it. I tried but failed in finding any coded examples that weren't heavily optimized. ( usually heavy optimizations affect clarity i.e. inlined assembly modules)
Any help would be appreciated( tutorials, code, personal opinions)
Duetti
-
-
I removed the code fragment
-
I found the errors in the code fragment above, the most serious of which was that I forgot to call sqrt() for the left and right edges.
-
Crap, I *might've* been able to help because I've dabbled with softare rasterization crap. Could you send me the code anyway? I'm interested in seeing it.
Congrats on fixing the problem.
-
I've posted this a million times here but....
Code:
//No assembly
double BI(double v1,double v2,double v3,double v4,double f1,double f2)
{
double val1=v1+f1*(v2-v1);
double val2=v3+f1*(v4-v3);
return (val1+f2*(val2-val1));
}
//Inline assembly
double BI(double v1,double v2,double v3,double v4,double f1,double f2)
}
double val1=0.0,val2=0.0,rval=0.0;
asm {
fld [v2]
fsub [v1]
fmul [f1]
fadd [v1]
fstp [val1]
fld [v4]
fsub [v3]
fmul [f1]
fadd [v3]
fstp [val2]
fld [val2]
fsub [val1]
fmul [f2]
fadd [val1]
fstp [rval]
}
return rval;
}
But to do what you want only requires 2 separate linear interpolations rather than one bilinear. Essentially you are doing a bilinear interpolation but its easier to do two singles which is:
interpolated_value=v1+f1*(v2-v1);
where f1 is the interpolant.
Code:
//Scan conversion
double m=(x2-x1)/(y2-y1);
double cm=(c2-c1)/y2-y1);
int x=x1;
int c=c1;
for (double y=y1;y<y2;y+=1.0)
{
edge[(int)y].x=x;
edge[(int)y].c=c;
x+=m;
c+=cm;
}
//Drawing from left edge to right edge
double x1=(double)left_edge[y].x;
double x2=(double)right_edge[y].x;
double c1=(double)left_edge[y].c;
double c2=(double)right_edge[y].c;
cm=(c2-c1)/(x2-x1);
double c=(double)c1;
for (double x=x1;x<x2;x++)
{
putpixel((int)x,(int)y,(int)c);
c+=cm;
}
So it is a type of bilinear interpolation since you first interpolate on y and then x. The data type conversions might be wrong in my examples but I'm sure you can get it right. Using < and > with doubles is not a good idea.
-
Apologies for the delay Silvercord. I tried to fix a few problems with the module. It's not error free but it works fine for triangles with flat bottom or top. Where shall I send the code?
-
What about this thread geek?
:-)
Duetti
-
Stop bumping threads...see rules in the link on my sig