在光线投射引擎中绘制纹理

Drawing textures in raycasting engine

我试图在汇编中制作光线投射引擎,但我遇到了问题。 绘图纹理似乎无法正常工作。

这是它的样子:

在查找与墙壁碰撞的 for 循环中,如果发现碰撞,我将 x 或 y 的浮点部分用于计算要在纹理上绘制的位置。

我试过调试,我发现问题可能是最终纹理 x 有几次是相同的,但是你可以在图片中看到从侧面看它几乎可以正常工作,所以我不认为这是问题所在。

想要的结果只是正确绘制纹理而没有这些扭曲。

我认为问题出在代码的某处here:

mov ebx,WINDOW_HEIGHT / 2
sub ebx,eax
mov eax,height

mov screenypos,ebx

dec typeofwall

movss xmm0,floatingpoint
mulss xmm0,FP4(64.0f)

mov eax,typeofwall
cvtsi2ss xmm1,eax
mulss xmm1,FP4(64.0f)

addss xmm0,xmm1

movss tempvarr,xmm0
invoke FLOOR,tempvarr
cvtss2si eax, xmm0
mov finaltexturex,eax

;invoke 

BUILDRECT,screenpos,screenypos,linewidth,height,hdc,localbrush

invoke DrawImage,hdc,wolftextures,screenpos,screenypos,finaltexturex,0,linewidth,64,linewidth,height

尝试首先为每一列打印 "hit" 坐标,以及您将使用哪个坐标进行纹理化(请记住,您必须使用 map_x 或 map_y纹理轴,取决于光线首先与墙壁相交的网格线以及从哪个方向。

现在我有了其他想法...您甚至在使用字节映射[16][16];或者类似的墙壁定义(Wolf3D 2.5D 光线投射),或者这个半多边形地图系统,计算与线段的交点(DOOM 2.5D 透视 BSP 2D 边缘抽屉(在原始 DOOM 中根本不是光线投射!))?

如果您正在使用 Wolf3D 光线投射器,请注意您必须大量清理交集公式,并明智地决定您在何时进行计算的哪一部分,因为错误的计算顺序可能会迅速累积相当大的精度误差,导致墙壁出现 "holes" 等怪癖(当对于单个像素列时,您错过了与墙壁的交点)等

对于浮点数,您更容易受到意想不到的精度问题的影响,因为以位编码的精度按指数快速变化(因此在 0.0,0.0 坐标附近比地图上的 1e6,1e6 坐标具有更好的精度).

正确完成后,它应该看起来像 "easy" 东西。我曾经在一个下午用 Pascal 制作了快速而肮脏的版本(作为一个正在尝试学习 Pascal 的朋友的例子)。但它也很容易出错(例如贝塞斯达的第一个上古卷轴 "ARENA" 有可怕的交叉计算,墙壁 y 位置参差不齐)。而且通常不正确的计算不仅精度较差,而且几乎总是涉及更多的计算操作,因此速度较慢。

用纸和铅笔把它画下来(地图网格,投影平面,用你有的值围绕三角测量,看看你如何最小化每个屏幕列 x 的设置阶段,因为最少的计算量 = 最高精度).

(答案很笼统,因为几乎没有代码可以检查(发布的代码对我来说看起来不错))。