atdunbg
|
8c0a11d2e8
|
feat: CSM 软阴影——sampler2DShadow 硬件 PCF + 3×3 纹素 tap
- 阴影采样器开启硬件深度比较(compareOp=eLess + linear filter):
单次采样 = 2×2 深度比较插值,clamp-to-border 白色语义不变
- ShadowFactor 改 3×3 纹素偏移 tap(等效 36 次比较),影中保留
0.3 环境感并按 PCF 结果插值——阴影边缘软过渡,消除二值硬边锯齿
|
2026-09-23 23:18:36 +08:00 |
|
atdunbg
|
2b875c9284
|
feat: OBJ 全量贴图接入——Material 加 AO 槽 + OBJ 工作流适配
- Material 槽位 4→5(+AO),参数 UBO binding 4→5;shader ambient
diffuse 项乘 ao(IBL 遮蔽),AO 默认纹理白色
- OBJ 槽落点补全:map_Bump→HEIGHT(5)、map_Ns→SHININESS(7)、
map_Ka→AMBIENT(3)(assimp OBJ importer 约定)——backpack 的
法线贴图此前也从未加载
- MTL 导出遗漏(roughness.jpg/ao.jpg 在目录未被引用):约定文件名
探测补槽(roughness/ao/occlusion × jpg/png),命中留 INFO 锚点
- 因子按工作流分支:glTF 用声明因子(MR 合图 B=金属度);
OBJ metallic=0(specular 工作流无金属概念),roughness 有图→1,
无图→Blinn-Phong Ns 换算 R=sqrt(2/(Ns+2))(补偿默认贴图 G=0.5)
|
2026-09-23 19:49:36 +08:00 |
|
atdunbg
|
9269afaa18
|
feat: IBL 阶段③——pre-filtered cubemap + BRDF LUT,split-sum 镜面项接入
- pre-filter:GGX 重要性采样(Hammersley + van der Corput 位反转),
128²×5 mip 分级 roughness,采样数 32<<mip 上限 256;UploadCube 泛化
支持 mip 链([mip: 6面] 紧凑排布逐 mip 逐面拷贝)
- BRDF LUT:128² R16G16Sfloat 积分表((NdotV,roughness)→F 缩放/偏置),
纯数学与环境无关,中性兜底同样生成;专用 clamp-to-edge 采样器
(共享 border 白采样器在 uv=1.0 混入白色导致高 roughness 偏大)
- shader:specular = prefiltered(R, roughness×4) × (F·A+B),
ambient = (diffuse + specular) × ambientColor
- Hammersley 分母修正为当次积分采样数(低 mip 偏差 bug)
- Debug 构建预积分 26s→14s(采样预算收敛 + pow 改乘法链;
env 1024² 重采样为大头,compute 迁移后归零)
|
2026-09-23 19:04:25 +08:00 |
|
atdunbg
|
fa25cb3348
|
feat: IBL 阶段②——漫反射辐照度卷积,PBR ambient 接入环境光
- Cubemap 构造期同步 CPU 半球 Lambert 积分(64×32 网格 ≈2048 采样/像素)
生成 32² irradiance cube(漫反射是超低频信号,分辨率无需高)
- shader:kD 用粗糙度感知 FresnelSchlickRoughness + (1-metallic),
N 采样 irradianceMap(Set2 binding 3)替换常数 ambient;
ambientColor 保留为强度/色调乘子
- CreateNeutral 兜底:无 HDR 资产时 1×1 常数 cube,描述符恒有效
- FaceDir 改为返回单位方向(equirect 查表要求,修掉未归一化的畸变)
|
2026-09-23 18:50:34 +08:00 |
|
atdunbg
|
4b5990e6c8
|
feat: 环境背景管线(IBL 阶段①)——HDR 等距柱状转 cube + Skybox pass
- Cubemap:stbi_loadf 加载 .hdr,CPU 双线性重采样 6 面(GL 规范方向表),
f32→fp16 转换后整块上传 eCubeCompatible image(R16G16B16A16Sfloat)
- SkyboxPass:HDRColor 的 first writer,承担清屏职责;无环境贴图自动
退化为纯清屏(Forward 不受影响)
- frag 逐像素 NDC 反投影取世界方向(invVP push,投影变换不可线性插值)
- Forward color 附件 Clear→Load:几何合成在天空之上
- SceneRenderer 产出 skyInvVP = inverse(proj × mat4(mat3(view)))
|
2026-09-23 18:37:01 +08:00 |
|
atdunbg
|
89bf4256e8
|
feat: 解析式 PBR(Cook-Torrance GGX,metallic-roughness 工作流)
- 修 void* 指针算术警告(Texture::InitFromDds)
- Material:slot2 语义切为 metallicRoughness(glTF 约定 G=粗糙度
B=金属度)+ 新增材质因子参数 UBO(binding 4,per-slot ring,
创建时写死,metallic/roughness 因子乘 MR 贴图)
- simple_shader.frag:Blinn-Phong → Cook-Torrance(GGX 分布 +
Smith 几何 + Schlick Fresnel,k=(r+1)²/8 解析光源版);金属不参与
漫反射;环境光暂为常数(IBL 后续)
- Model:读 aiTextureType_UNKNOWN(glTF MR 落点)+ AI_MATKEY_
METALLIC/ROUGHNESS_FACTOR(旧资产缺键退化为电介质 0/0.5);
材质缓存键含因子
- main.cpp:演示场景换回 backpack(旧资产走因子路径验证 PBR 全链路)
- 旧 specular 贴图不再使用(语义被 MR 取代)
|
2026-09-23 18:01:14 +08:00 |
|
atdunbg
|
2c4efc5165
|
feat: 多光源——点光源类型(距离衰减,位置来自 Transform)
- LightComponent 加 Type(Directional/Point)+ radius;点光位置取
实体 Transform(固有组件首次实际受益)
- LightData shader 契约扩为 4×vec4(color/direction/position/params,
每灯 64B,未用字段置零);UBO 688→816B
- 光照循环按类型分支:方向光无衰减;点光 L 指向光源 + 平方距离衰减,
衰减半径外跳过;CSM 阴影只来自第 0 盏方向光
- main.cpp:SunTemple 场景加暖橙火坑光 + 冷蓝填充光(点光);
KeyLight/FillLight 改 designated initializer
|
2026-09-23 17:46:25 +08:00 |
|
atdunbg
|
c54f60c5ea
|
feat: 材质系统 v1——4 纹理槽(albedo/normal/specular/emissive)+ 法线贴图
- 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 零警告
|
2026-09-23 14:50:10 +08:00 |
|
atdunbg
|
0328d4aaeb
|
feat: CSM 级联阴影(3 级联 × 1024²,实用分割 + 纹素对齐)
- SceneRenderer::ComputeCascades:相机视锥实用分割(λ=0.6)→ 反投影
取切片角点 → 光空间 AABB 拟合 → 纹素对齐(消除相机移动时阴影边缘
闪烁)→ [0,1] 深度重映射
- Shadow pass 单 pass 渲 3 个 region,每级联 push 各自光空间 VP
- Forward:UBO lightSpace[3]+cascadeSplits(视图深度选级联),Set2
三张级联图按 binding 0/1/2 采样;vertex 输出 fragViewDepth
- 光源视锥剔除用最远级联(覆盖全阴影范围);双视锥独立剔除铁律保留
- 旧单张 2048 全场景图退役;近处级联分辨率 ~128px/unit(约 2× 提升)
- 编译零错误、validation 零警告、8 秒冒烟通过(10 pass 全活跃)
|
2026-09-23 13:48:43 +08:00 |
|
atdunbg
|
27b7f8785c
|
feat: TAA 时域抗锯齿(velocity + 邻域 clamp + 子像素抖动)
- Velocity buffer:Forward 第二颜色附件,vertex 计算 clip 空间运动向量
(UBO 尾部追加 projNoJitter/prevView/prevProj;上一帧实例矩阵 SSBO
Set0 binding2,与当前实例数组平行对齐——转动的物体速度正确不鬼影)
- 子像素抖动:SceneRenderer Halton(2,3)×8 序列,抖动只进光栅化投影
- TAA resolve pass:velocity 反推历史位置 + 3×3 邻域 clamp 去鬼影 +
mix(cur,hist,0.9) 时域累积;TAAColor 自引用历史
- RG 历史读补 post-barrier:采样后恢复镜像 resting layout(TAA 的历史
是 ColorAttachment layout,不恢复则下帧 entry oldLayout 脱节)
- 管线:Forward(HDR+Velocity) → TAA(TAAColor) → Bloom/Tonemap 改源 TAAColor
- 编译零错误、validation 零警告、8 秒冒烟通过(10 pass 全活跃)
|
2026-09-23 13:29:31 +08:00 |
|
atdunbg
|
c75832e73e
|
feat: RenderGraph 帧历史资源(ReadHistory)+ TemporalDiff 验证 pass
- PassBuilder::ReadHistory:读上一帧槽位 ((slot-1+F) mod F) 的物理镜像,
TAA/运动模糊等时域效果的前置能力,RG 最后一个已知边界补齐
- 历史读不建拓扑边(跨帧依赖由同队列提交序保证)、不入本帧状态链、
不改生命周期;剔除照常参与(生产者存活判定)
- 历史 barrier:首帧走 first(old=Undefined),之后走 steady 且
src=ALL_COMMANDS|MEMORY_WRITE 显式闭合跨帧可用性+可见性;
有历史读的资源,常规 entry steady 的 src 同样升级(历史读打破了
同槽位 fence 全等保前提)
- TemporalDiff 调试 pass:|上一帧−当前帧|×增益,静止=黑/运动边缘发光
即链路正确;Tonemap binding2 经 push 开关切调试视图
- 编译零错误、validation 零警告、8 秒冒烟通过(9 pass 全活跃)
|
2026-09-23 13:05:10 +08:00 |
|
atdunbg
|
91880d88fe
|
fix: tonemap 输出预乘 alpha 匹配 PRE_MULTIPLIED 合成模式 + 调整地面位置
|
2026-09-23 11:35:05 +08:00 |
|
atdunbg
|
df4871a49b
|
feat: 透明窗口支持 + 退出确认流程 + ImGui 总开关
用户自主改进批次:
- 透明窗口:GLFW_TRANSPARENT_FRAMEBUFFER + 窗口 opacity 0.5,
swapchain composite alpha 按能力自适应(Opaque/Pre/PostMultiplied),
Forward 清屏 alpha=0,tonemap 透传 HDR alpha——物体实体、背景透明
- 退出确认:Window 挂 WindowCloseCallback 发事件,App 侧 OnWindowClose
置确认标记,OnRenderOverlay 弹 ImGui 确认框后 Close();
主循环退出条件改为 m_Running(close 事件驱动)
- ImGui 总开关:` 键切换 ImGuiLayer::SetEnabled,禁用时跳过
NewFrame/OnRenderOverlay/BuildDrawData 整段
- 帧率控制简化:去掉 LimitFps 开关,非 vsync 时恒按 target 限帧
(默认 60,可调 ≥24);m_VSync 默认 false(Mailbox 不限速)
- 清理:Model.cpp const 修正,swapchain 日志带 present mode,
GPU 遥测暂时注释
验证:0 error 0 warning,composite alpha 实测选 PreMultiplied(0x2),
present=Mailbox
|
2026-09-23 10:57:48 +08:00 |
|
atdunbg
|
6a3fcac072
|
fix: Shadow pass 接入 GPUDriven batch,实例上限提至 16384
100 背包掉帧 + 警告刷屏的根因:
1. backpack.obj 有 44 个 mesh 部件,100 实体 × 44 = 4400 实例
打爆 4096 上限 → 每帧截断 + 告警刷屏。上限提至 16384
(1MB/slot),告警改一次性
2. Shadow pass 仍逐实体逐部件画(4400 draw,CPU 提交瓶颈)。
改为与 Forward 共用同一批 batch:Set0 绑 ObjectBuffer,
lightVP 一次 push,44 draw 完成。shadow.vert 经
gl_InstanceIndex 从 SSBO 取模型矩阵
实测(100 背包):GPU 总耗时 ~5.7ms(Shadow 2.9 + Forward 2.6 +
后处理 0.1),0 警告,帧率受 mailbox 垂直同步 pacing 限制
|
2026-09-22 20:06:43 +08:00 |
|
atdunbg
|
7fca721a24
|
feat: GPUDriven 实例化渲染——draw 数与实体数解耦
- UniformBuffer ring 支持 eStorageBuffer usage(GPUDriven 实例矩阵
per-frame-slot,正确性保证与 UBO 一致:fence 等待后写入)
- DescriptorManager 加 UpdateStorageBuffer;池补 STORAGE_BUFFER 类型
- Set0 新增 binding1 = 实例矩阵 SSBO(vertex 读取,std430)
- Forward pass 重写:每帧从 ECS 收集实例矩阵(按 mesh 聚合 batch,
两趟遍历保证 batch 区间连续),同 mesh 的 N 个实体合并为
一次 drawIndexed(instanceCount=N),firstInstance 指向 batch 起点;
vertex shader 经 gl_InstanceIndex 取模型矩阵,forward 不再用 push
- draw 数 = 唯一 mesh 数,与实体数量解耦(4096 实例上限,
超出截断告警;聚合改哈希为后续 TODO)
验证:8 pass 全活,validation 0 error 0 warning,GPU Timings 面板
实测各 pass 毫秒,场景渲染与阴影正确
|
2026-09-22 19:46:17 +08:00 |
|
atdunbg
|
908e688178
|
feat: ACES tonemap + Bloom 后处理链(Extract/BlurH/BlurV 半分辨率)
- ACES(Narkowicz) 经 push 开关启用,exposure 接 ImGui 滑条
- RG: TextureDesc 支持 sizeScale 相对尺寸;per-pass 渲染尺寸解析
(半分辨率 pass 的 viewport 由此决定)
- RG Toposort 重写:RAW+WAR+WAW 按声明序逐资源建边,支持多写者
ping-pong 资源(旧逻辑对 reader 连接所有 writer,ping-pong 成环)
- GetPhysicalView 缺物理镜像时 throw(ENGINE_FATAL 只记日志不中止)
- 全屏 pass 通用 16B push + 公共录制 lambda,Extract/Blur/Tonemap 复用
|
2026-09-22 19:18:51 +08:00 |
|
atdunbg
|
952ba8135d
|
feat: HDR 管线 + Tonemap pass,显示变换显式建模
管线:Shadow → Forward(写 HDRColor R16G16B16A16F) → Tonemap →
ImGui(loadOp=Load) → Present。对齐 UE/Unity 结构:场景线性值
进 HDR 离屏图,Tonemap(全屏三角,exposure push + gamma 编码)
显式完成显示变换,Backbuffer 只接收显示空间颜色。
- Swapchain 改 B8G8R8A8Unorm:Srgb 附件会硬件二次提亮,UI 泛白
(#4296FA→#8CCBFC);Unorm 下写什么显示什么,编码责任归 Tonemap
- Shader object push range 规则落地:程序级声明——同一 pass 的
全部 shader EXT range 定义必须一致(VUID-08878),layout 同样
按 vertex|fragment 声明,push 调用点覆盖全部声明 stage(VUID-01796)
- Tonemap 装配:Set0 = HDR 图(per-frame-slot 描述符 + GetPhysicalView),
clamp 占位待 ACES 替换,bloom/FXAA 等后处理在 HDR 域插 pass
- CMake 加 imgui_demo.cpp(ShowDemoWindow 链接)
- 修复:m_TonemapDescriptorSets 未 resize 即下标写入(启动即崩)
验证:5 pass 全活,validation 0 error 0 warning,UI 原生色彩无泛白
|
2026-09-22 19:00:56 +08:00 |
|
atdunbg
|
07a3b87001
|
feat: Shadow pass 接入 RenderGraph,支持 SRT 变换与程序化平面
阴影(本修正的核心根因):
- Shadow pass 光源正交写深度(2048 D32),Forward 采样比较;
写入与采样共用同一 lightSpace 矩阵,杜绝姿态/镜像不一致
- 修复:push constant range 64B→128B(原 Shadow pass 推 {lightVP,model}
超出 layout 声明范围 = UB,阴影中模型矩阵读到垃圾导致旋转错乱)
- 修复:ShadowFactor 缺少 NDC→UV 映射(*0.5+0.5),采样区域整体错位
- 修复:RG ShaderRead stage 位值直转(eFragment=0x10 在 PipelineStage2
是 TESSELLATION_CONTROL),改为逐位显式映射
- Camera perspective 深度重映射到 Vulkan [0,1](公式与 ortho 不同:
M22=M22*0.5-0.5, M32*=0.5);光源 ortho remap 用 M32=M32*0.5+0.5
引擎配套:
- TransformComponent 重构为 position/rotation/scale + Compose()
- Texture::CreateSolidColor / Model::CreatePlane 程序化资产
(两段式上传公共路径),AssetManager.CreatePlane 带缓存入口
- RG 新增 GetPhysicalView(h, slot):按帧槽位把 RG 资源绑进外部描述符
(阴影图 per-slot 物理镜像各自绑定)
验证:validation 0 error 0 warning,阴影随实体旋转正确
|
2026-09-22 16:40:54 +08:00 |
|
atdunbg
|
7d628f8d8a
|
添加多模型渲染,添加贴图渲染,添加平行光, 暂时不上传assets
|
2026-09-21 14:07:20 +08:00 |
|
atdunbg
|
381b7c0aa6
|
feat: 搭建 Vulkan 1.4 渲染器骨架,绘制旋转 3D 立方体
使用 Vulkan 1.4 现代路径初始化引擎骨架:
- 用 Shader Object (VK_EXT_shader_object) 替代传统 VkPipeline
- 用 Dynamic Rendering 替代 RenderPass/Framebuffer
- 用 Synchronization2 管理 barrier
核心模块:
- Window:GLFW 封装,GLFW_NO_API 模式,兼容 Wayland
- Log:spdlog 封装
- Types:u32/u64/f32 类型别名
Vulkan 后端:
- Device:Instance、PhysicalDevice、LogicalDevice、Queue 及 feature 查询
- Swapchain:Image、ImageView、DepthBuffer、Recreate
- ShaderManager:SPIR-V 加载与 ShaderEXT 创建
- CommandManager:CommandPool 与主 CommandBuffer
- SyncManager:per-frame Fence 与 ImageAvailable semaphore,per-image RenderFinished semaphore,2 frames in flight
- MemoryAllocator:内存子分配器,256MB block,persistent mapping
- Buffer:VertexBuffer、IndexBuffer、UniformBuffer 封装
- UniformBuffer:每帧上传 MVP 矩阵
- DescriptorManager:DescriptorSetLayout、DescriptorPool、DescriptorSet 及更新
Renderer:
- 协调所有子系统
- 绘制每面不同颜色的旋转 3D 立方体
- 启用 depth test,MVP 矩阵由 GLM 计算
构建:
- CMake 组织 Engine 静态库与 App 可执行文件
- glfw、glm、spdlog 通过 add_subdirectory 引入
|
2026-09-20 23:09:40 +08:00 |
|