我如何在1997年进行实时比赛

我想分享一下我几乎在互联网时代之前尝试“自行完成”“ 3D图形引擎”的记忆(当然,好像他已经去过某个地方了,但实际上我没有一个)。 没有美国可以被发现,革命也没有发生,但是有很多的努力,折磨和狂热。 多年以来,许多事件的记忆被抹去,细节消失,印象褪色-经历了无数次旅行,软盘盒丢失了,描述的事件中没有文物。

背景知识


过去四年的学习是在鄂木斯克体育学校进行的,在那里,一个孩子(体育和咒骂除外)被教以C语言,这种语言与对游戏图形的兴趣相重叠,使我能够自己写点东西,试图实现自己当时在游戏中看到的东西。 使用2D图形已经很难让人感到惊讶,但是Wolf 3D使我停滞了一段时间。 一位资深同志说:“是的,一切都在铁窗上”,这使我得以离开地面。 然后,我意识到可以将Bresenham算法应用于缩放图像列,并且在Wolf3D上开始进行某种模仿。 我一点也不努力去创造一种可玩的游戏(简直太庸俗了!),我喜欢实现图形算法的过程,喜欢您知道如何完成并可以做到的感觉。 在期末考试中,我选择了信息学,并向老师介绍了“理论”部分,这让他们为实际应用感到惊讶。 但是在考试的前一周,我看到了Descent-一款带有纹理的真实3D游戏。 这是不可能的,我知道有3DS,但是在那里制作动画片需要很多时间,然后它飞到我们眼前。

毕业时,我没有像所有正常孩子那样饱满,而是和朋友杜克·努克姆(他也是专栏作家)进行了讨论,我非常喜欢他的幽默和多变。 然后一个人告诉我“看看雷神之锤”。 当我看了kwaku时,我认为它足以承受它,这是不可能的,它是真实的3D图形,没有任何列-我绝对不知道该怎么做。

我精通几何


现在您可以在5分钟内找到任何信息,但是该怎么办? 我有一本关于3D图形的书,但他们根本没有弄清楚这个问题。 在“ Duma”中,所有脸部都以梯形形式在屏幕上打开,通过拉伸列来完成纹理的拉伸。 但是与此同时,我没有注意到非线性是水平出现的事实,而且事实上杜马中的图片并不完全真实。 因此,我错过了牛顿发现的3D图形的主要原理-“ 线性化它” 。 什么将成为所有后续问题和抛出的根源。

由于我们已经知道如何绘制梯形,因此让我们在屏幕上“绘制”每个三角形小平面。 是的,它不能用列来绘制,但是几何形状并不是一件很困难的事情,让我们将来自相机的光线穿过屏幕的每个像素,并找出与面部相交的位置。 这实际上是光线追踪,只有精简版! 任何学生都将在5分钟内写下此公式。 该行的等式:

 vecx=kxsysz0=k vecS

在哪里 xsys这些是屏幕平面上像素的坐标, z0这是从相机到屏幕平面的距离(相机在参考系统的零位置), k-参数
平面方程:

 vecn vecx=D

其中n是正常值,则很容易找到参数(以及坐标):

k= fracD vecn vecs


好吧,这很容易达到分裂之的境界。 电脑折叠得很好,可以相乘(无非是加法和移位),但是除法...我的Pentium上的除法花了46个时钟周期。 即使320到200,即使仅此而已,那么对于每一帧,您都需要300万小节。 而且我的大麻只有100张,这意味着原则上您的速度不会超过30 fps。 如果分辨率提高了2倍? 7 fps? 但是这位年轻的发烧友并不为难。

好吧,假设我们计算了与人脸的交点,那么我们需要解决两个问题:

  1. 决定是否在此像素中绘制面,或者是否有另一个面重叠
  2. 查找纹理坐标

排序树


当然,我知道Z缓冲区。 但是请相信我,知道Z缓冲区的人们中有99%错误地想象它,就像我错误地想象它一样(会有一个解释)。 无论如何,我都想避免不必要的计算(除法太难了),所以我决定使用另一种技术,请在书中阅读-空间的二进制分区树,它们也是BSP树。 我一直爱树木,按树排序的方法总是让我着迷于它的魔力,这就是它的变化-我连续调试了8个小时,但是我可以!

该方法允许对面孔进行排序(同时,将一些面孔切成多个部分),以便在显示时先绘制“近”面孔,然后绘制远处的面孔。 因此,如果在绘制人脸时看到像素已经被拍摄,那么我们可以安全地移动到下一个像素,解决了顺序问题,仍然需要拉纹理。

墙纸纹理


U,V坐标? 不,我没有听到。 但是请不要怪我,因为当您粘贴墙纸时,您对它们的想法并不相同。 您认为您有墙纸的一个边缘(水平纹理矢量),在这里您有墙纸的另一边缘(垂直纹理矢量),将它们放在墙上! 因此,对于每个脸部,我针对纹理的边缘开始了两个向量,并知道了交点,从而找到了纹理内部的坐标。

我们需要一个情节和效果。


所获得的渲染效果虽然不是很快,但是却能获得! 我能够进行3D图形处理! 但是,我们将呈现什么? 我们需要某种情节,某些模型,我们需要某种声音。

助行器还是传单? 这个助步器走了,不允许感觉到所有3D美,绝对是苍蝇! 将有我们的血统。

我做了一个平台,在上面放了几座建筑物,在上面拉了带有窗户的纹理,做了一个喷泉(看起来很酷)。 我们要拍摄什么? 他们在地震中射钉子,那不是很酷。 由于当时文化学家不知道的某些原因,“螺栓”一词很流行(我需要用锤子敲打),我意识到我们会用螺栓射击-事实证明它们是螺栓-拧入建筑物的螺栓上的槽看起来非常漂亮”。

敌人? 好吧,我无法制作人物模型,我做到了……飞行救护车几乎是立方体的,只是稍微倾斜了挡风玻璃。 但是纹理保存了。

听起来 爆炸声和爆炸声以及我从魔兽世界上摘下来的一架飞行器的叫声,声带开始了声效。卖世界的那个人-我本人听金属,但我为我的父母感到难过,他们在调试时晚上不得不听同样的话。
在Windows 95中,声音没有混合在一起,但是她(这是大学的好处),老师告诉我关于多线程的知识,我在单独的流中编写了混音器-另一个成功(Windows 98将在一年内发布,声音本身会混合在一起,这种秘密技能将变得无用)。

有可能做得更好吗? 我决定重新发现线性化并想到,如果我们准确地找到线条边缘的纹理坐标,并且内部会发疯,将会发生什么? 我尝试过-一切开始工作的速度提高了很多倍,但是建筑物附近开始出现严重的变形-就像在弯曲的镜子里一样。 角度校正-不,我没有听到。
好吧,因为我没有听说过,所以没有任何关系,因此我拒绝了此选项。

故事快结束了


第一年年末,我打算参加一门计算机图形学特别课程,并向老师展示了所有内容。 当他解释纹理坐标和法线的线性插值,照度的近似计算,透视误差的估计及其校正时,我们可能会对他同样感到惊讶,我向他展示了一些确实有效的方法。

在第二年,我尝试根据新知识重做所有内容,但默认年份为98,并且在3D加速器上看到了第二次地震-异常美妙。 那时根本没有钱,加速器就像一艘太空船,出于某种原因,我决定在不久的将来不再使用它。 对图形编程的兴趣开始迅速消失-但是我对处理声音的想法感到兴奋。 但这是另一个故事

PS实际纹理坐标非线性变化,为了速度,它们被线性坐标代替。 但是Z坐标会发生什么,为什么它们在转换过程中会翻转Z? 这个问题的答案由Z缓冲区给出。

Source: https://habr.com/ru/post/zh-CN464045/


All Articles