返回介绍

绘制线段和三角形来获得线框渲染效果​

发布于 2025-02-18 12:46:45 字数 3075 浏览 0 评论 0 收藏 0

现在我们已经通过前面的教程 编写相机、网格和设备对象的核心逻辑 建立了 3D 引擎的核心,我们可以对渲染工作做一些增强了。下一步我们再连接点来绘制一些线条来组成一个线框渲染效果。

在本章教程中,你将学习如何绘制线条、什么是面(Face) 以及用 Bresenham 算法得到一些三角形。

可喜的是,最后你就能知道如何写出非常酷的东西了。

点我运行

大赞!我们的 3D 旋转立方体真正展示在了我们的屏幕上!首先使用基本算法画出两个点之间的线

让我们来先写一个简单的算法来绘制 2 个顶点之间的线,我们将用以下逻辑:

  • 如果 2 点之间的距离小于 2 个像素,什么也不做
  • 否则,我们计算两点之间的中心点 (point0 坐标 + (point1 坐标 - point0 坐标) / 2)
  • 我们在屏幕上将这个点绘制出来
  • 我们使用递归的方式在 point0&中心点之间以及中心点与 point1 之间绘制点

下面是示例代码:

【译者注:C#代码】

public void DrawLine(Vector2 point0, Vector2 point1)
{
  var dist = (point1 - point0).Length();

  // 如果两点间的距离小于 2,什么都不做
  if (dist < 2)
    return;

  // 查找两点间的中心点
  Vector2 middlePoint = point0 + (point1 - point0)/2;
  // 绘制这个点到屏幕上
  DrawPoint(middlePoint);
  // 我们使用递归的方式在 point0&中心点之间以及中心点与 point1 之间绘制点
  DrawLine(point0, middlePoint);
  DrawLine(middlePoint, point1);
}

【译者注:TypeScript 代码】

public drawLine(point0: BABYLON.Vector2, point1: BABYLON.Vector2): void {
  var dist = point1.subtract(point0).length();

  // 如果两点间的距离小于 2,什么都不做
  if(dist < 2)
    return;

  // 查找两点间的中心点
  var middlePoint = point0.add((point1.subtract(point0)).scale(0.5));
  // 绘制这个点到屏幕上
  this.drawPoint(middlePoint);
  // 我们使用递归的方式在 point0&中心点之间以及中心点与 point1 之间绘制点
  this.drawLine(point0, middlePoint);
  this.drawLine(middlePoint, point1);
}

【译者注:JavaScript 代码】

Device.prototype.drawLine = function (point0, point1) {
  var dist = point1.subtract(point0).length();

  // 如果两点间的距离小于 2,什么都不做
  if (dist < 2) {
    return;
  }

  // 查找两点间的中心点
  var middlePoint = point0.add((point1.subtract(point0)).scale(0.5));
  // 绘制这个点到屏幕上
  this.drawPoint(middlePoint);
  // 我们使用递归的方式在 point0&中心点之间以及中心点与 point1 之间绘制点
  this.drawLine(point0, middlePoint);
  this.drawLine(middlePoint, point1);
};

你需要更新渲染循环处理函数来使用这个新的代码片段:

【译者注:C#代码】

for (var i = 0; i < mesh.Vertices.Length - 1; i++)
{
  var point0 = Project(mesh.Vertices[i], transformMatrix);
  var point1 = Project(mesh.Vertices[i + 1], transformMatrix);
  DrawLine(point0, point1);
}

【译者注:TypeScript 代码】

for (var i = 0; i < cMesh.Vertices.length -1; i++){
  var point0 = this.project(cMesh.Vertices[i], transformMatrix);
  var point1 = this.project(cMesh.Vertices[i + 1], transformMatrix);
  this.drawLine(point0, point1);
}

【译者注:JavaScript 代码】

for (var i = 0; i < cMesh.Vertices.length -1; i++){
  var point0 = this.project(cMesh.Vertices[i], transformMatrix);
  var point1 = this.project(cMesh.Vertices[i + 1], transformMatrix);
  this.drawLine(point0, point1);
}

你现在应该得到这样的效果:

点击运行

我知道这看起来很奇怪,但这是预期的行为。它能帮助你了解如何显示 3D 网格。为了有一个更好的渲染效果,需要了解另一个概念。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文