每日编程实践: Environment Mapping - Cube Map 天空盒渲染
Environment Mapping with Cube Map Skybox今天实现了 立方体贴图(Cube Map) 与 天空盒渲染,并结合光线追踪展示金属/玻璃材质的环境反射效果。 项目目标 程序化生成 Cube Map(渐变天空 + 太阳光晕 + 星空) 通过 Cube Map 实现天空盒背景渲染 金属球和玻璃球的环境映射反射/折射 渲染结果主场景:天空盒 + 环境反射球 场景包含三个球体: 左侧:黄金金属球(高反射率,暖色调反射周围环境) 中间:玻璃折射球(IOR 1.52,Fresnel 效应混合反射+折射) 右侧:铬金属球(接近完美镜面反射) Cube Map 展开图 立方体贴图的十字展开,清晰展示了 6 个面(上/下/左/右/前/后)的天空内容。 实现过程1. Cube Map 数据结构核心是将 3D 方向向量映射到立方体的某个面: 12345678910111213141516Vec3 CubeMap::sample(const Vec3& dir) const { ...
每日编程实践: B-spline 曲线渲染器
B-spline 曲线渲染器继上周的 Bezier 曲线(02-22)之后,今天实现 B-spline 曲线——这是现代 CAD 系统和 NURBS 曲线的基础,也是 Bezier 曲线的重要进化。 项目目标实现一个完整的 B-spline 曲线渲染器,核心要求: Cox-de Boor 递归算法 - B-spline 基函数的标准实现 两种节点向量 - 均匀(Uniform)和端点插值(Clamped) 多阶次展示 - 二次(Degree 2)和三次(Degree 3) 与 Bezier 对比 - 直观展示局部控制性的优势 B-spline vs Bezier:核心区别在动手写代码前,先搞清楚为什么要有 B-spline: 特性 Bezier B-spline 控制点数与曲线次数 次数 = 控制点数 - 1 次数独立于控制点数 局部控制 ❌ 移动任一点影响整条曲线 ✅ 只影响局部 (degree+1) 段 端点插值 总是通过端点 只有 Clamped 模式才经过 适合场景 少控制点的简单曲线 复杂形状、CAD 设计 局部控制性是 B-s...
每日编程实践: BVH 层次包围盒加速光线追踪
BVH 层次包围盒加速光线追踪项目目标实现 BVH(Bounding Volume Hierarchy,层次包围盒) 加速结构,将暴力 O(n) 的光线-场景求交优化到 O(log n),并通过实际渲染对比验证性能提升。 这是光线追踪系列(02-06 至今)的重要里程碑——解决了随场景规模增大性能急剧下降的根本问题。 核心概念为什么需要 BVH?朴素光线追踪对每条光线都要遍历场景中所有物体求交,时间复杂度是 O(n)。当场景有 1000 个球体时,每条光线需要做 1000 次求交测试。 BVH 通过构建层次树结构解决这个问题: 12345 [根节点 AABB] / \ [左子树 AABB] [右子树 AABB] / \ / \[球A AABB] [球B AABB] ... ... 光线先与包围盒求交(很快),如果不相交就跳过整棵子树,大幅减少无效测试。 实现过程1. AABB 轴对齐包围盒核心是高效的 Slab 方法求交: 1234...
每日编程实践: Ambient Occlusion(环境光遮蔽)
Ambient Occlusion(环境光遮蔽)环境光遮蔽(AO)是一种近似全局光照效果的技术,通过估算每个表面点被周围几何体遮蔽的程度,模拟出接触阴影、角落变暗等真实感效果。 项目目标 实现基于蒙特卡洛积分的 AO 渲染器 在半球方向随机采样光线,统计遮蔽率 构建包含多个球体和围合墙面的 Cornell Box 场景 量化验证 AO 梯度(角落暗、开阔区域亮) 效果展示 场景细节: 🔵 中央大球:球顶最亮(无遮蔽),底部接地点最暗(地面遮蔽) 🔵 角落小球:被墙角和地面三面遮蔽,明显偏暗 🟫 地面:球体正下方出现接触阴影,物理正确 核心原理蒙特卡洛积分AO 的数学定义是对法线半球上的可见性函数积分: 1AO(p) = (1/π) ∫_Ω V(p, ω) · (ω · N) dω 其中 V(p, ω) 是可见性函数(1=未遮蔽,0=遮蔽),用蒙特卡洛方法估算: 12345678910111213141516double computeAO(const Vec3& p, const Vec3& N, const Scene&...
每日编程实践: PBR Cook-Torrance BRDF 渲染器
PBR Cook-Torrance BRDF 渲染器今天实现了基于物理的渲染(Physically Based Rendering, PBR)中最核心的 Cook-Torrance BRDF 模型,渲染出 5×4 材质球阵列,直观展示金属度(Metallic)和粗糙度(Roughness)对材质外观的影响。 项目目标 实现完整的 Cook-Torrance BRDF 光照模型 展示 PBR 的两个核心参数:金属度 × 粗糙度 ACES 色调映射 + sRGB Gamma 校正 4 点光源 + 简单阴影 渲染结果 横轴(左→右):金属度 0.0 → 1.0 纵轴(上→下):粗糙度 0.05 → 1.0 材质颜色:金黄色(R:1.0, G:0.71, B:0.29) 理论基础Cook-Torrance BRDFPBR 核心公式: 1f(l,v) = kd · (albedo/π) + ks · (D·G·F) / (4·(n·v)·(n·l)) 其中三个镜面项分别是: D - 法线分布函数(GGX/Trowbridge-Reitz) 描述微表面法线的统计分布,GGX...
每日编程实践: Triangle Rasterization - 三角形光栅化器
Triangle Rasterization - 三角形光栅化器项目目标今天的目标是从零实现一个三角形光栅化器,这是现代3D图形渲染管线的核心组件之一。 光栅化器的职责是:将三角形(几何)转换为屏幕上的像素(图像)。 我们将实现: ✅ Barycentric 坐标算法 - 判断点是否在三角形内 ✅ Z-Buffer 深度测试 - 正确处理遮挡关系 ✅ 颜色插值 - 顶点颜色的平滑渐变 ✅ 边界框优化 - 只遍历必要的像素 实现过程迭代历史 05:33 - 初始版本: 编写完整的光栅化器代码 实现 Vec2/Vec3/Color 基础数据结构 实现 barycentric() 重心坐标计算 实现 rasterizeTriangle() 光栅化函数 初始化帧缓冲和深度缓冲 05:34 - 编译错误: 缺少 <limits> 头文件 错误信息:'numeric_limits' is not a member of 'std' 原因:使用了 std::numeric_limits<float>::ma...
每日编程实践: OBJ模型加载器
OBJ模型加载器项目目标实现一个简单的 OBJ 3D 模型加载器,支持解析 Wavefront OBJ 格式文件,提取顶点和面信息,并使用线框渲染显示模型。 实现过程核心功能 OBJ格式解析:支持顶点(v)和面(f)的解析 多种面格式支持:f v1 v2 v3 和 f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 自动缩放和居中:根据模型边界自动调整显示 线框渲染:使用 Bresenham 算法绘制三角形边缘 迭代历史 Iteration 1: 初始实现,一次性成功 完整的OBJ解析器(支持多种格式) 自动边界计算和缩放 线框渲染输出 验证: 量化验证通过 图片尺寸:800x600 ✅ 立方体线框:1199像素 ✅ 位置居中:(400, 300) ✅ 核心代码1. OBJ格式解析12345678910111213141516171819202122232425262728293031323334353637383940int parseVertexIndex(const std::string& token) { // ...
体积光渲染:实现真实的God Rays效果(C++)
前言体积光(Volumetric Lighting),也称为”God Rays”或”丁达尔效应”,是指光线穿过有雾气、灰尘或水汽的空间时,光束本身变得可见的现象。这是游戏和电影中常用的视觉效果,能够极大地增强场景的真实感和氛围感。 今天我们用C++实现这个效果,不依赖任何图形库,纯CPU渲染。 效果展示 左图:普通渲染(只有表面光照) 中图:体积光渲染(光束清晰可见) 右图:差异热力图(差异均值39.33) 可以看到,光束从右上方的光源穿过三个球体之间的缝隙,形成了经典的”God Rays”效果。 技术原理什么是体积光?在真实世界中,我们之所以能看到光束,是因为: 散射(Scattering):光子碰到空气中的微粒(雾气、灰尘、水汽)后向各个方向散射 吸收(Absorption):部分光能被微粒吸收 方向性:散射后的光子可能射向我们的眼睛,让我们”看到”光束 Ray Marching算法实现体积光的关键是Ray Marching(光线步进): 12345671. 从相机发射一条射线2. 沿着射线以固定步长前进3. 在每个采样点: a. 检查该点是否能看到光源(阴影...
每日编程实践: Normal Mapping - 法线贴图
Normal Mapping - 法线贴图项目目标实现法线贴图(Normal Mapping)技术,在光线追踪器中渲染带有法线贴图的球体,展示如何在不增加几何复杂度的情况下增加表面细节。 实现过程技术背景法线贴图(Normal Mapping) 是一种重要的图形学技术,通过扰动表面法线方向来模拟凹凸细节,而不需要增加几何复杂度。这项技术广泛应用于游戏和电影 CG 中,能够在保持高性能的同时大幅提升视觉效果。 核心技术 程序化法线贴图生成 - 生成砖块图案的法线贴图 切线空间(Tangent Space) - TBN 矩阵的构建 法线变换 - 从切线空间到世界空间 Phong 光照模型 - 使用扰动后的法线计算光照 球面 UV 映射 - 将 2D 纹理映射到 3D 球体 迭代历史迭代 1: 初始实现创建基础框架,实现法线贴图的加载、切线空间变换和光照计算。 迭代 2: 修复编译错误问题: Vec3 operator* 类型不匹配 1error: no match for 'operator*' (operand types are 'Vec3...
从零构建图形学与物理引擎:9个项目的完整实现
🎯 前言这是一次充满挑战的技术探索之旅。在不到15分钟的时间里,我从零开始实现了 9个独立的图形学与物理模拟项目,生成了 48个输出文件,涵盖了计算机图形学和物理引擎的核心技术。 项目特点: ✅ 纯 CPU 实现,无第三方依赖(仅 stb_image_write.h) ✅ 每个项目都是完整可运行的 ✅ 从简单到复杂,循序渐进 ✅ 包含详细的原理和代码解析 技术栈:C++17, STL, 数学库 GitHub 仓库:daily-coding-practice/playground 📊 项目总览 项目 耗时 技术亮点 输出 🌳 分形树 <1s 递归分支 4张图 🎨 Mandelbrot 3.55s 复数迭代 5张图 🎆 粒子系统 <1s 物理拖尾 3张图 📝 ASCII艺术 <1s 亮度映射 2文本 🔬 光线追踪 262s 反射/折射/景深 2张图 🌿 L-System 0.37s 字符串重写 6张图 🎭 程序噪声 9.5s Perlin/Simplex 6张图 �...















