[TinyRenderer] Lesson 1 布兰森汉姆绘制线算法

本文详细介绍了优化Bresenham线算法的过程,从初步实现到逐步消除性能瓶颈,包括代码优化和浮点运算的替代方案。通过分析和测试,展示了如何减少不必要的像素设置和提高渲染效率,最终实现线框渲染的高效实现。

翻译

布兰森汉姆绘制线算法

1 第一次尝试

第一课的目标是渲染金属丝网。要做到这一点,我们应该学习如何绘制线段。我们可以简单地读懂Bresenham的行算法,但是让我们自己写代码。在(x0, y0)点和(x1, y1)点之间绘制线段的最简单代码是什么样子的?
显然,是这样的:

void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) { 
    for (float t=0.; t<1.; t+=.01) { 
        int x = x0 + (x1-x0)*t; 
        int y = y0 + (y1-y0)*t; 
        image.set(x, y, color); 
    } 
}

在这里插入图片描述

可用代码片段here

2 第二次尝试

这段代码的问题(除了效率低下)是选择常数,我取它等于.01。
如果取它为.1,线段就会像这样
在这里插入图片描述
我们可以很容易地找到必要的步骤:它就是要绘制的像素数。
最简单的(但错误的)代码看起来像以下:

void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) { 
    for (int x=x0; x<=x1; x++) { 
        float t = (x-x0)/(float)(x1-x0); 
        int y = y0*(1.-t) + y1*t; 
        image.set(x, y, color); 
    } 
}

注意!
在我的学生的代码中,第一个错误的来源是整数除法,比如’ (x-x0)/(x1-x0) '。
然后,如果我们尝试用这段代码绘制以下线条:

line(13, 20, 80, 40, image, white); 
line(20, 13, 40, 80, image, red); 
line(80, 40, 13, 20, image, red);

在这里插入图片描述

原来一条线是好的,第二条是有孔的,第三条线根本就没有。
注意,第一行和第三行(在代码中)以不同的颜色和不同的方向绘制了同一条线(源点和目标点翻转了)。
我们已经看过白色的了,画得很好。
我希望把白线的颜色改成红色,但是我做不到。
这是对对称性的测试:绘制线段的结果不应该依赖于点的顺序:(a,b)线段应该与(b,a)线段完全相同。

3 第三次尝试

我们通过交换点来修复缺失的红线,使x0总是小于x1。

在其中一个线段上有洞,这是由于它的高度大于宽度。
我的学生经常提出以下解决办法:

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值