Skip to content

Commit f10d680

Browse files
authored
Merge pull request #14 from indevn/main
TBR Pipeline Implementation & Pipeline Optimization
2 parents 461cfe7 + b84cfd2 commit f10d680

21 files changed

Lines changed: 1956 additions & 330 deletions

README-cn.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ cmake --build build-macos --target all
8585
#### 3. 运行示例应用程序
8686

8787
```bash
88-
./build/bin/system_test ../obj
88+
./build/bin/system_test ./obj
8989
```
9090

9191
---

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ cmake --build build-macos --target all
8686
#### 3. Run the Example Application
8787

8888
```bash
89-
./build/bin/system_test ../obj
89+
./build/bin/system_test ./obj
9090
```
9191

9292
---

src/include/face.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Face {
4040
// Get functions
4141
// 获取函数
4242
inline const std::array<size_t, 3>& GetIndices() const { return indices_; }
43-
inline const size_t GetIndex(size_t index) const { return indices_[index]; }
43+
inline size_t GetIndex(size_t index) const { return indices_[index]; }
4444
inline const Material& GetMaterial() const { return material_; }
4545

4646
private:

src/include/log_system.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#ifndef SIMPLERENDER_SRC_INCLUDE_LOG_SYSTEM_H_
1818
#define SIMPLERENDER_SRC_INCLUDE_LOG_SYSTEM_H_
1919

20+
#ifndef SPDLOG_ACTIVE_LEVEL
21+
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
22+
#endif
2023
#include <spdlog/spdlog.h>
2124

2225
namespace simple_renderer {

src/include/rasterizer.hpp

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "config.h"
55
#include "shader.hpp"
6+
#include "vertex.hpp"
67

78
namespace simple_renderer {
89

@@ -15,21 +16,80 @@ class Rasterizer {
1516
auto operator=(Rasterizer&& rasterizer) -> Rasterizer& = default;
1617
~Rasterizer() = default;
1718

19+
/**
20+
* @brief 构造具有指定尺寸的光栅化器
21+
* @param width 光栅化器宽度
22+
* @param height 光栅化器高度
23+
*/
1824
Rasterizer(size_t width, size_t height);
1925

26+
/**
27+
* @brief 光栅化三角形,生成片段列表
28+
* @param v0 三角形第一个顶点
29+
* @param v1 三角形第二个顶点
30+
* @param v2 三角形第三个顶点
31+
* @return 生成的片段向量
32+
*/
2033
std::vector<Fragment> Rasterize(const Vertex& v0, const Vertex& v1,
2134
const Vertex& v2);
2235

36+
/**
37+
* @brief 非分配版本:将片段直接写入调用方提供的容器
38+
*
39+
* 可选的裁剪区域为半开区间 [x0, x1) × [y0, y1)
40+
* 用于 TBR:将光栅化限制在 tile 边界内,便于复用外部 scratch 容器
41+
*
42+
* @param v0 三角形第一个顶点
43+
* @param v1 三角形第二个顶点
44+
* @param v2 三角形第三个顶点
45+
* @param x0 裁剪区域左边界(包含)
46+
* @param y0 裁剪区域上边界(包含)
47+
* @param x1 裁剪区域右边界(不包含)
48+
* @param y1 裁剪区域下边界(不包含)
49+
* @param out 输出片段容器
50+
*/
51+
void RasterizeTo(const Vertex& v0, const Vertex& v1, const Vertex& v2,
52+
int x0, int y0, int x1, int y1,
53+
std::vector<Fragment>& out);
54+
55+
/**
56+
* @brief SoA 版本:按顶点索引从 SoA 读取三角形三顶点
57+
* @param soa 结构体数组格式的顶点数据
58+
* @param i0 三角形第一个顶点索引
59+
* @param i1 三角形第二个顶点索引
60+
* @param i2 三角形第三个顶点索引
61+
* @param x0 裁剪区域左边界(包含)
62+
* @param y0 裁剪区域上边界(包含)
63+
* @param x1 裁剪区域右边界(不包含)
64+
* @param y1 裁剪区域下边界(不包含)
65+
* @param out 输出片段容器
66+
*/
67+
void RasterizeTo(const VertexSoA& soa, size_t i0, size_t i1, size_t i2,
68+
int x0, int y0, int x1, int y1,
69+
std::vector<Fragment>& out);
70+
2371
private:
2472
size_t width_, height_;
2573

74+
// 透视矫正结果
75+
struct PerspectiveCorrectionResult {
76+
Vector3f corrected_barycentric;
77+
float interpolated_z;
78+
};
79+
80+
// 透视矫正helper函数
81+
PerspectiveCorrectionResult PerformPerspectiveCorrection(
82+
float w0, float w1, float w2,
83+
float z0, float z1, float z2,
84+
const Vector3f& original_barycentric) const;
85+
2686
template <typename T>
2787
T Interpolate(const T& v0, const T& v1, const T& v2,
28-
const Vector3f& barycentric_coord);
88+
const Vector3f& barycentric_coord) const;
2989

3090
Color InterpolateColor(const Color& color0, const Color& color1,
3191
const Color& color2,
32-
const Vector3f& barycentric_coord);
92+
const Vector3f& barycentric_coord) const;
3393

3494
std::pair<bool, Vector3f> GetBarycentricCoord(const Vector3f& p0,
3595
const Vector3f& p1,

src/include/renderer.h

Lines changed: 69 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,57 +18,95 @@
1818
#define SIMPLERENDER_SRC_INCLUDE_RENDERER_H_
1919

2020
#include <cstdint>
21-
#include <functional>
22-
#include <span>
21+
#include <memory>
22+
#include <string>
2323

24-
#include "buffer.hpp"
25-
#include "light.h"
2624
#include "log_system.h"
27-
#include "math.hpp"
2825
#include "model.hpp"
29-
#include "rasterizer.hpp"
3026
#include "shader.hpp"
27+
#include "renderers/renderer_base.hpp"
3128

3229
namespace simple_renderer {
3330

31+
// 渲染模式枚举
32+
/**
33+
* @brief 渲染模式
34+
* - PER_TRIANGLE: 逐三角形(triangle-major)前向渲染
35+
* - TILE_BASED: 基于 tile(tile-major)前向渲染
36+
* - DEFERRED: 延迟渲染(片段收集后再着色)
37+
*/
38+
enum class RenderingMode {
39+
PER_TRIANGLE, //!< 逐三角形(triangle-major)
40+
TILE_BASED, //!< 基于 tile(tile-major)
41+
DEFERRED //!< 延迟渲染
42+
};
43+
44+
/**
45+
* @brief 将渲染模式枚举转为可读字符串
46+
* @param mode 渲染模式
47+
* @return 可读字符串(PER_TRIANGLE/TILE_BASED/DEFERRED)
48+
*/
49+
std::string RenderingModeToString(RenderingMode mode);
50+
51+
/**
52+
* @brief 渲染门面(Facade)
53+
*
54+
* 职责:
55+
* - 仅作为模式选择与调用入口;
56+
* - 根据 `RenderingMode` 构造并持有具体渲染器;
57+
* - 对外暴露统一的 `DrawModel` 接口。
58+
*/
3459
class SimpleRenderer {
3560
public:
3661
/**
37-
* 构造函数
38-
* @param width
39-
* @param height
40-
* @param buffer 要进行绘制的内存区域,大小为 width*height*sizeof(uint32_t)
41-
* @param
62+
* @brief 构造渲染器门面
63+
* @param width 画布宽度(像素)
64+
* @param height 画布高度(像素)
4265
*/
4366
SimpleRenderer(size_t width, size_t height);
67+
~SimpleRenderer() = default;
4468

45-
/// @name 默认构造/析构函数
46-
/// @{
47-
SimpleRenderer(const SimpleRenderer &_simplerenderer) = default;
48-
SimpleRenderer(SimpleRenderer &&_simplerenderer) = default;
49-
auto operator=(const SimpleRenderer &_simplerenderer) -> SimpleRenderer & =
50-
default;
51-
auto operator=(SimpleRenderer &&_simplerenderer) -> SimpleRenderer & =
52-
default;
53-
virtual ~SimpleRenderer() = default;
54-
/// @}
69+
/**
70+
* @brief 绘制单个模型
71+
* @param model 模型
72+
* @param shader 着色器(含 uniform)
73+
* @param buffer 输出颜色缓冲(width*height)
74+
* @return 是否成功
75+
*/
76+
bool DrawModel(const Model &model, const Shader &shader, uint32_t *buffer);
5577

56-
bool Render(const Model &model, const Shader &shader, uint32_t *buffer);
78+
/**
79+
* @brief 设置渲染模式
80+
*/
81+
void SetRenderingMode(RenderingMode mode);
82+
/**
83+
* @brief 获取当前渲染模式
84+
*/
85+
RenderingMode GetRenderingMode() const;
86+
87+
// 可选:配置参数(仅对 TileBasedRenderer 生效;运行中修改将重建 TBR 实例)
88+
/**
89+
* @brief 启用或禁用 Early‑Z(仅 TBR 有效)
90+
*/
91+
void SetEarlyZEnabled(bool enabled);
92+
/**
93+
* @brief 设置 Tile 大小(仅 TBR 有效)
94+
*/
95+
void SetTileSize(size_t tile_size);
96+
97+
private:
98+
void EnsureRenderer();
5799

58100
private:
59101
const size_t height_;
60102
const size_t width_;
61103
LogSystem log_system_;
104+
RenderingMode current_mode_;
105+
std::unique_ptr<RendererBase> renderer_;
62106

63-
std::shared_ptr<Shader> shader_;
64-
std::shared_ptr<Rasterizer> rasterizer_;
65-
66-
/**
67-
* 绘制模型
68-
* @param model 模型
69-
*/
70-
void DrawModel(const Model &model, uint32_t *buffer);
71-
void DrawModelSlower(const Model &model, uint32_t *buffer);
107+
// TBR 配置缓存:在创建 TileBasedRenderer 时下发
108+
bool tbr_early_z_ = true;
109+
size_t tbr_tile_size_ = 64;
72110
};
73111
} // namespace simple_renderer
74112

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef SIMPLERENDER_SRC_INCLUDE_RENDERERS_DEFERRED_RENDERER_HPP_
2+
#define SIMPLERENDER_SRC_INCLUDE_RENDERERS_DEFERRED_RENDERER_HPP_
3+
4+
#include "renderers/renderer_base.hpp"
5+
6+
namespace simple_renderer {
7+
8+
/**
9+
* @brief 延迟渲染器(Deferred)
10+
*
11+
* 组织处理方式模拟 OpenGL 在 GPU上的工作原理,模仿 GPU管线。
12+
* 但相比于另外两个前向渲染实现,导致内存使用增加和渲染速度变慢。
13+
*
14+
* 特点:
15+
* - AoS 顶点路径;
16+
* - 首先按像素收集所有片段并选择最近深度;
17+
* - 再对选择的片段执行片段着色(模拟经典 GPU 管线的一种教学实现)。
18+
* -
19+
*/
20+
class DeferredRenderer final : public RendererBase {
21+
public:
22+
using RendererBase::RendererBase;
23+
/**
24+
* @copydoc RendererBase::Render
25+
*/
26+
bool Render(const Model& model, const Shader& shader, uint32_t* out_color) override;
27+
};
28+
29+
} // namespace simple_renderer
30+
31+
#endif // SIMPLERENDER_SRC_INCLUDE_RENDERERS_DEFERRED_RENDERER_HPP_
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef SIMPLERENDER_SRC_INCLUDE_RENDERERS_PER_TRIANGLE_RENDERER_HPP_
2+
#define SIMPLERENDER_SRC_INCLUDE_RENDERERS_PER_TRIANGLE_RENDERER_HPP_
3+
4+
#include "renderers/renderer_base.hpp"
5+
6+
namespace simple_renderer {
7+
8+
/**
9+
* @brief 逐三角形渲染器(Triangle‑Major)
10+
*
11+
* 特点:
12+
* - AoS 顶点路径;
13+
* - 每线程本地 framebuffer(depth/color)合并;
14+
* - 背面剔除在屏幕空间完成;
15+
* - 接近“传统”栈式前向渲染教学实现。
16+
*/
17+
class PerTriangleRenderer final : public RendererBase {
18+
public:
19+
using RendererBase::RendererBase;
20+
/**
21+
* @copydoc RendererBase::Render
22+
*/
23+
bool Render(const Model& model, const Shader& shader, uint32_t* out_color) override;
24+
};
25+
26+
} // namespace simple_renderer
27+
28+
#endif // SIMPLERENDER_SRC_INCLUDE_RENDERERS_PER_TRIANGLE_RENDERER_HPP_
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Renderer base and options
2+
#ifndef SIMPLERENDER_SRC_INCLUDE_RENDERERS_RENDERER_BASE_HPP_
3+
#define SIMPLERENDER_SRC_INCLUDE_RENDERERS_RENDERER_BASE_HPP_
4+
5+
#include <cstdint>
6+
#include <memory>
7+
8+
#include "rasterizer.hpp"
9+
#include "vertex.hpp"
10+
#include "model.hpp"
11+
#include "shader.hpp"
12+
13+
namespace simple_renderer {
14+
15+
16+
/**
17+
* @brief 渲染器抽象基类
18+
*
19+
* 约定:
20+
* - Render 负责完成完整的渲染过程(顶点变换 + 光栅化 + 着色 + 写入输出缓冲)。
21+
* - 子类选择不同的“组织单元”:(按照并行组织单元)逐三角形、按 tile、或延迟管线。
22+
* - 公共的透视除法与视口变换在此提供,子类按需复用。
23+
*/
24+
class RendererBase {
25+
public:
26+
RendererBase(size_t width, size_t height)
27+
: width_(width), height_(height), rasterizer_(std::make_shared<Rasterizer>(width, height)) {}
28+
virtual ~RendererBase() = default;
29+
30+
RendererBase(const RendererBase&) = delete;
31+
RendererBase& operator=(const RendererBase&) = delete;
32+
33+
/**
34+
* @brief 执行一次渲染
35+
* @param model 模型数据
36+
* @param shader 着色器(包含材质/光照/矩阵等 uniform)
37+
* @param out_color 输出颜色缓冲(大小为 width*height)
38+
* @return 是否渲染成功
39+
*/
40+
virtual bool Render(const Model& model, const Shader& shader, uint32_t* out_color) = 0;
41+
42+
protected:
43+
/**
44+
* @brief 透视除法:裁剪空间 -> NDC
45+
* @param vertex 裁剪空间顶点
46+
* @return NDC 顶点(保留 1/w 以供透视校正)
47+
*/
48+
Vertex PerspectiveDivision(const Vertex& vertex);
49+
/**
50+
* @brief 视口变换:NDC -> 屏幕坐标
51+
* @param vertex NDC 顶点
52+
* @return 屏幕空间顶点
53+
*/
54+
Vertex ViewportTransformation(const Vertex& vertex);
55+
56+
protected:
57+
size_t width_;
58+
size_t height_;
59+
std::shared_ptr<Rasterizer> rasterizer_;
60+
61+
static constexpr float kMinWValue = 1e-6f;
62+
};
63+
64+
} // namespace simple_renderer
65+
66+
#endif // SIMPLERENDER_SRC_INCLUDE_RENDERERS_RENDERER_BASE_HPP_

0 commit comments

Comments
 (0)