我正在开发一款带有软件渲染器的游戏,以获得最精确的PS1外观。在研究PS1图形/渲染系统工作原理 - 导致顶点晃动等问题时,我发现了一些关于他们如何进行除法的文档。以下是相关链接:http://problemkaputt.de/psx-spx.htm#gteoverview(请参见“GTE除法不准确性”部分)。
相关代码:
相关代码:
if (H < SZ3*2) then ;check if overflow
z = count_leading_zeroes(SZ3) ;z=0..0Fh (for 16bit SZ3)
n = (H SHL z) ;n=0..7FFF8000h
d = (SZ3 SHL z) ;d=8000h..FFFFh
u = unr_table[(d-7FC0h) SHR 7] + 101h ;u=200h..101h
d = ((2000080h - (d * u)) SHR 8) ;d=10000h..0FF01h
d = ((0000080h + (d * u)) SHR 8) ;d=20000h..10000h
n = min(1FFFFh, (((n*d) + 8000h) SHR 16)) ;n=0..1FFFFh
else n = 1FFFFh, FLAG.Bit17=1, FLAG.Bit31=1 ;n=1FFFFh plus overflow flag
我很难理解这是如何工作的,'unr'表是什么?我们为什么要移位? 如果有人能够更详细地解释一下这个东西是如何实现除法的,那就太好了。
unr_table
是一个[1,2)中数字的倒数表。请注意常量101h
的添加:与表项配合使用,这形成了一个9位固定点近似值,其中0x100
相当于 0.5。我不确定为什么他们添加了101h
而不是我所期望的值100h
;额外的加1可能代表对以下固定点数学的截断性质进行补偿的调整因素。 - njuffa