根因1(致命):光源位置写成 lightDir*30。lightDir 是光的传播方向 (指向场景),乘 30 后光源跑到场景下方——从地面下方向上打光, 地面永远是光线第一个交点,物体永远不可能遮挡地面,影子恒不存在。 修复:光源位置 = -lightDir * 30(逆传播方向退回)。 根因2:垂直光(direction≈(0,-1,0))时 lookAt 的 up=(0,1,0) 与视线 平行,叉积为零 → 矩阵 NaN → shadow map 全垃圾。修复:|dir.y|>0.99 时改用 (0,0,1) 作为 up。 场景:地面 quad(Model::CreatePlane 程序化构造,AssetManager 缓存) + 主光调平让影子落在相机视野内。已截图验证影子可见。
75 lines
2.1 KiB
C++
75 lines
2.1 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/Mesh.h>
|
|
#include <vulkan/vulkan.hpp>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
struct aiNode;
|
|
struct aiMesh;
|
|
struct aiScene;
|
|
|
|
namespace Engine
|
|
{
|
|
class Device;
|
|
class MemoryAllocator;
|
|
class DescriptorManager;
|
|
class Texture;
|
|
|
|
class Model
|
|
{
|
|
public:
|
|
Model(Device& device, MemoryAllocator& allocator,
|
|
DescriptorManager& descriptorManager,
|
|
vk::DescriptorSetLayout textureLayout,
|
|
const std::string& path);
|
|
// 程序化构造:单 quad 平面(XZ 平面朝上),不经过 assimp
|
|
static Scope<Model> CreatePlane(Device& device, MemoryAllocator& allocator,
|
|
DescriptorManager& descriptorManager,
|
|
vk::DescriptorSetLayout textureLayout,
|
|
f32 size, const std::string& texturePath);
|
|
|
|
~Model();
|
|
|
|
Model(const Model&) = delete;
|
|
Model& operator=(const Model&) = delete;
|
|
|
|
const std::vector<Scope<Mesh>>& GetMeshes() const { return m_Meshes; }
|
|
|
|
private:
|
|
struct ProceduralTag {};
|
|
Model(ProceduralTag, Device& device, MemoryAllocator& allocator,
|
|
DescriptorManager& descriptorManager,
|
|
vk::DescriptorSetLayout textureLayout);
|
|
void LoadModel(const std::string& path);
|
|
void ProcessNode(aiNode* node, const aiScene* scene);
|
|
Scope<Mesh> ProcessMesh(aiMesh* mesh, const aiScene* scene);
|
|
|
|
Texture* GetOrLoadTexture(const std::string& path);
|
|
|
|
Device& m_Device;
|
|
MemoryAllocator& m_Allocator;
|
|
DescriptorManager& m_DescriptorManager;
|
|
vk::DescriptorSetLayout m_TextureLayout;
|
|
|
|
std::vector<Scope<Mesh>> m_Meshes;
|
|
std::string m_ModelPath;
|
|
|
|
// 纹理缓存:同一路径只加载一次
|
|
std::unordered_map<std::string, Scope<Texture>> m_TextureCache;
|
|
Scope<Texture> m_DefaultTexture;
|
|
};
|
|
} // namespace Engine
|
|
|
|
|
|
#endif //HELLOVULKAN_MODEL_H
|