基于x-scan算法实现的z-buffer染色。c#语言,.net core framework 3.1运行。
模型是读取3D Max的obj模型。
x-scan算法实现:
public List<Vertex3> xscan() {List<Vertex3> results = new List<Vertex3>();SurfaceFormula formula = getFormula();Box rect = getBound();for (int y = rect.IntMinY; y <= rect.IntMaxY; y++) {List<double> set = new List<double>();for (int i = 0; i < this.vectex.Length; i++) {Vertex3 v1 = this.vectex[i];Vertex3 v2 = this.vectex[(i + 1) % vectex.Length];if (v1.IntY == v2.IntY || y < Math.Min(v1.Y, v2.Y) || y > Math.Max(v1.Y,v2.Y ))continue;LineFormula formula1 = new LineFormula(v1, v2);Double? x = formula1.getX(y);if (x != null) {bool e = false;foreach (double d in set) if (Math.Abs(d - x.Value) < 0.005)e = true;if (e == false)set.Add(x.Value);}}if (set.Count > 0 && set.Count % 2 == 0) {set.Sort();for (int i=0; i<set.Count-1; i++)for (int x = (int)set[i]; x <= (int) set[i + 1]; x++)results.Add(new Vertex3(x, y, formula.getZ(x, y)));}}return results;
}
z-buffer算法:
private List<Vertex3RGB> zbuffer(Model.Model model, Bitmap canvas) {int?[,] deep = new int?[canvas.Width, canvas.Height];Vertex3RGB[,] pixels = new Vertex3RGB[canvas.Width, canvas.Height];for (int i = 0; i < canvas.Width; i++)for (int j = 0; j < canvas.Height; j++)deep[i, j] = null;foreach (Surface surface in model.Surface){Vertex3 nv = surface.NormalVector();if (this.normalvector && nv.Z <= 0)continue;List<Vertex3> results = surface.xscan();foreach (Vertex3 v in results){if (v.IntX < 0 || v.IntX >= canvas.Width)continue;if (v.IntY < 0 || v.IntY >= canvas.Height)continue;if (deep[v.IntX, v.IntY] == null || v.IntZ > deep[v.IntX, v.IntY]){deep[v.IntX, v.IntY] = v.IntZ;pixels[v.IntX, v.IntY] = new Vertex3RGB(v, brushColor.ToArgb(), nv);}}}List<Vertex3RGB> r = new List<Vertex3RGB>();for (int i = 0; i < pixels.GetLength(0); i++)for (int j = 0; j < pixels.GetLength(1); j++)if (pixels[i, j] != null)r.Add(pixels[i, j]);return r;
}
原始模型如下(使用法相量):
基于x-scan的zbuffer算法(使用法向量):
基于x-scan光照渲染(使用法向量):