File tree Expand file tree Collapse file tree 6 files changed +506
-0
lines changed
Expand file tree Collapse file tree 6 files changed +506
-0
lines changed Original file line number Diff line number Diff line change 1+ # Ray Tracing in One Weekend
Original file line number Diff line number Diff line change 1+ # 1. 概述
2+
3+
4+ 多年来我教授了很多图形学课程,常常使用光线追踪来教学,因为它迫使你编写所有的代码,但不依赖 API 也能生成很酷的图像。我决定将我的课程笔记整理成一个实践指南,帮助你尽快实现一个有趣的程序。它不会是一个功能全面的光线追踪器,但会包括间接光照——这是光线追踪在电影中大放异彩的关键所在。按部就班地跟着做,你最终构建的光线追踪架构将非常适合日后扩展成更完整的系统。
5+
6+ 当人们说“光线追踪”时,可能指很多不同的技术。而我将要讲解的,其实是一个路径追踪器,而且是比较通用的那种。虽然代码会非常简单(让计算机多干活!),但我相信你会对它生成的图像感到满意。
7+
8+ 我将按照我自己的习惯顺序带你一步步实现一个光线追踪器,并分享一些调试技巧。到最后,你将拥有一个能生成优质图像的光线追踪器。这个过程你在一个周末内就能完成。如果花得更久也没关系。我用的是 C++ 作为主要语言,但你不一定非得用它。不过我建议你还是用 C++,因为它快、跨平台,而且目前电影和游戏中的多数渲染器也是用它写的。需要说明的是,我尽量不使用太多“现代 C++”的特性,但继承和操作符重载在光线追踪中非常有用,我保留了它们。
9+
10+ 我不会在网上直接发布完整代码,但这些代码都是真实的,除了 vec3 类中的一些简单操作符以外,我会展示全部代码。我坚信动手敲代码才能学会它;但如果代码现成可用我也会用,所以当我不分享代码时才是真正践行了这个理念。——不过我留下这段话,是因为我后来180度大转弯了。有不少读者在实现时遇到细节错误,彼此对比代码后得到了帮助。所以我建议你还是亲自敲一遍代码,但你也可以在 GitHub 上的 RayTracing 项目中找到每本书对应的最终源码。
11+
12+ 关于这些书中代码的实现,有几点原则我们始终坚持:
13+
14+ * 所有代码都应体现书中讲解的核心概念。
15+
16+ * 虽然使用 C++,但尽可能简洁。我们的风格更偏向 C,但会适当使用现代特性以提升易用性或可读性。
17+
18+ * 编码风格尽量延续最初几本书的传统,以保持一致性。
19+
20+ * 行长度控制在每行不超过 96 个字符,以确保代码在代码库和书籍中展示一致。
21+
22+
23+ 因此,这些代码为你提供了一个基础实现,剩下的优化空间和现代化改进则留给读者自行探索。这些代码是可以不断优化的,而我们优先选择的是简单明了的方案。
24+
25+ 我们假设你对向量有一些基础了解,比如点乘和向量加法。如果你还不了解,建议先复习一下。可参考 Morgan McGuire 的《Graphics Codex》在线文档,Steve Marschner 与 Peter Shirley 合著的《Fundamentals of Computer Graphics》,或者 J.D. Foley 和 Andy Van Dam 的《Computer Graphics: Principles and Practice》。
26+
27+ 查看项目的 README 文件可以了解项目详情,包括 GitHub 仓库地址、目录结构、编译与运行说明、错误修正与贡献方法等内容。
28+
29+ 如需进一步阅读相关资源,请查看我们的 wiki 页面“Further Reading”。
30+
31+ 这些书已经排版优化过,可直接通过浏览器打印,同时每次发布中也包含对应的 PDF 文件,在“Assets”部分可以找到。
32+
33+ 如果你想与我们联系,欢迎通过邮件交流:
34+
35+ * Peter Shirley:
[email protected] 36+
37+ * Steve Hollasch:
[email protected] 38+
39+ * Trevor David Black:
[email protected] 40+
41+
42+ 最后,如果你在实现过程中遇到问题,有一般性问题,或希望分享自己的创意与成果,请访问该项目的 GitHub Discussions 论坛。
43+
44+ 感谢所有为这个项目做出贡献的人,他们的名字列在本书末尾的致谢部分。
45+
46+ 那我们开始吧!
Original file line number Diff line number Diff line change 1+ # 2. 输出图像
2+ ## 2.1. PPM 图像格式
3+
4+ 每当你启动一个渲染器时,你需要某种方式来查看图像。最直接的方法就是将图像写入文件。不过问题在于,图像格式有很多种,其中大多数都很复杂。我总是从一个纯文本的 PPM 文件开始。下面是 Wikipedia 上对其的简要描述:
5+
6+ 图 1:PPM 示例
7+
8+ 让我们写点 C++ 代码来输出这样一个图像:
9+
10+ ``` cpp
11+
12+ #include < iostream>
13+
14+ int main () {
15+
16+ // Image
17+
18+ int image_width = 256;
19+ int image_height = 256;
20+
21+ // Render
22+
23+ std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
24+
25+ for (int j = 0; j < image_height; j++) {
26+ for (int i = 0; i < image_width; i++) {
27+ auto r = double(i) / (image_width-1);
28+ auto g = double(j) / (image_height-1);
29+ auto b = 0.0;
30+
31+ int ir = int(255.999 * r);
32+ int ig = int(255.999 * g);
33+ int ib = int(255.999 * b);
34+
35+ std::cout << ir << ' ' << ig << ' ' << ib << '\n';
36+ }
37+ }
38+ }
39+
40+ ```
41+
42+ 代码清单 1:[ main.cc] 创建你的第一张图像
43+
44+ 这段代码中有几点需要注意:
45+
46+ * 像素是按行写出的。
47+
48+ * 每一行像素从左到右写出。
49+
50+ * 所有的行自顶向下依次写出。
51+
52+ * 按惯例,红/绿/蓝三个通道内部使用 0.0 到 1.0 的实数表示。在输出前,需要将其缩放到 0 到 255 的整数范围。
53+
54+ * 从左到右,红色从完全关闭(黑)渐变到完全开启(亮红);从上到下,绿色从完全关闭(黑)渐变到完全开启(亮绿)。红光和绿光混合后会变成黄色,所以我们应该预期图像右下角是黄色的。
Original file line number Diff line number Diff line change 11# Summary
2+ - [ Ray Tracing in One Weekend] ( ./RT_in_OneWeekend/RT_in_OneWeekend.md )
3+ - [ Overview] ( ./RT_in_OneWeekend/overview.md )
4+ - [ Output an Image] ( ./RT_in_OneWeekend/output_an_image.md )
5+ - [ The PPM Image Format] ( ./RT_in_OneWeekend/ppm.md )
6+
27- [ Direct3D 12] ( dx12/dx12.md )
38 - [ Important Changes] ( dx12/important_changes.md )
49 - [ Hardware Feature Levels] ( dx12/hardware_feature_levels.md )
3237 - [ shader linking] ( ./shaderlinking.md )
3338 - [ 变量定义] ( ./变量定义.md )
3439
40+ - [ 代码资源] ( ./code.md )
41+
You can’t perform that action at this time.
0 commit comments