• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            麒麟子

            ~~

            導航

            <2010年5月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            統計

            常用鏈接

            留言簿(12)

            隨筆分類

            隨筆檔案

            Friends

            WebSites

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            per-pixel lighting 紋理空間坐標基的計算方法

             

             

            文章來源:http://www.freegames.com.cn/school/383/2007/27685.html
            Nemesis2k
            per-pixel lighting 紋理空間坐標基的計算方法

            我知道的幾種方法:

            1. 對于參數化的表面,設其方程為 P = P (u, v),其中 P 為向量,
            三個分量分別為 x, y z。也可以表示為:
            Px = Px (u ,v)
            Py = Py (u ,v)
            Pz = Pz (u ,v)
            那在任意一個頂點
            T = {dPx/du, dPy/du, dPz/du}
            B = {dPx/dv, dPy/dv, dPz/dv}
            N = T X B
            然后把 T, B, N 歸一化就行了。
            這里的偏導數可以用差分計算。
            這樣計算出來的切空間是在每一個頂點的切空間。

            2。對于由三角形面片組成的網格,在 MSDN 上的 Per-pixel lighting
            文章里介紹了一種方法。
            設三角形的三個頂點是 P0, P1, P2,其中每個頂點都有位置,法向量
            和 2-D 紋理坐標。
            Pi : {x, y, z}, {nx, ny, nz}, {s, t}
            現在我們要計算在 P0 點的切空間。
            這里要分辨兩個切空間:
            1)頂點上的切空間
            2)三角形面片上的切空間
            兩個切空間是相同的嗎?我覺得是不同的。方法 2 和方法 3 計算出來的
            實際上都是三角形面片的切空間,頂點的切空間還要通過平均頂點所在
            各個三角形面片的切空間基向量來計算。(是這樣的嗎?高手指教一下!)

            設三角形面片所在的切空間的基向量為 T, B, N,坐標原點在 P0。
            那么三角形面片中的任意向量應該可以表示為:
            Vec = x*T + y*B
            因此,如果我們找到了兩個向量 Vec1, Vec2 以及它們在 T, B 上的
            分量,那么自然就可以解出 T, B 了。
            令:
            Vec1 = P1 - P0
            Vec2 = P2 - P0
            dS1 = P1.s - P0.s
            dS2 = P2.s - P0.s
            dT1 = P1.t - P0.t
            dT2 = P2.t - p0.t
            那么我們有
            Vec1 = dS1*T + dT1*B (1)
            Vec2 = dS2*T + dT2*B (2)
            聯立 (1), (2) 就可以解出
            B*(dS2*dT1 - dS1*dT2) = (dS2*Vec1 - dS1*Vec2)
            所以:
            (dS2*dT1 - dS1*dT2) 是一個常數,反正我們之后要對 B 歸一化,
            可以不用管它。于是:
            B = normalize(dS2*Vec1 - dS1*Vec2) 這就是 MSDN 里那篇文章里的方法。
            B 可以通過解方程獲得,但是 T 就不行了,因為這樣解出來的 T 和
            B 不一定垂直。怎么處理呢?
            MSDN 中的方法是,利用頂點的 N 來求 T:
            T = B X N
            然后再求 N
            N = T X B
            但是這樣可以嗎?這里的 N 是頂點 P0 的 N,而不是三角形面片的 N。
            是不是這樣求出來的 T, N, B 恰好是頂點 P0 的切空間的坐標基,不需要
            再平均了?(高手指教!)
            我想的處理方法是這樣的:
            同樣解出 T 來:
            T = normalize(dT2*Vec1 - dT1*Vec2)
            然后 N = T X B。這個 N 是三角形面片的 N。
            然后 T = B X N。這樣 T, N, B 構成正交基,而且是三角形面片的。
            要計算 P0 頂點的切空間基,還需要平均多個面片。
            這種方法到是比較復雜。

            一個問題是,為什么有
            Vec1 = dS1*T + dT1*B (1)
            Vec2 = dS2*T + dT2*B (2)
            這兩個公式!
            我想是因為在計算頂點的紋理坐標時,因為是從平面映射到平面,所以我們使用了
            仿射變換:
            s = as*x + bs*y + cs
            t = as*x + bs*y + cs
            反過來我們有
            x = ax*s + bx*t + cx (3)
            y = ay*s + by*t + cy (4)
            z = az*s + bz*t + cz (5)
            于是
            Vec1.x = P1.x - P0.x = ax*(P1.s - P0.s) + bx*(P1.t - P0.t)
            Vec1.y = P1.y - P0.y = ay*(P1.s - P0.s) + by*(P1.t - P0.t)
            Vec1.z = P1.z - P0.z = az*(P1.s - P0.s) + bz*(P1.t - P0.t)
            于是
            Vec1 = {ax, ay, az}*dS1 + {bx, by, bz}*dT1
            這和 (1) 已經很象了,那么 {ax, ay, az} 就是 T 嗎?
            答案是是的!事實上 (3), (4), (5) 就是三角形面片的參數表示,那么
            T = {dx/ds, dy/ds, dz/ds} = {ax, ay, az}
            B = {dx/dt, dy/dt, dz/dt} = {bx, by, bz}
            也就是說,如果我們能直接把 ax, ay, az, bx, by, bz 求出來,T 和 B 就求出來了

            (當然要把他們正交歸一化)

            3 nVidia 網站上的方法。
            我們可以假設
            x = ax*s + bx*t + cx
            y = ay*s + by*t + cy
            z = az*s + bz*t + cz
            如何求解 (3) ?這里有 3 個未知數,那我們需要 3 個方程。
            將 3 個頂點的屬性 {x, y ,z}, {s, t} 帶入,剛好有三個方程:
            P0.x = ax*P0.s + bx*P0.t + cx (1)
            P1.x = ax*P1.s + bx*P1.t + cx (2)
            P2.x = ax*P2.s + bx*P2.t + cx (3)
            解出來就得到 ax, bx, cx 了。
            同理可得: ay, by, cy, az, bz, cz。
            T = {ax, ay, az}
            B = {bx, by, bz}
            N = T X B
            T = B X N
            然后都歸一化即可。

            nVidia 網站上的方法呢,是建立三個平面方程
            Ax*x + Bx*s + Cx*t + Dx = 0 (4)
            Ay*y + By*s + Cy*t + Dy = 0 (5)
            Az*z + Bz*s + Cz*t + Dz = 0 (6)

            并且指出,三角形面片上的所有點的 (x, s, t) 都在
            方程 (4) 定義的平面中。那么
            dx/ds = -Bx/Ax
            dx/dt = -Cx/Ax

            同理
            dy/ds = -By/Ay
            dy/dt = -Cy/Ay

            dz/ds = -Bz/Az
            dz/dt = -Cz/Az

            那么這些 Ax, Ay, Az, Bx, By, Bz, Cx, Cy, Cz 怎么求呢?
            容易知道,{Ax, Bx, Cx} 其實是平面的法向量,那么可以
            選平面中的三個點,計算出兩個向量,然后叉乘。

            {Ax, Bx, Cx} = {P1.x - P0.x, P1.s - P0.s, P1.t - P0.t} X
            {P2.x - P0.x, P2.s - P0.s, P2.t - P0.t}

            這兩種方法是等價的。

            posted on 2009-04-17 21:45 麒麟子 閱讀(556) 評論(0)  編輯 收藏 引用 所屬分類: GPU and Graphic

            国产精品视频久久久| 久久99精品国产麻豆不卡| 婷婷久久五月天| 亚洲AV无码1区2区久久| 久久精品夜夜夜夜夜久久| 久久精品一区二区国产| 亚洲国产精品无码久久久久久曰| 一97日本道伊人久久综合影院| 中文字幕久久精品无码| 久久中文娱乐网| 亚洲国产日韩欧美综合久久| 国内精品久久人妻互换| 久久乐国产综合亚洲精品| 久久精品国产亚洲av日韩| 亚州日韩精品专区久久久| 国产精品久久永久免费| 久久青青草原亚洲av无码| 久久久久人妻一区二区三区vr| 精品久久久无码中文字幕| 久久99精品久久久久久hb无码 | 一级女性全黄久久生活片免费| 国产精品久久久久久久久免费| 欧美午夜A∨大片久久 | 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 国产产无码乱码精品久久鸭| 亚洲va久久久久| 亚洲欧美精品一区久久中文字幕| 亚洲午夜久久影院| 2021精品国产综合久久| 久久夜色精品国产网站| 久久精品国产AV一区二区三区| 国内精品久久久久久久久电影网| 国产午夜福利精品久久2021| 欧美午夜精品久久久久免费视| 久久婷婷是五月综合色狠狠| 欧美亚洲日本久久精品| 久久人人爽人人澡人人高潮AV | 国产成人精品久久免费动漫| 久久久久国产精品熟女影院 | 四虎影视久久久免费观看| 国产巨作麻豆欧美亚洲综合久久|