ray 类:(位于ray.h中。ray.cpp为空)

#ifndef RAY_H
#define RAY_H
#include "vec3.h"class ray
{public:ray() {}ray(const vec3& a, const vec3& b) { A = a; B = b; }vec3 orgin() const     { return A; }vec3 direction() const { return B; }vec3 point_at_parameter(float t) const { return A + t*B; }//已知t时,可以获得光线上该点的坐标(向量)vec3 A;vec3 B;/*virtual ~ray();protected:private:
*/
};#endif // RAY_H

ray类中其实主要是定义两个向量:起点向量(坐标)A和方向向量B。

从ray的方程R(t)=A+t*B可以得知A,B两个向量即可决定一条光线。

    #include <iostream>#include <fstream>#include "ray.h"using namespace std;vec3 color(const ray& r){vec3 unit_direction = unit_vector(r.direction());float t = 0.5*(unit_direction.y() + 1.0);return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0);}int main(){int nx = 200;int ny = 100;ofstream outfile( ".\\results\\RaysBackgroundY.txt", ios_base::out);outfile << "P3\n" << nx << " " << ny << "\n255\n";std::cout << "P3\n" << nx << " " << ny << "\n255\n";vec3 lower_left_corner(-2.0, -1.0, -1.0);vec3 horizontal(4.0, 0.0, 0.0);vec3 vertical(0.0, 2.0, 0.0);vec3 origin(0.0, 0.0, 0.0);for (int j = ny-1; j >= 0; j--){for (int i = 0; i < nx; i++){float u = float(i) / float(nx);float v = float(j) / float(ny);ray r(origin, lower_left_corner + u*horizontal + v*vertical);vec3 col = color(r);int ir = int (255.99*col[0]);int ig = int (255.99*col[1]);int ib = int (255.99*col[2]);outfile << ir << " " << ig << " " << ib << "\n";std::cout << ir << " " << ig << " " << ib << "\n";}}}

原理分析:

光线起点(也就是eye或者camera)固定的情况下,光线的方向向量的变动范围既形成光线束。光线束即是eye或者camera看到画面。

也就意味着:方向向量的变动范围决定着所能看到画面的范围。

另外,光线中每个光子的频率(颜色)决定这画面的内容。

所以,如果我们要通过光线追踪来画图的话,只需要做两件事情:

第一步,确定光线的方向向量的活动范围函数,从而确定画面的范围、大小(一条光线对应这画面上的一个像素点)。

第二步,对每一条光线(像素点)设置颜色,(高质量图的每个像素点上可能对应多个采样)从而确定画面上的内容。

如下图,光线的起点为(0,0,0),要求在黑框内作图(即光线和黑框平面的交点落在黑框内)

        vec3 lower_left_corner(-2.0, -1.0, -1.0);vec3 horizontal(4.0, 0.0, 0.0);vec3 vertical(0.0, 2.0, 0.0);

所以,交点坐标可以表示为向量:lower_left_corner + u*horizontal + v*vertical

光线的方向向量 = 交点的向量 - 起点向量,由于起点为原点,所以方向向量=交点向量。

每个交点的u,v的值即为该像素点在整个画面中的位置。

        int nx = 200;int ny = 100;for (int j = ny-1; j >= 0; j--){for (int i = 0; i < nx; i++){float u = float(i) / float(nx);float v = float(j) / float(ny);
    ray r(origin, lower_left_corner + u*horizontal + v*vertical);
    /*由画面中每个像素点在画面中的相对位置每个像素点对应的光线的方向向量从而确定画面的范围/大小。(完成第一步)*/vec3 col = color(r);
    //根据光线对每一个像素点上色。(完成第二步)
    }}vec3 color(const ray& r){vec3 unit_direction = unit_vector(r.direction());
//对方向向量进行标准化。float t = 0.5*(unit_direction.y() + 1.0);
//标准化之后的y值在[-1,1]中y+1在[0,2]中0.5*(y+1)在[0,1]中return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0);//t=0时,color=vec3(1,1,1),乘以255后对应的RGB为(255,255,255)//t=1时,color=vec3(0.5,0.7,1),乘以255后对应的RGB为(127.5,178.5,255)//如上两个颜色分别对应着“白色”和“浅蓝色”。
/*画面颜色=(1-t)*“白色”+ t*“浅蓝色”,即画面颜色为“白色”和“浅蓝色”(沿着Y方向)的线性插值的结果。如果要换成X或者Z方向,将上面的.y()改成.x()或者.z()即可。
若要换其他颜色,设置对应的RGB值即可。RGB值和颜色的对应可参考word中“字体颜色设置”“ 其他颜色”“自定义”*/
}

通过“XnView”将结果的.txt转换成.jpg后的图片:

白色、浅蓝色沿着Y轴线性插值:

白色、浅蓝色沿着X轴线性插值:

白色、浅蓝色沿着Z轴线性插值:

白色、粉红色沿着Y轴线性插值:

问题十二:怎么用ray tracing画第一张图相关推荐

  1. 问题五十:怎么用ray tracing画blobs

    这一节,画这个: 参考文献: Blinn, J.F., A generalization of algebraic surfacedrawing. ACM Trans. Graph. 1(3) , 2 ...

  2. 问题六十:怎么用ray tracing画回旋体(rotational sweeping / revolution)

    60.1 概述 回旋体,大概是长这个样子: 回旋体是指曲线(称为"基本曲线")围绕y轴转一圈得到的图形. (基本曲线是由多段b-spline曲线段连接而成) 这里先强调一下: 上图 ...

  3. 问题十三:怎么用ray tracing画个球

    当然这个球是画在之前的背景图上. 通过画第一张图,已经直到画图有两个步骤:其一,确定位置(范围.大小):其二,设置颜色. 画球也不例外. 第一步:确定球的位置.球上每个像素点的位置即为光线与球的交点, ...

  4. 问题五十三:怎么用ray tracing画参数方程表示的曲面(1)

    首先,以球面为例学习怎么用ray tracing画参数方程表示的曲面:然后,再画一个牛角面. 特别说明:这一章节所画的曲面只是示意性的,所以先不care图片上的瑕疵. 53.1 数学推导 球面的参数方 ...

  5. 问题三十三:怎么用ray tracing画特殊长方体(box)

    33.1 怎么用ray tracing画特殊长方体 在光线追踪中被用到的一种常见形态是长方体盒子.这种基本物体被用于可见物体和包围盒,包围盒被用于加速复杂物体的相交测试. 吐槽:单词都认识,就是不知道 ...

  6. 第十二周项目4-利用遍历思想求解图问题(6-7)

    /* Copyright (c)2015,烟台大学计算机与控制工程学院 All rights reserved. 文件名称:第十二周项目4-利用遍历思想求解图问题(6-7) 作 者:佟兴锋 完成日期: ...

  7. python plt.subplot_Python plt 利用subplot 实现在一张画布同时画多张图

    subplot(arg1, arg2, arg3) arg1: 在垂直方向同时画几张图 arg2: 在水平方向同时画几张图 arg3: 当前命令修改的是第几张图 plt.figure()另起一张新的画 ...

  8. php 图片画图片格式,php 用图片处理函数画一张图

    一起来看看下面有一张图: 我们该怎么把这张图给画出来呢. 我们按照步骤能够分析出来: 1.画图 2.准备好画这张图需要的颜色 3.填充背景颜色 4.画两条对角线 5.在上面画一个圆 6.在圆上面画一个 ...

  9. python matplotlib画多个图_python matplotlib模块 如何画两张图出来

    展开全部 python matplotlib模块 如何画两张图出2113来的方法:5261 代码如下所示: import numpy as np import matplotlib.pyplot as ...

最新文章

  1. IOS开发-地图 (mapkit)实验
  2. IromPython .Net 的简介和第一个例子
  3. Oracle - 行转列, 列转行
  4. mysql列宽设置,mysql – 从.csv文件确定最佳列宽
  5. jooq_jOOQ API设计缺陷的怪异事件
  6. 好程序员web分享图片标签、绝对路径和相对路径
  7. Android模块化之MicroModule(微信Pins工程) 1
  8. 【优化求解】基于狼群算法WPA求解最优目标matlab代码
  9. 高等数学微积分公式大全
  10. 吉客云与金蝶云星空集成方案(吉客云主管库存)
  11. AUTOCAD——成组命令
  12. Drain算法:日志解析
  13. 是时候展示真正的云存储黑科技了!
  14. 只需3步把VSCode打造成Markdown编辑器
  15. 无需越狱,iPhone修改微信提示音!
  16. 关于蓝牙打印机的一些问题
  17. 人效提高350%,基于KICP搭建的营销套电客服机器人,让欧派家居赢在起点
  18. 数电课设数字钟设计(基于quartus)
  19. was部署java项目_web工程was部署
  20. 腾讯校招课堂|程序员如何在腾讯完成自己的“游戏梦”

热门文章

  1. mysql常用基础操作语法(九)~~外连接查询【命令行模式】
  2. 优雅的使用Python之软件管理
  3. WP8开发日志(3):MVC设计模式进阶——绑定多个数据集
  4. python基础:os.path的相关操作
  5. 【Oracle】进阶知识进一步了解
  6. Spark2.2(三十九):如何根据appName监控spark任务,当任务不存在则启动(任务存在当超过多久没有活动状态则kill,等待下次启动)...
  7. sqlserver 迁移
  8. python---图表的使用
  9. ERROR: ld.so: object '/usr/lib64/libtcmalloc.so.4' from LD_PRELOAD cannot be preloaded: ignored
  10. CentOS 安装 rz sz