zoukankan      html  css  js  c++  java
  • 【Ray Tracing in One Weekend 超详解】 光线追踪1-1

    Preface

    从这一篇起,我们开始学光线追踪这门牛逼的技术。读了几天,一个字:强!

    这一篇我们主要讲述技术入门和一些简单的案例。

    我们先学这本:

            

    Ready

    这本书需要ppmview这个软件帮忙看效果图,不过下载也非常快。

    其次,需要你会C/C++读写文件

    最后需要你具备三维空间想象能力以及我对书中公式的讲述

    Chapter1: Output an image

    先看一张图,秒懂一下它如何设置像素

    话说,有这么一个文件,叫做.ppm文件。它以水平向右为x正方向,以垂直向下为y正方向。

    它的文件存储内容解读如上,关于第一行的P3是指文件的type

    P3下面那两个数指的是列数和行数,或者你可以理解为x轴的长度和y轴的长度,或者理解为图像的宽和高。

    再下面一行有一个数为像素的最大值

    之后有x*y个(r,g,b)三元组,它会按照顺序读取,并且在图像的左上角开始一行一行扫描设置像素值

    所以我们现在开始写代码实现上面那个图像,但是我按照上面的输入到文件中,由于只有6个像素点,我几乎看不到任何图像,我不知道你们的情况,所以我自己设定一个例子:

    我设定上面那个图像的每一个颜色方格为20*20尺寸的。然后每个方格对应自己的像素值。

    代码如下:

    #define stds std::
    void build_1_1()
    {
        const stds string s1[3] = { "255 0 0","0 255 0","0 0 255" };
        const stds string s2[3] = { "255 255 0","255 255 255","0 0 0" };
    
        stds ofstream file("graph1-1.ppm");
        if (file.is_open())
        {
            file << "P3
    " << 60 << " " << 40 << "
    255
    ";
            for (int i = 0; i < 20; ++i)
                for (int j = 0; j < 60; ++j)
                    file << s1[j / 20] << stds endl;
    
            for (int i = 0; i < 20; ++i)
                for (int j = 0; j < 60; ++j)
                    file << s2[j / 20] << stds endl;
            file.close();
            stds cout << "complished" << stds endl;
        }
        else stds cerr << "error" << stds endl;
    }

    然后我们用ppmview打开就是这样的:

        

    好了,大家估计明白了我们这个文件的使用

    那我们来整一个好玩的。

    这是书上的代码,如果你能够看懂,那固然很好,不过看不懂也没关系

    它说了个啥意思呢?

    它先设置三个量r,g,b,它们的值在[0,1),然后通过乘255.99将值映射到[0,255]

    好了我们可以看第一个像素:(0,255,0.2),应该是绿色的,如果觉得blue的0.2有点干扰,你可以设为0(建议这么做),第一行扫完之后,也就是内部for第一次跳出的时候,那个像素是(255,255,0.2),差不多是r和g组合,接近黄色,那么第一行就是r从0到255,绿色到黄色渐变。用同样的方法,我们可以知道,左下角这个点应该是近黑色,右下角应该是近红色。中间的内容是线性插值得到的像素值。

     Chapter 2:The vec3 class

     此章节,以及后面的部分,数学部分直接引用现写的3D数学库

    转到:https://www.cnblogs.com/lv-anchoret/p/10163085.html

     

    这一章就是将上述rgb用三维向量表示:

    #define LOWPRECISION
    
    #include <fstream>
    #include <lvgmlvgm.h>
    using namespace lvgm;
    
    #define stds std::
    
    void build_1_2()
    {
        int X = 400, Y = 200;
        stds ofstream file("graph2-1.ppm");
        if (file.is_open())
        {
            file << "P3
    " << X << " " << Y << "
    255
    ";
            for (int j = Y - 1; j >= 0; --j)
                for (int i = 0; i < X; ++i)
                {
                    dvec3 col(double(i) / X, double(j) / Y, 0.0);
                    int ir = int(255.99*col.r());
                    int ig = int(255.99*col.g());
                    int ib = int(255.99*col.b());
                    file << ir << " " << ig << " " << ib << stds endl;
                }
            file.close();
            stds cout << "complished" << stds endl;
        }
        else
            stds cerr << "load file failed!" << stds endl;
    }
    
    
    int main()
    {
        build_1_2();
    
    }

    把blue改为0,图像就清晰多了

    由于今日天色已晚,咱们明天继续

    感谢您的阅读,晚安~

  • 相关阅读:
    九连环
    Fruit Ninja(取随机数)
    Distinct Values(贪心)
    Harvest of Apples
    Don't Be a Subsequence
    ConvexScore
    守卫
    Trie树
    NOIP 2005 过河
    HDU 4597 Play Game 记忆化DP
  • 原文地址:https://www.cnblogs.com/lv-anchoret/p/10163205.html
Copyright © 2011-2022 走看看