簡體   English   中英

如何插入 UV 坐標?

[英]How do I interpolate the UV co-ordinates?

我正在嘗試將紋理應用於我的 .md2 模型。 我使用 Gouraud 着色給它上色(底部/頂部平面三角形的標准算法),我必須使用類似的代碼來處理紋理坐標 U 和 V。但我真的不明白如何對它們進行插值。 從我的嘗試來看,我的代碼似乎只在邊緣插入,而不是在它們之間插入。 我錯過了什么? 謝謝你。 在此處輸入圖片說明

這里的顏色由 u 為紅色,v 為綠色,255 為藍色(僅用於底部扁平三角形): 在此處輸入圖片說明

 void Rasteriser::TfillBottomFlatTriangle(Vertex vertex1, Vertex vertex2, Vertex vertex3, COLORREF c1, COLORREF c2, COLORREF c3, HDC hdc)
    {
        float slope1 = (vertex2.GetX() - vertex1.GetX()) / (vertex2.GetY() - vertex1.GetY());
        float slope2 = (vertex3.GetX() - vertex1.GetX()) / (vertex3.GetY() - vertex1.GetY());

    //U and V
    float slope1U = (vertex2.GetU() - vertex1.GetU()) / (vertex2.GetY() - vertex1.GetY());
    float slope2U = (vertex3.GetU() - vertex1.GetU()) / (vertex3.GetY() - vertex1.GetY());

    float slope1V = (vertex2.GetV() - vertex1.GetV()) / (vertex2.GetY() - vertex1.GetY());
    float slope2V = (vertex3.GetV() - vertex1.GetV()) / (vertex3.GetY() - vertex1.GetY());

    float x1 = vertex1.GetX();
    float x2 = vertex1.GetX() + 0.5f;

    //U and V
    float x1U = vertex1.GetU();
    float x2U = x1U;

    float x1V = vertex1.GetV();
    float x2V = x1V;


    if (slope2 < slope1)
    {
        float slopeTmp = slope1;
        slope1 = slope2;
        slope2 = slopeTmp;

        float slopeTmpU = slope1U;
        slope1U = slope2U;
        slope2U = slopeTmpU;

        float slopeTmpV = slope1V;
        slope1V = slope2V;
        slope2V = slopeTmpV;

    }

    for (float scanlineY = vertex1.GetY(); scanlineY <= vertex2.GetY(); scanlineY++)
    {
        /* loop over each pixel of horizontal line */

        for (float xPos = ceil(x1); xPos < x2; xPos++)
        {

                float t = (xPos - x1) / (x2 - x1);
                float u = (1 - t) * x1U + t * x2U;
                float v = (1 - t) * x1V + t * x2V;
                COLORREF colour = _model.GetTexture().GetTextureValue((int)u, (int)v);
                SetPixel(hdc, (int)xPos, (int)scanlineY, colour);

        }
        // get new x-coordinate of endpoints of horizontal line 
        x1 += slope1;
        x2 += slope2;
        x1U += slope1U;
        x2U += slope2U;
        x1V += slope1V;
        x2V += slope2V;
    }

}

問題在這里:

    //U and V
    float x1U = vertex1.GetU();
    float x2U = vertex1.GetU() + 0.5f;

    float x1V = vertex1.GetV();
    float x2V = vertex1.GetV() + 0.5f;

0.5對於 uv 坐標來說很多,所以這告訴我這是錯誤的。

我認為正確的方法是這樣的:

    //U and V
    float x1U = vertex1.GetU();
    float x2U = x1U;

    float x1V = vertex1.GetV();
    float x2V = x1V;

快速健全性測試:對於初始y我們有x1U = Vertex1.ux2U = Vertex1.u 對於最后的y我們有x1U = Vertex2.ux2U = Vertex3.u對嗎?

我認為發生的事情是每個三角形都包含您紋理的一半,我想我們可以在圖像中看到它。

編輯:我在 python 中實現了相同的算法並得到了預期的結果:

import numpy as np

p = np.array([[0,0],
              [-5,10],
              [10,10]],dtype=np.float)

uv = np.array([[0.1,0.6],
               [0.2,0.5],
               [0.3,0.4]])

slope = (p[[1,2],0] - p[0,0])/(p[[1,2],1] - p[0,1])

slope_uv = (uv[[1,2],:] - uv[0,:])/(p[[1,2],1] - p[0,1]).reshape(-1,1)

x1 = p[0,0]
x2 = p[0,0] + 0.5

uv1 = uv[0,:]
uv2 = np.copy(uv1)

result = []

for scanY in range(int(p[0,1]),int(p[1,1])):
    for x in range(int(np.ceil(x1)),int(x2)):
        t = (x-x1)/(x2-x1)
        u = (1-t) * uv1 + t * uv2
        result.append((x,scanY,u[0],u[1]))
    x1 += slope[0]
    x2 += slope[1]
    uv1 += slope_uv[0,:]
    uv2 += slope_uv[1,:]

#%%
R = np.array(result,dtype=float)
from matplotlib import pyplot as plt

plt.figure()
plt.subplot(2,1,1)
plt.scatter(R[:,0],R[:,1],c = R[:,2])
plt.title('u')
plt.colorbar()
plt.subplot(2,1,2)
plt.scatter(R[:,0],R[:,1],c = R[:,3])
plt.title('v')
plt.colorbar()

結果如下:

在此處輸入圖片說明

我猜您的問題是頂點的uv值不正確。

另外,我可以在您的代碼中看到以下行:

                COLORREF colour = _model.GetTexture().GetTextureValue((int)u, (int)v);

這沒什么意義,因為u,v通常介於 0 和 1 之間。我認為您可能需要在調用 GetTextureValue 或乘以它之前除以紋理的大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM