ZigZagK的博客
一个周末就学会光线追踪 (test ver.)
AT4
2024年3月31日 01:21
图形学
查看标签

Ray Tracing in One Weekend

原始内容 https://raytracing.github.io/books/RayTracingInOneWeekend.html

Output an Image 输出一个图像

PPM 图像格式

PPM (portable pixmap) 是一种无损压缩的图像格式,这是维基上的介绍:

PPM介绍

创建图像版 "HelloWorld"

在 VSCode 中创建一个目录,包含如下文件

在 rayTracing.cpp 中写入能输出一个图像的内容:

// rayTracing.cpp
#include <iostream>

int main() {

    // image
    
    int image_width = 256;
    int image_height = 256;
    
    // render
    
    std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
    
    for (int j = 0; j < image_height; ++j) {
        for (int i = 0; i < image_width; ++i) {
            auto r = double(i) / (image_width - 1);
            auto g = double(j) / (image_height - 1);
            auto b = 0;
            
            int ir = static_cast<int>(255.999 * r);
            int ig = static_cast<int>(255.999 * g);
            int ib = static_cast<int>(255.999 * b);
            
            std::cout << ir << ' ' << ig << ' ' << ib << '\n';
        }
    }
}

关于这个代码的一些注意事项:

cmake_minimum_required(VERSION 3.0)

project(rayTracing)

add_executable(rayTracing rayTracing.cpp)

在 VSCode 中按下 Shift+Ctrl+P,搜索 CMake: Configure, 打开 CMake 配置,选择一个 C++ 构建工具等待完成配置,之后在 Shift+Ctrl+P 中搜索 CMake: Build 或者按下 F7 进行构建,面板中会输出编译出的可执行文件。具体也可以参考:【软件构建: CMake 快速入门】

打开 VSCode 的终端,一般这时候终端会显示你在根目录下,而可执行文件一般构建在 Build 目录下,所以此时先输入:

cd build

将文件重定向为 PPM 文件:

.\rayTracing.cpp > image.ppm

通常电脑无法直接打开 PPM 文件,推荐使用一个在线的 PPM Viewer, 或者也可以使用 VSCode 的 PBM/PPM/PGM Viewer for Visual Studio Code 插件,我们可以得到如下的图片:

结果图

完美!符合预期,这就是图形的 "HelloWorld".

Progress Indicator 进度指示器

在输出中添加一个进度指示器,可以观察长渲染的进度,并识别出一些可能的无限循环等问题。上面的程序将渲染结果输出至标准输出流 std::cout,我们将进度指示器输出至日志记录输出流 std::clog

for (int j = 0; j < image_height; ++j) {
    std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush;
    for (int i = 0; i < image_width; ++i) {
        auto r = double(i) / (image_width - 1);
        auto g = double(j) / (image_height - 1);
        auto b = 0;
        
        int ir = static_cast<int>(255.999 * r);
        int ig = static_cast<int>(255.999 * g);
        int ib = static_cast<int>(255.999 * b);
        std::cout << ir << ' ' << ig << ' ' << ib << '\n';
    }
}
std::clog << "\rDone.                 \n";

现在,在运行时,将显示剩余扫描行数的运行计数

进度指示器 正在运行

进度指示器 正在运行

版权声明:本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处!