问题三十:《Ray Tracing In One Weekend》封面图形生成

198 篇文章 12 订阅
195 篇文章 27 订阅

30.1 封面图片

先完成封面图片。

Code如下:

----------------------------------------------main.cpp------------------------------------------

main.cpp

    hitable *random_scene() {
        int n = 500;
        hitable **list = new hitable *[n+1];
/*定义一个包含n+1个元素的数组,数组的每个元素是指向hitable对象的指针。然后将数组的指针赋值给list。所以,list是指针的指针。*/
        list[0] = new sphere(vec3(0,-1000,0), 1000, new lambertian(vec3(0.5, 0.5, 0.5)));
/*先创建一个中心在(0,-1000,0)半径为1000的超大漫射球,将其指针保存在list的第一个元素中。*/
        int i = 1;
        for (int a = -11; a < 11; a++) {
            for (int b = -11; b < 11; b++) {
/*两个for循环中会产生(11+11)*(11+11)=484个随机小球*/
                float choose_mat = (rand()%(100)/(float)(100));
/*产生一个(0,1)的随机数,作为设置小球材料的阀值*/
                vec3 center(a+0.9*(rand()%(100)/(float)(100)), 0.2, 
b+0.9*(rand()%(100)/(float)(100)));
/*” a+0.9*(rand()%(100)/(float)(100))”配合[-11,11]产生(-11,11)之间的随机数,而不是[-11,11)之间的22个整数。使得球心的x,z坐标是(-11,11)之间的随机数*/
                if ((center-vec3(4,0.2,0)).length() > 0.9) {
/*避免小球的位置和最前面的大球的位置太靠近*/
                    if (choose_mat < 0.8) {     //diffuse
/*材料阀值小于0.8,则设置为漫反射球,漫反射球的衰减系数x,y,z都是(0,1)之间的随机数的平方*/
                        list[i++] = new sphere(center, 0.2,
                		new lambertian(vec3(
(rand()%(100)/(float)(100))*(rand()%(100)/(float)(100)),
(rand()%(100)/(float)(100))*(rand()%(100)/(float)(100)),
(rand()%(100)/(float)(100))*(rand()%(100)/(float)(100)))));
                    }
                    else if (choose_mat < 0.95) {
/*材料阀值大于等于0.8小于0.95,则设置为镜面反射球,镜面反射球的衰减系数x,y,z及模糊系数都是(0,1)之间的随机数加一再除以2*/
                        list[i++] = new sphere(center, 0.2,
                                    new metal(vec3(0.5*(1+(rand()%(100)/(float)(100))),
0.5*(1+(rand()%(100)/(float)(100))),
0.5*(1+(rand()%(100)/(float)(100)))),
0.5*(1+(rand()%(100)/(float)(100))));
                    }
                    else {
/*材料阀值大于等于0.95,则设置为介质球*/
                        list[i++] = new sphere(center, 0.2, new dielectric(1.5));
                    }
                }
            }
        }

        list[i++] = new sphere(vec3(0, 1, 0), 1.0, new dielectric(1.5));
        list[i++] = new sphere(vec3(-4, 1, 0), 1.0, new lambertian(vec3(0.4, 0.2, 0.1)));
        list[i++] = new sphere(vec3(4, 1, 0), 1.0, new metal(vec3(0.7, 0.6, 0.5), 0.0));
/*定义三个大球*/
        return new hitable_list(list, i);
    }

书上坑爹的是,没有给出相机参数,而是直接贴了张结果图。坑爹啊!我是根据三个大球在画面中的相对位置,调了一组参数,得到的图片和参考图片近似吧。

 

       vec3 lookfrom(11,2,3);

       vec3 lookat(0,0.6,0);

       float dist_to_focus = (lookfrom - lookat).length();

       float aperture = 0.0;

       camera cam(lookfrom, lookat, vec3(0,1,0), 20, float(nx)/float(ny), aperture,0.7*dist_to_focus);


调试过程中的几张图片

       vec3 lookfrom(11,1,4);

       vec3 lookat(0,1,0);

       float dist_to_focus = (lookfrom - lookat).length();

       float aperture = 0.0;

       camera cam(lookfrom, lookat, vec3(0,1,0), 20, float(nx)/float(ny), aperture,0.7*dist_to_focus);


        vec3 lookfrom(11,1,3.5);

       vec3 lookat(0,0.6,0);

       float dist_to_focus = (lookfrom - lookat).length();

       float aperture = 0.0;

       camera cam(lookfrom, lookat, vec3(0,1,0), 20, float(nx)/float(ny), aperture,0.7*dist_to_focus);



改变/增加大球后的code如下:

----------------------------------------------main.cpp------------------------------------------

main.cpp

    hitable *random_scene() {
        int n = 500;
        hitable **list = new hitable *[n+1];
        list[0] = new sphere(vec3(0,-1000,0), 1000, new lambertian(vec3(0.5, 0.5, 0.5)));
        int i = 1;
        for (int a = -11; a < 11; a++) {
            for (int b = -11; b < 11; b++) {
                float choose_mat = (rand()%(100)/(float)(100));
                vec3 center(a+0.9*(rand()%(100)/(float)(100)), 0.2, 
b+0.9*(rand()%(100)/(float)(100)));
                if ((center-vec3(4,0.2,0)).length() > 0.9) {
                    if (choose_mat < 0.8) {     //diffuse
                        list[i++] = new sphere(center, 0.2,
                		new lambertian(vec3(
(rand()%(100)/(float)(100))*(rand()%(100)/(float)(100)),
(rand()%(100)/(float)(100))*(rand()%(100)/(float)(100)),
(rand()%(100)/(float)(100))*(rand()%(100)/(float)(100)))));
                    }
                    else if (choose_mat < 0.95) {
                        list[i++] = new sphere(center, 0.2,
                                    new metal(vec3(0.5*(1+(rand()%(100)/(float)(100))),
0.5*(1+(rand()%(100)/(float)(100))),
0.5*(1+(rand()%(100)/(float)(100)))),
0.5*(1+(rand()%(100)/(float)(100))));
                    }
                    else {
                        list[i++] = new sphere(center, 0.2, new dielectric(1.5));
                    }
                }
            }
        }

        list[i++] = new sphere(vec3(-6, 2, -6), 2.0, new metal(vec3(0.7, 0.6, 0.5), 0.0));
        list[i++] = new sphere(vec3(6, 2, -6), 2.0, new metal(vec3(0.7, 0.6, 0.5), 0.0));

        list[i++] = new sphere(vec3(0, 2, -7), 2.0, new metal(vec3(0.7, 0.6, 0.5), 0.0));

        list[i++] = new sphere(vec3(-2, 1, -4), 1.0, new dielectric(1.5));
        list[i++] = new sphere(vec3(2, 1, -4), 1.0, new dielectric(1.5));
        list[i++] = new sphere(vec3(0, 1, 0), 1.0, new dielectric(1.5));

        list[i++] = new sphere(vec3(-4, 1, -2), 1.0, new lambertian(vec3(0.4, 0.2, 0.1)));
        list[i++] = new sphere(vec3(4, 1, -2), 1.0, new lambertian(vec3(0.4, 0.2, 0.1)));

        list[i++] = new sphere(vec3(-6, 1, 0), 1.0, new metal(vec3(0.7, 0.6, 0.5), 0.0));
        list[i++] = new sphere(vec3(6, 1, 0), 1.0, new metal(vec3(0.7, 0.6, 0.5), 0.0));

        return new hitable_list(list, i);
    }

 不同的观测角度,得到不同的几张图片:

       vec3 lookfrom(0,1,8);

       vec3 lookat(0,3,-8);

       float dist_to_focus = (lookfrom - lookat).length();

       float aperture = 0.0;

       camera cam(lookfrom, lookat, vec3(0,1,0), 40, float(nx)/float(ny), aperture,0.7*dist_to_focus);


        vec3 lookfrom(0,8,8);

       vec3 lookat(0,0,-4);

       float dist_to_focus = (lookfrom - lookat).length();

       float aperture = 0.0;

       camera cam(lookfrom, lookat, vec3(0,1,0), 40, float(nx)/float(ny), aperture,0.7*dist_to_focus);


30.2 What next?

1. Lights. You can do this explicitly, bysending shadow rays to lights. Or it can be done implicitly by making someobjects emit light.

2. biasing scattered rays toward them, andthen downweighting those rays to cancel out the bias. Both work. I am in theminority in favoring the latter approach.

3. Triangles. Most cool models are intriangles form. The model I/O is the worst and almost everybody tries to getsomebody else’s code to do this.

4. Surface textures. This lets you pasteimages on like wall paper. Pretty easy and a good thing to do.

5. Solid textures. Ken Perlin has his codeonline. Andrew Kensler has some very cool info at his blog.

6. Volumes and media. Cool stuff and willchallenge your software architecture. I favor making volumes have the hitableinterface and probabilistically have intersections based on density. Yourrendering code doesn’t even have to know it has volumes with that method.

7. Parallelism. Run N copies of your codeon N cores with different random seeds. Average the N runs. This averaging canalso be done hierarchically where N/2 pairs can be averaged to get N/4 images,and pairs of those can be averaged. That method of parallelism should extendwell into the thousands of cores with very little coding.

 

30.3 补充封面图片标准答案

在第二本书《ray tracing the next week》(还没买,只能试读一章)的第一章中看到了这个标准答案。

       vec3 lookfrom(13,2,3);

       vec3 lookat(0,0,0);

       float dist_to_focus = (lookfrom - lookat).length();

       float aperture = 0.0;

       camera cam(lookfrom, lookat, vec3(0,1,0), 20, float(nx)/float(ny), aperture, 0.7*dist_to_focus);


其实之前已经调到(11,2,3)(0,0.6,0)已经很接近了。

 

 

------------------------------------《Ray TracingIn One Weekend》学习完毕------------------------------------



  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值