我正在尝试使用扫描线方法在3D中栅格化三个三角形。但在处理完所有多边形之后,相邻多边形之间的边缘质量非常差。 渲染图片:
对于栅格化,我使用带有活动边缘表的扫描线方法。 每条扫描线仅与两条边相交。我存储交叉点(x,y,z)然后画线。 对于计算交叉点,我使用此类并为每个新扫描线调用活动边缘的update()方法:
public class Edge {
private Point3D start, end;
public double dx = 0, dy = 0, dzX = 0, dzY = 0, currX = 0, currY = 0, currZx = 0, currZy = 0;
private double calcCurrX = 0, calcCurrY = 0, calcCurrZx = 0, calcCurrZy = 0;
private double lx = 0, ly = 0,lz = 0;
public Edge(Point3D start, Point3D end) {
this.start = new Point3D(start);
this.end = new Point3D(end);
reset();
}
public void update(){
calcCurrX += dx;
calcCurrZx += dzX;//for drawing scanline slices
calcCurrZy += dzY;//for use with scanline
calcCurrY += dy;
currX = calcCurrX + 0.5;
currY = calcCurrY + 0.5;
currZx = calcCurrZx + 0.5;
currZy = calcCurrZy + 0.5;
}
public Point3D getStart() {
return start;
}
public void setStart(Point3D start) {
this.start = start;
reset();
}
public Point3D getEnd() {
return end;
}
public void setEnd(Point3D end) {
this.end = end;
reset();
}
public void reset(){
lx = this.end.x - this.start.x;
ly = this.end.y - this.start.y;
lz = this.end.z - this.start.z;
dx = lx / ly;
dy = ly / ly;
dzX = lz / lx;
dzY = lz / ly;
calcCurrX = this.start.x;// + 0.5 * Math.signum(dx);
calcCurrZx = this.start.z;// + 0.5 * Math.signum(dzX);
calcCurrZy = this.start.z;// + 0.5 * Math.signum(dzY);
calcCurrY = this.start.y;// + 0.5 * Math.signum(dy);
currX = calcCurrX + 0.5;
currY = calcCurrY + 0.5;
currZx = calcCurrZx + 0.5;
currZy = calcCurrZy + 0.5;
}}
这是循环遍历所有扫描线的代码,计算交叉点并绘制线条:
int scanlineEnd = (int) edges[0].getEnd().y;
for (Edge edge : edges) {
if (scanlineEnd < (int) edge.getEnd().y)
scanlineEnd = (int) edge.getEnd().y;
}
scanlineEnd = Math.min(scanlineEnd, zBuffer[0].length);
int scanline = (int) edges[0].getStart().y;
ArrayList<Edge> activeEdges = computeActiveEdges(edges, scanline);
while (scanline < scanlineEnd){
if(activeEdges.isEmpty()) break;
if(scanline == (int) activeEdges.get(0).getEnd().y || scanline == (int) activeEdges.get(1).getEnd().y){
activeEdges = computeActiveEdges(edges, scanline);
}
if (scanline < 0){
activeEdges.get(0).update();
activeEdges.get(1).update();
scanline++;
continue;
}
Point3D start = new Point3D((int) activeEdges.get(0).currX, (int) activeEdges.get(0).currY, (int) activeEdges.get(0).currZy);
Point3D end = new Point3D((int) activeEdges.get(1).currX, (int) activeEdges.get(1).currY, (int) activeEdges.get(1).currZy);
if (end.x < start.x) {
Point3D temp = start;
start = end;
end = temp;
}
double dzX = 0;
if ((int) start.x != (int) end.x) {
dzX = (end.z - start.z) / (end.x - start.x);
}
int y = (int) start.y;
double currZx = start.z;
//int zMin = findMinZ(coordinatesT), zMax = findMaxZ(coordinatesT);
for (int x = (int) start.x; x <= (int) end.x; x++) {
if (x >= 0 && x < zBuffer.length) {
if (zBuffer[x][y] < (int) currZx) {
image.setRGB(x, y, color.getRGB());
zBuffer[x][y] = (int) (currZx);
}
}
currZx += dzX; //here i compute z for line that connects two intersection points. I think i'm doing it incorrect
}
activeEdges.get(0).update();
activeEdges.get(1).update();
scanline++;
}
如何在多边形之间获得更好的边缘质量?