From 68804eab7d96d53b10fdd07793b3efc1cb737f9a Mon Sep 17 00:00:00 2001 From: SepComet <2428390463@qq.com> Date: Fri, 20 Mar 2026 19:58:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=99=E5=85=A5=20DepthBuffer=20=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=BA=A6=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CPU-Software-Renderer/CONVENTIONS.md | 41 +++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/CPU-Software-Renderer/CONVENTIONS.md b/CPU-Software-Renderer/CONVENTIONS.md index f4f26ab..c530a17 100644 --- a/CPU-Software-Renderer/CONVENTIONS.md +++ b/CPU-Software-Renderer/CONVENTIONS.md @@ -97,14 +97,41 @@ `Camera::get_viewport_matrix()` 里也对 `Y` 做了翻转,因此 NDC 的“向上”为正,最终会映射成屏幕坐标“向下”为正。 -## 8. Demo 中的可见性规则 +## 8. 深度缓冲约定 -`main.cpp` 里的旋转立方体示例,目前采用的是一个简化版隐藏线规则: +当前项目已经接入 `Core::DepthBuffer`,并采用以下规则: -- 先在 view space 中判断哪些面朝向相机 -- 再把这些可见面的边标记为可绘制 -- 最后只绘制被标记出来的边 +- `DepthBuffer` 存储类型为 `float` +- 每帧开始时必须调用 `depthBuffer->clear()`,默认清为 `INFINITY` +- 当前约定为“深度值越小,离相机越近” +- 深度测试通过后,必须同时更新 `DepthBuffer` 和 `FrameBuffer` +- `DepthBuffer` 只负责存储和读取深度,不负责决定颜色写入逻辑;是否写颜色由光栅化阶段决定 -这只是一个 demo 级别的近似方案,不是完整的隐藏线消除算法。 +当前三角形光栅化里的深度流程为: -后续如果项目要加入更严格的裁剪、剔除或可见性规则,应当以代码实现为准,并同步更新本文档。 +- 在屏幕空间遍历三角形包围盒 +- 以像素中心 `x + 0.5, y + 0.5` 作为采样点 +- 用屏幕空间 `x/y` 计算重心坐标 +- 用同一组重心坐标判断点是否在三角形内,并插值顶点 `z` +- 若新深度更近,则写入 `DepthBuffer` 和 `FrameBuffer` + +也就是说: + +- 重心坐标的计算是二维问题,只使用屏幕空间 `x/y` +- 顶点 `z` 的插值使用这组重心权重完成 +- 当前实现是屏幕空间线性插值,后续如果引入纹理、法线或更严格的属性插值,需要进一步考虑透视校正插值 + +## 9. Demo 中的可见性规则 + +`main.cpp` 里的旋转立方体示例,目前采用以下可见性与遮挡规则: + +- 三角形是否参与光栅化,仍由投影合法性检查和背面剔除决定 +- 三角形之间的遮挡,不再依赖按平均深度排序,而是由 `DepthBuffer` 逐像素决定 +- 当前 demo 仍保留按面筛选后的轮廓线绘制,用于显示黑色边框 + +这意味着: + +- `DepthBuffer` 不能替代投影合法性检查或背面剔除 +- `DepthBuffer` 负责的是像素级遮挡,而不是顶点级或三角形级是否进入渲染流程 + +后续如果项目要加入更严格的裁剪、剔除、透视校正插值或隐藏线规则,应当以代码实现为准,并同步更新本文档。 \ No newline at end of file