|
|
最近做Parallax的研究,发现必须要在PS中逐像素进行Eye Vector的归一化运算(Normalize),否则画面计算将不精确,无奈偶是用d3d8的,PS只能用到1.4版本,缺乏rsq、rcp指令的支持,对于插值的Eye Vector实在无法做到Normalization。原PS伪代码如下:
从纹理坐标寄存器得到当前像素EyeVec、Height
Normalize(EyeVec) //此处PS2.0以下无法实现
NewTexCoord = OldTexCoord + EyeVec * Height * Scale * ( 1 - Biass )
我苦思冥想很久,终于得到一个变通办法跳过Normalize,且PS汇编指令比以前还大大减少。我的方法是先在VS中进行Eyevec 的TBN空间变化,然后计算得到EyeVec的模,再在PS中将EyeVec的X、Z坐标除以EyeVec的模,即可得到Normalization的EyeVec的X、Z坐标。关键代码如下:
vs.1.0
.... // r2.xyz存储了未Normalization的TBN空间的EyeVector分量
mov oT1.xyz, r2.xyz // oT1.xyz储存未Normalization的EyeVector
dp3 r2.x, r2, r2
rsq r2.x, r2.x
rcp oT1.w, r2.x // 将EyeVec模存储到oT1.w中
//-------------------------------------------------------------
ps.1.4
.....
texcrd r3.rg, t1_dw.rga // t1.xy存储了EyeVec的X、Z坐标,t1.w存储了EyeVec的模
这样一条PS汇编指令就同时完成了装载EyeVec坐标且Normalize化的工作,比原算法中Normalize指令简化了不少。Interpolated的EyeVec模线性变化,这与每个像素到眼睛的距离是线性变化的一致,所以,这个算法理论上讲是正确的。 |
|