添加双纹理采样
This commit is contained in:
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 |
@@ -1,6 +1,7 @@
|
||||
#version 450
|
||||
|
||||
layout (binding = 1) uniform sampler2D samplerColor;
|
||||
layout (binding = 2) uniform sampler2D samplerColor_ex;
|
||||
|
||||
layout (location = 0) in vec2 inUV;
|
||||
layout (location = 1) in vec3 inNormal;
|
||||
@@ -11,16 +12,27 @@ layout (location = 0) out vec4 outFragColor;
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture(samplerColor, inUV);
|
||||
vec4 color_ex = texture(samplerColor_ex, inUV);
|
||||
|
||||
vec3 N = normalize(inNormal);
|
||||
|
||||
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);
|
||||
}
|
||||
Binary file not shown.
@@ -336,3 +336,112 @@ void AppBase::pickPhysicalDevice(VkPhysicalDevice& physicalDevice, VkSurfaceKHR&
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,9 @@
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <unordered_map>
|
||||
#include <array>
|
||||
|
||||
void VK_CHECK(VkResult ret);
|
||||
|
||||
@@ -51,6 +54,13 @@ struct QueueFamilyIndices {
|
||||
}
|
||||
};
|
||||
|
||||
struct TextureLoadingVertexStructure
|
||||
{
|
||||
float pos[3];
|
||||
float uv[2];
|
||||
float normal[3];
|
||||
};
|
||||
|
||||
class AppBase
|
||||
{
|
||||
public:
|
||||
@@ -81,6 +91,15 @@ protected:
|
||||
|
||||
bool enableValidationLayers = true;
|
||||
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
|
||||
+32
-7
@@ -408,7 +408,14 @@ void FaceApp::setup_descriptor_set_layout()
|
||||
set_layout_binding_fragment.binding = 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{};
|
||||
@@ -457,6 +464,12 @@ void FaceApp::setup_descriptor_set()
|
||||
image_descriptor.sampler = tex_demo0.sampler;
|
||||
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{};
|
||||
write_descriptor_set_uniform.sType = VK_STRUCTURE_TYPE_WRITE_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.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 =
|
||||
{
|
||||
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);
|
||||
@@ -489,13 +512,13 @@ void FaceApp::render(VkCommandBuffer commandBuffer)
|
||||
std::unique_lock<std::mutex> lock_point(mtx_point);
|
||||
//Application::render(commandBuffer);
|
||||
|
||||
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);
|
||||
//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);
|
||||
|
||||
|
||||
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);
|
||||
@@ -550,6 +573,8 @@ void FaceApp::initVulkan()
|
||||
createVmaAllocator();
|
||||
LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices);
|
||||
loadTexture("demo0.png", tex_demo0, true);
|
||||
loadTexture("demo0_ex.png", tex_demo0_ex, true);
|
||||
|
||||
loadTexture("out.png", tex_bg, false);
|
||||
createVertexBuffer();
|
||||
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[2] = z;
|
||||
}
|
||||
|
||||
calculateVertexNormals(obj_vertices, obj_indices);
|
||||
uploadVertexData();
|
||||
}
|
||||
|
||||
|
||||
+2
-6
@@ -8,12 +8,7 @@
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/matrix_transform.inl>
|
||||
|
||||
struct TextureLoadingVertexStructure
|
||||
{
|
||||
float pos[3];
|
||||
float uv[2];
|
||||
float normal[3];
|
||||
};
|
||||
|
||||
|
||||
struct PushConstants {
|
||||
float myValue;
|
||||
@@ -101,6 +96,7 @@ private:
|
||||
void createUniformBuffer();
|
||||
|
||||
Texture tex_demo0 = {0};
|
||||
Texture tex_demo0_ex = { 0 };
|
||||
bool faceAppInited = false;
|
||||
|
||||
float myFloatValue = 1.5f;
|
||||
|
||||
Reference in New Issue
Block a user