添加双纹理采样

This commit is contained in:
xsl
2025-10-22 18:16:03 +08:00
parent ce2444bd07
commit f6dd3ab38e
8 changed files with 178 additions and 17 deletions
+109
View File
@@ -335,4 +335,113 @@ void AppBase::pickPhysicalDevice(VkPhysicalDevice& physicalDevice, VkSurfaceKHR&
if (physicalDevice == VK_NULL_HANDLE) {
throw std::runtime_error("failed to find a suitable GPU!");
}
}
// 计算面的法线
void AppBase::calculateFaceNormal(const TextureLoadingVertexStructure& v0,
const TextureLoadingVertexStructure& v1,
const TextureLoadingVertexStructure& v2,
float* outNormal)
{
// 计算两个边向量
float edge1[3] = { v1.pos[0] - v0.pos[0], v1.pos[1] - v0.pos[1], v1.pos[2] - v0.pos[2] };
float edge2[3] = { v2.pos[0] - v0.pos[0], v2.pos[1] - v0.pos[1], v2.pos[2] - v0.pos[2] };
// 叉积计算法线
outNormal[0] = edge1[1] * edge2[2] - edge1[2] * edge2[1];
outNormal[1] = edge1[2] * edge2[0] - edge1[0] * edge2[2];
outNormal[2] = edge1[0] * edge2[1] - edge1[1] * edge2[0];
// 归一化
float length = std::sqrt(outNormal[0] * outNormal[0] +
outNormal[1] * outNormal[1] +
outNormal[2] * outNormal[2]);
if (length > 0.0f) {
outNormal[0] /= length;
outNormal[1] /= length;
outNormal[2] /= length;
}
}
// 计算所有顶点的法线
void AppBase::calculateVertexNormals(std::vector<TextureLoadingVertexStructure>& obj_vertices,
const std::vector<uint32_t>& obj_indices)
{
// 验证索引数量是3的倍数
if (obj_indices.size() % 3 != 0) {
return; // 或者抛出异常
}
// 为每个顶点创建法线累加器和计数
std::vector<std::array<float, 3>> normalSums(obj_vertices.size(), { 0.0f, 0.0f, 0.0f });
std::vector<int> normalCounts(obj_vertices.size(), 0);
// 遍历所有三角形
for (size_t i = 0; i < obj_indices.size(); i += 3) {
uint32_t idx0 = obj_indices[i];
uint32_t idx1 = obj_indices[i + 1];
uint32_t idx2 = obj_indices[i + 2];
// 验证索引有效性
if (idx0 >= obj_vertices.size() || idx1 >= obj_vertices.size() || idx2 >= obj_vertices.size()) {
continue;
}
// 获取三角形的三个顶点
const auto& v0 = obj_vertices[idx0];
const auto& v1 = obj_vertices[idx1];
const auto& v2 = obj_vertices[idx2];
// 计算面的法线
float faceNormal[3];
calculateFaceNormal(v0, v1, v2, faceNormal);
// 将面法线累加到每个顶点
for (int j = 0; j < 3; j++) {
normalSums[idx0][j] += faceNormal[j];
normalSums[idx1][j] += faceNormal[j];
normalSums[idx2][j] += faceNormal[j];
}
normalCounts[idx0]++;
normalCounts[idx1]++;
normalCounts[idx2]++;
}
// 计算每个顶点的平均法线并归一化
for (size_t i = 0; i < obj_vertices.size(); i++) {
if (normalCounts[i] > 0) {
// 计算平均值
float avgNormal[3] = {
normalSums[i][0] / normalCounts[i],
normalSums[i][1] / normalCounts[i],
normalSums[i][2] / normalCounts[i]
};
// 归一化
float length = std::sqrt(avgNormal[0] * avgNormal[0] +
avgNormal[1] * avgNormal[1] +
avgNormal[2] * avgNormal[2]);
if (length > 0.0f) {
obj_vertices[i].normal[0] = avgNormal[0] / length;
obj_vertices[i].normal[1] = avgNormal[1] / length;
obj_vertices[i].normal[2] = avgNormal[2] / length;
}
else {
// 如果法线长度为0,设置为默认值
obj_vertices[i].normal[0] = 0.0f;
obj_vertices[i].normal[1] = 1.0f;
obj_vertices[i].normal[2] = 0.0f;
}
}
else {
// 如果没有面使用这个顶点,设置默认法线
obj_vertices[i].normal[0] = 0.0f;
obj_vertices[i].normal[1] = 1.0f;
obj_vertices[i].normal[2] = 0.0f;
}
}
}