添加双纹理采样
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user