基于x-scan算法实现的z-buffer染色。c#语言,.net core framework 3.1运行。
模型是读取3D Max的obj模型。
x-scan算法实现:
cs
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算法:
cs
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光照渲染(使用法向量):