添加双纹理采样

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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

+17 -5
View File
@@ -1,6 +1,7 @@
#version 450 #version 450
layout (binding = 1) uniform sampler2D samplerColor; layout (binding = 1) uniform sampler2D samplerColor;
layout (binding = 2) uniform sampler2D samplerColor_ex;
layout (location = 0) in vec2 inUV; layout (location = 0) in vec2 inUV;
layout (location = 1) in vec3 inNormal; layout (location = 1) in vec3 inNormal;
@@ -11,16 +12,27 @@ layout (location = 0) out vec4 outFragColor;
void main() void main()
{ {
vec4 color = texture(samplerColor, inUV); vec4 color = texture(samplerColor, inUV);
vec4 color_ex = texture(samplerColor_ex, inUV);
vec3 N = normalize(inNormal); vec3 N = normalize(inNormal);
vec4 textureColor = color; vec4 textureColor = color;
if (textureColor.a < 0.1) {
//textureColor = vec4(0.2, 0.2, 0.2, 0.5);
discard;
}
outFragColor = textureColor; //if (textureColor.a < 0.1)
//{
//textureColor = vec4(0.2, 0.2, 0.2, 0.5);
// discard;
//}
// ¼ÆËãÓë (0,0,1) µÄµã³Ë
float ndot = dot(N, vec3(0.0, 0.0, -1.0));
// ±£Ö¤½á¹û >= 0
ndot = max(ndot, 0.0);
vec4 blendedColor = mix(color_ex, color, ndot);
outFragColor = blendedColor;
// outFragColor = vec4(1, 0, 0, 1); // outFragColor = vec4(1, 0, 0, 1);
} }
Binary file not shown.
+109
View File
@@ -336,3 +336,112 @@ void AppBase::pickPhysicalDevice(VkPhysicalDevice& physicalDevice, VkSurfaceKHR&
throw std::runtime_error("failed to find a suitable GPU!"); 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;
}
}
}
+19
View File
@@ -38,6 +38,9 @@
#include <mutex> #include <mutex>
#include <chrono> #include <chrono>
#include <ctime> #include <ctime>
#include <cmath>
#include <unordered_map>
#include <array>
void VK_CHECK(VkResult ret); void VK_CHECK(VkResult ret);
@@ -51,6 +54,13 @@ struct QueueFamilyIndices {
} }
}; };
struct TextureLoadingVertexStructure
{
float pos[3];
float uv[2];
float normal[3];
};
class AppBase class AppBase
{ {
public: public:
@@ -81,6 +91,15 @@ protected:
bool enableValidationLayers = true; bool enableValidationLayers = true;
VkDebugUtilsMessengerEXT debugMessenger; VkDebugUtilsMessengerEXT debugMessenger;
// 计算面的法线
void calculateFaceNormal(const TextureLoadingVertexStructure& v0, const TextureLoadingVertexStructure& v1, const TextureLoadingVertexStructure& v2, float* outNormal);
// 计算所有顶点的法线
void calculateVertexNormals(std::vector<TextureLoadingVertexStructure>& obj_vertices, const std::vector<uint32_t>& obj_indices);
}; };
#endif // VULKAN_UTILS_H #endif // VULKAN_UTILS_H
+32 -7
View File
@@ -408,7 +408,14 @@ void FaceApp::setup_descriptor_set_layout()
set_layout_binding_fragment.binding = 1; set_layout_binding_fragment.binding = 1;
set_layout_binding_fragment.descriptorCount = 1; set_layout_binding_fragment.descriptorCount = 1;
std::vector<VkDescriptorSetLayoutBinding> set_layout_bindings{ set_layout_binding_vertex , set_layout_binding_fragment}; // 添加第二个纹理绑定点
VkDescriptorSetLayoutBinding set_layout_binding_fragment1{};
set_layout_binding_fragment1.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
set_layout_binding_fragment1.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
set_layout_binding_fragment1.binding = 2;
set_layout_binding_fragment1.descriptorCount = 1;
std::vector<VkDescriptorSetLayoutBinding> set_layout_bindings{ set_layout_binding_vertex , set_layout_binding_fragment, set_layout_binding_fragment1 };
VkDescriptorSetLayoutCreateInfo descriptor_layout{}; VkDescriptorSetLayoutCreateInfo descriptor_layout{};
@@ -457,6 +464,12 @@ void FaceApp::setup_descriptor_set()
image_descriptor.sampler = tex_demo0.sampler; image_descriptor.sampler = tex_demo0.sampler;
image_descriptor.imageLayout = tex_demo0.image_layout; image_descriptor.imageLayout = tex_demo0.image_layout;
// 第二个纹理描述符 - 假设你的第二个纹理变量名为 tex_demo1
VkDescriptorImageInfo image_descriptor1;
image_descriptor1.imageView = tex_demo0_ex.view;
image_descriptor1.sampler = tex_demo0_ex.sampler;
image_descriptor1.imageLayout = tex_demo0_ex.image_layout;
VkWriteDescriptorSet write_descriptor_set_uniform{}; VkWriteDescriptorSet write_descriptor_set_uniform{};
write_descriptor_set_uniform.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; write_descriptor_set_uniform.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write_descriptor_set_uniform.dstSet = m_descriptor_set; write_descriptor_set_uniform.dstSet = m_descriptor_set;
@@ -474,10 +487,20 @@ void FaceApp::setup_descriptor_set()
write_descriptor_set_image.pImageInfo = &image_descriptor; write_descriptor_set_image.pImageInfo = &image_descriptor;
write_descriptor_set_image.descriptorCount = 1; write_descriptor_set_image.descriptorCount = 1;
// 添加第二个纹理的写入描述符
VkWriteDescriptorSet write_descriptor_set_image1{};
write_descriptor_set_image1.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write_descriptor_set_image1.dstSet = m_descriptor_set;
write_descriptor_set_image1.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
write_descriptor_set_image1.dstBinding = 2; // 绑定到位置2
write_descriptor_set_image1.pImageInfo = &image_descriptor1;
write_descriptor_set_image1.descriptorCount = 1;
std::vector<VkWriteDescriptorSet> write_descriptor_sets = std::vector<VkWriteDescriptorSet> write_descriptor_sets =
{ {
write_descriptor_set_uniform, write_descriptor_set_uniform,
write_descriptor_set_image write_descriptor_set_image,
write_descriptor_set_image1, // 添加第二个纹理
}; };
vkUpdateDescriptorSets(device, static_cast<uint32_t>(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); vkUpdateDescriptorSets(device, static_cast<uint32_t>(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL);
@@ -489,13 +512,13 @@ void FaceApp::render(VkCommandBuffer commandBuffer)
std::unique_lock<std::mutex> lock_point(mtx_point); std::unique_lock<std::mutex> lock_point(mtx_point);
//Application::render(commandBuffer); //Application::render(commandBuffer);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout_bg, 0, 1, &m_descriptor_set_bg, 0, NULL); //vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout_bg, 0, 1, &m_descriptor_set_bg, 0, NULL);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline_bg); //vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline_bg);
vkCmdPushConstants(commandBuffer, m_pipelineLayout_bg, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &myFloatValue); //vkCmdPushConstants(commandBuffer, m_pipelineLayout_bg, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &myFloatValue);
vkCmdDraw(commandBuffer, 6, 1, 0, 0); //vkCmdDraw(commandBuffer, 6, 1, 0, 0);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_set, 0, NULL); vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_set, 0, NULL);
@@ -550,6 +573,8 @@ void FaceApp::initVulkan()
createVmaAllocator(); createVmaAllocator();
LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices); LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices);
loadTexture("demo0.png", tex_demo0, true); loadTexture("demo0.png", tex_demo0, true);
loadTexture("demo0_ex.png", tex_demo0_ex, true);
loadTexture("out.png", tex_bg, false); loadTexture("out.png", tex_bg, false);
createVertexBuffer(); createVertexBuffer();
createUniformBuffer(); createUniformBuffer();
@@ -665,7 +690,7 @@ void FaceApp::update_face_vertex_buffer(float* pos, int pointCount)
obj_vertices[i].pos[1] = y; obj_vertices[i].pos[1] = y;
obj_vertices[i].pos[2] = z; obj_vertices[i].pos[2] = z;
} }
calculateVertexNormals(obj_vertices, obj_indices);
uploadVertexData(); uploadVertexData();
} }
+2 -6
View File
@@ -8,12 +8,7 @@
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/matrix_transform.inl> #include <glm/gtc/matrix_transform.inl>
struct TextureLoadingVertexStructure
{
float pos[3];
float uv[2];
float normal[3];
};
struct PushConstants { struct PushConstants {
float myValue; float myValue;
@@ -101,6 +96,7 @@ private:
void createUniformBuffer(); void createUniformBuffer();
Texture tex_demo0 = {0}; Texture tex_demo0 = {0};
Texture tex_demo0_ex = { 0 };
bool faceAppInited = false; bool faceAppInited = false;
float myFloatValue = 1.5f; float myFloatValue = 1.5f;