- Material:单贴图 → 4 槽(binding=Slot 枚举),MakeCacheKey 组合键 保持材质去重(同贴图组合共享描述符集) - Model:读取 aiTextureType DIFFUSE/NORMALS/SPECULAR/EMISSIVE 四类路径; aiProcess_CalcTangentSpace 生成切线(Vertex +tangent 属性,location 3); 每槽默认纹理兜底(白/平法线(128,128,255)/黑/黑,1x1) - 纹理 sRGB 语义按槽位:颜色图 SRGB 变体,数据图(Normal/Specular)线性 UNORM——Texture 路径加载加 srgb 参数;修复 InitFromPixels 图文 format 不一致的 validation 警告 - UBO 尾部追加 cameraPos(Blinn-Phong V 向量) - simple_shader.frag:TBN 法线贴图(无切线/平法线退化回几何法线)+ Blinn-Phong 高光(specular 图强度系数)+ 自发光直加 - SunTemple 实测:148 张 DDS 全槽位加载(96 张线性变体)、1056 mesh、 validation 零警告
90 lines
3.0 KiB
C++
90 lines
3.0 KiB
C++
//
|
||
// Created by atdunbg on 2026/9/21.
|
||
//
|
||
|
||
#ifndef HELLOVULKAN_MODEL_H
|
||
#define HELLOVULKAN_MODEL_H
|
||
|
||
#pragma once
|
||
|
||
#include <Engine/Core/Types.h>
|
||
#include <Engine/Renderer/Material.h>
|
||
#include <Engine/Renderer/Mesh.h>
|
||
#include <vulkan/vulkan.hpp>
|
||
#include <array>
|
||
#include <string>
|
||
#include <unordered_map>
|
||
#include <vector>
|
||
|
||
struct aiNode;
|
||
struct aiMesh;
|
||
struct aiScene;
|
||
|
||
namespace Engine
|
||
{
|
||
class Device;
|
||
class MemoryAllocator;
|
||
class DescriptorManager;
|
||
class Texture;
|
||
class Material;
|
||
|
||
class Model
|
||
{
|
||
public:
|
||
Model(Device& device, MemoryAllocator& allocator,
|
||
DescriptorManager& descriptorManager,
|
||
vk::DescriptorSetLayout textureLayout,
|
||
const std::string& path);
|
||
|
||
// 程序化模型:单位法线朝上的 XZ 平面(纯色贴图),用于地面等。
|
||
// size 为半边长(平面总边长 = 2*size)。
|
||
struct ProceduralTag {};
|
||
static Scope<Model> CreatePlane(Device& device, MemoryAllocator& allocator,
|
||
DescriptorManager& descriptorManager,
|
||
vk::DescriptorSetLayout textureLayout,
|
||
f32 halfSize, u8 r, u8 g, u8 b);
|
||
|
||
~Model();
|
||
|
||
Model(const Model&) = delete;
|
||
Model& operator=(const Model&) = delete;
|
||
|
||
const std::vector<Scope<Mesh>>& GetMeshes() const { return m_Meshes; }
|
||
|
||
private:
|
||
Model(Device& device, MemoryAllocator& allocator,
|
||
DescriptorManager& descriptorManager,
|
||
vk::DescriptorSetLayout textureLayout,
|
||
ProceduralTag, f32 halfSize, const std::array<u8, 3>& color);
|
||
|
||
void LoadModel(const std::string& path);
|
||
void ProcessNode(aiNode* node, const aiScene* scene);
|
||
Scope<Mesh> ProcessMesh(aiMesh* mesh, const aiScene* scene);
|
||
void InitDefaultTextures();
|
||
|
||
Texture* GetOrLoadTexture(const std::string& path, bool srgb);
|
||
|
||
// 材质缓存入口:同贴图组合共享同一 Material(一个描述符集),
|
||
// 槽位路径为空/文件缺失折到对应默认纹理。路径已做反斜杠归一化。
|
||
// paths 下标 = Material::Slot(albedo/normal/specular/emissive)
|
||
Material* GetOrCreateMaterial(const std::string paths[Material::kSlotCount]);
|
||
|
||
Device& m_Device;
|
||
MemoryAllocator& m_Allocator;
|
||
DescriptorManager& m_DescriptorManager;
|
||
vk::DescriptorSetLayout m_TextureLayout;
|
||
|
||
// 缓存声明在 m_Meshes 之前:mesh 持 Material* 裸指针,
|
||
// 析构序 = meshes 先于材质/纹理缓存
|
||
std::unordered_map<std::string, Scope<Material>> m_MaterialCache;
|
||
std::unordered_map<std::string, Scope<Texture>> m_TextureCache;
|
||
// 各槽位默认纹理(材质缺图时兜底):白 / 平法线 / 黑高光 / 黑自发光
|
||
std::array<Scope<Texture>, Material::kSlotCount> m_DefaultTextures;
|
||
|
||
std::vector<Scope<Mesh>> m_Meshes;
|
||
std::string m_ModelPath;
|
||
};
|
||
} // namespace Engine
|
||
|
||
#endif //HELLOVULKAN_MODEL_H
|