zoukankan      html  css  js  c++  java
  • 法线贴图

    http://blog.csdn.net/huazai434/article/details/5650146

    一,法线贴图实际上是一张纹理图,但纹理中存储的并不是颜色值,而是法向量坐标。这项技术的主要目的是实现物体表面的粗糙细节。

    二,法向量在纹理中的存储形式。对于24位纹理格式,r g b 三个元素中分别存储了法向量的三个坐标值。

     

    然而,法向量三个坐标值 的取值范围均为(-1.1),而纹理格式中rgb分量的范围是(0,255),因此我们必须做相应的变换。变换方程如下:

    f(x)=(0.5x+0.5)*255

     

    当我们从纹理文件中读取纹素值后,我们便需要将其从(0,255)转换成(-1,1)。由于tex2D函数返回值范围是(0,1)因此我们只需做如下的变换:

     

    f(x)=2*x-1

     

    三,如何生成法线贴图。

    法线贴图通常由灰度高度图产生。在灰度高度图中,不同点的高度h是不同的。而各点的法向量便是法线贴图中对应纹素的法向量。

    首先通过有限差分格式近似出两个切向量,然后叉乘求得法向量。公式如下:

    dhOverdx=[f(xi+dx,yi)-f(xi-dx,yi)]/2dx

    dhOverdz=[f(xi,y+dy)-f(xi,y-dy)]/2dy

     

    u=(1,dhOverdx,0);

    V=(0,dhOverdy,1);

     

    n=cross(u,v);

     

    注:我们还可以利用这个方法来计算TBN。

    所谓TBN是指tagent,binormal 和normal。对于某一个顶点来讲,T 和B 是两个切向量,而N 是法向量。这三个向量组成一个坐标系的三个基,这个坐标系便是纹理坐标系。法线纹理中的向量便是相对于纹理坐标系的。

     

    当然,TBN的计算方法可谓是多种多样,我看过各种各样的计算方法,但最基本的思路便是这个有限差分法。实际上,只要思路正确,采用哪种具体的计算方法并不重要,应为TBN本来就是近似的,没有精确值。而且,各种计算方法在效果上的差别甚微。

     

    四,利用法线贴图计算光照值。

     

    我们首先要解决的问题是坐标系不统一的问题。计算光照需要光线向量,视点向量,和法向量。前两者位于世界坐标系下,法向量则位于纹理坐标系下。因此需要将光线向量和视点向量从世界空间变换到纹理空间,然后进行光照计算。如何变换呢?

     

    首先计算TBN。如果是自定义网格,则按照如上所述进行计算。如果是D3DXMesh类型,可使用如下函数:

    D3DXComputeTangentFrameEx(参数略);这个函数的好处是可以对TBN进行插值,正如对法向量进行插值一样。

    然后将TBN写成3x3矩阵形式:(TBN的坐标是相对于物体空间)

            Tx   Ty   Tz

    M =   Bx   By    Bz

            Nx   Ny    Nz

    这个矩阵是从纹理空间到物体空间的变换矩阵。

    其逆矩阵M-1即转置矩阵是从物体空间到纹理空间的变换矩阵。

    这个过程在VS中完成,并将光向量和视点向量传递到PS,进行标准化后,便可进行Phong处理。

  • 相关阅读:
    LeetCode 252. Meeting Rooms
    LeetCode 161. One Edit Distance
    LeetCode 156. Binary Tree Upside Down
    LeetCode 173. Binary Search Tree Iterator
    LeetCode 285. Inorder Successor in BST
    LeetCode 305. Number of Islands II
    LeetCode 272. Closest Binary Search Tree Value II
    LeetCode 270. Closest Binary Search Tree Value
    LeetCode 329. Longest Increasing Path in a Matrix
    LintCode Subtree
  • 原文地址:https://www.cnblogs.com/kex1n/p/3436011.html
Copyright © 2011-2022 走看看