网上资料多的要命最后还是看的有点混乱挣扎了几天似乎依然存在问题。。下面是我的理解。。请高手指点。。先多谢了!!
凹凸纹理 所含的信息就是每个像素的高度值,首先可以通过“任意一个像素点”的“上下左右”4个像素点分别求得“U方向上的高度差”记作“Du”,和“V方向上的高度差”记作“Dv”,(“高度差”也正好是这个像素点的在“垂直于‘UV面’的那个坐标轴(记为Z轴) 方向上的偏移”),那么这个“像素点的局部坐标系”的“U轴”就可以用“纹理坐标系”里的一个vector来表示,即vector3(1,0,Du),同理“像素点局部坐标系”的“V轴”就是vector3(0,1,Dv),然后叉乘得到“像素点局部坐标系”的“Z轴”,也就得到了此像素点的法线了,然后shader时进行“逐像素”的光照计算,通过凹凸纹理实现法线纹理。
——到此如果有错误,敬请指点。。感激不尽!!
但是对比 凹凸纹理 与 法线纹理,首先不是同一时期的技术,其次 凹凸纹理 有句描述是“对下层纹理进行干扰”。才发觉 凹凸纹理 的“初衷”根本不是 法线贴图 而只是对下一stage纹理混合时uv寻址时进行uv干扰,也正好是公式:
                 vector2(Du`, Dv`) == vector2(Du, Dv)*matrix(M00, M10)
                                                            (M01, M11)
                                   ==vector2(Du*M01 + Dv*M11, Du*M00 +Dv*M10);
                 Du` ==Du*M01 + Dv*M11; Dv` ==Du*M00 +Dv*M10;

                 (D好像是delta的意思吧)
然后,下层的坐标本来在VertexBuffer中,设为vector2(U1,V1),现在出现干扰,在固定管线渲染时应该就成了vector2(U1+Du`, V1+Dv`),然后使用这个 纹理坐标 进行这一层的纹理寻址,最后出现的效果就是,使用 凹凸纹理 后会使得下一层纹理 根据凹凸纹理信息 产生褶皱感(比如某些地方的纹理被压缩,其它一些地方的纹理被拉伸等)。以上是我的个人理解,不知是否正确,如有错误,请高手不吝赐教!!!

解决方案 »

  1.   

    更正。。 凹凸纹理 存放的就是Du和Dv的高度差值了另外有点疑问:文档上说 纹理坐标扰动Dv\Du或Dv`\Du`的范围介于-1~+1之间怎么理解?
    明明sample里如下这样计算的啊
    (这里是使用高度图,生成BumpTexture时)
    LONG v01;//右边像素点
    LONG v10;//下边像素点
    LONG vM1;//左边像素点
    LONG v1M;//上边像素点
    LONG iDu =vM1-v01;
    LONG iDv =v1M-v10;
      

  2.   

    搞定了,过来分享下
    最终Dv`和Du`将被由[0,255]区间转换为[-1,+1]区间,Dv和Du在计算时一直使用的是[0,255]区间!
    Du和Dv经过2x2变换矩阵最终生成了Du`和Dv`,然后Du`和Dv`再变换到区间[-1,+1]
    Du`和Dv`的区间变换方式如下:
    0->-1, 255->+1
    128->0
    64->-0.5 192->0.5
    如果最终计算得到的Du`和Dv`的值大于255,则按其余数来进行坐标干扰,当然应该理解成很多张纹理图被平铺在一起,然后进行寻址的,这样就不存在255(或说+1)这个上限了
      

  3.   

    最后再补充一点D3D Graphic的文档
    输入到像素着色器的颜色值被认为是经过透视校正的,但并非所有硬件都能保证这一点。寻址处理器根据纹理坐标产生的颜色总是以透视校正的方式进行迭代。但是,在迭代过程中,它们也会被截取到范围0到1之间。迭代:实际就是如果超过1则取余数来表示,几何意义在于很多张相同的 纹理图 平铺在平面上,这就称为“迭代”。
    被截取到范围0到1之间:是指余数部分,当然会在0-1之间了