hlsl`dst`指令有什么用?

问题描述 投票:0回答:1

文档

dst
“计算距离向量”:

dest = dst( src0, src1 ) ;

它说,

第一个源操作数 (src0) 假定为向量(忽略、d*d、d*d、忽略),第二个源操作数 (src1) 假设为向量(忽略、1/d、忽略、1) /d)。目的地 (dest) 是结果向量 (1, d, d*d, 1/d)。
//Code
dest.x = 1;
dest.y = src0.y * src1.y;
dest.z = src0.z;
dest.w = src1.w;

这到底是什么意思?为什么要使用它?

hlsl
1个回答
0
投票

在计算机图形学中,计算向量的长度是一项非常常见的工作 - 例如计算两点之间的距离。鉴于您已经计算了点之间的差异,距离可以计算为:

d = sqrt(x*x + y*y + z*z);

不幸的是,计算一个数的根是非常昂贵的;事实上,目前已知最快的方法是首先计算根的,然后计算根本身,如下所示:

// invsqrt(x) := 1/sqrt(x)

dSqr = x*x + y*y + z*z;
dInv = invsqrt(d);
d = 1/dInv;

请注意,最后一行可以替换为:

d = dSqr*dInv;

实际上,这可能确实更有效一点,因为除法往往比乘法更昂贵。

现在,通常情况下,在远处运行的部分“下游”代码可能需要的不是在

d
本身上运行,而是在
d*d
上运行(例如,将其插入到进一步的毕达哥拉斯式计算中),或者
 1/d
(例如在雾状着色器中),甚至
1/(d*d)
(例如在照明计算中)。

通过将最终结果和中间值传递给下游代码,可以优化此类计算,或者至少更有效地实现此类计算;因此,您可能决定传递一整批基于距离的值 - 这可能就是微软所说的“距离向量”的意思:

d
d*d
1/d

现在至于为什么该向量中还有一个

1
,我不确定,但它导致了一个简洁的属性,即该向量包含从
d
pow(d,-1)
pow(d,2)
的完整幂集(虽然有点混乱)

dst
指令似乎被设计为执行组装这样一个距离向量的最后一步:首先在一个寄存器中计算距离的平方,然后在另一个寄存器中计算距离的倒数之后,
dst
指令将把这些值一起放入一个寄存器中,一路计算乘积来计算实际距离。

至于为什么输入寄存器需要在每个组件中“呈现”输入操作数,我想这是为了可以优化实现指令的微代码(实际上这可能是在中包含

1
的真正原因)那里):请注意
dst
运算实际上是两个操作数的逐分量乘法,只不过每个源操作数的两个分量被
1
替换:

dest = (1, src0.y, src0.z, 1) * (1, src1.y, 1, src1.w);

所以:这就是

dst
指令在处理距离时的用处,微软所说的“距离向量”可能意味着什么,以及该指令的一些奇怪之处可能有其根源(双关语)。

© www.soinside.com 2019 - 2024. All rights reserved.