c++ - 如何插入 UV 坐标?
问题描述
我正在尝试将纹理应用于我的 .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.u
和x2U = Vertex1.u
。对于决赛y
,我们有x1U = Vertex2.u
,x2U = 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 或乘以它或其他东西之前,您可能需要除以纹理的大小。
推荐阅读
- moodle - R 考试中的答案框
- python - 如何根据选择的 click.option 运行特定功能?
- javascript - 如何在每个新月安排 node-cron 作业?
- azure - Azure AppService 几次无法从 Azure 容器注册表中提取 docker 映像
- azure - Azure 永久将 IP 列入白名单
- python - Sphinx 不读取我的函数 docString?
- sql - Postgres查询根据状态条件将多行合并为一
- java - 使用java将重音字符转换为英文
- mongodb - 聚合 Mongo 中的两个 $Geonear
- php - 如何在 sh 文件中运行 PHP 脚本?