问题十二:怎么用ray tracing画第一张图
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画第一张图相关推荐
- 问题五十:怎么用ray tracing画blobs
这一节,画这个: 参考文献: Blinn, J.F., A generalization of algebraic surfacedrawing. ACM Trans. Graph. 1(3) , 2 ...
- 问题六十:怎么用ray tracing画回旋体(rotational sweeping / revolution)
60.1 概述 回旋体,大概是长这个样子: 回旋体是指曲线(称为"基本曲线")围绕y轴转一圈得到的图形. (基本曲线是由多段b-spline曲线段连接而成) 这里先强调一下: 上图 ...
- 问题十三:怎么用ray tracing画个球
当然这个球是画在之前的背景图上. 通过画第一张图,已经直到画图有两个步骤:其一,确定位置(范围.大小):其二,设置颜色. 画球也不例外. 第一步:确定球的位置.球上每个像素点的位置即为光线与球的交点, ...
- 问题五十三:怎么用ray tracing画参数方程表示的曲面(1)
首先,以球面为例学习怎么用ray tracing画参数方程表示的曲面:然后,再画一个牛角面. 特别说明:这一章节所画的曲面只是示意性的,所以先不care图片上的瑕疵. 53.1 数学推导 球面的参数方 ...
- 问题三十三:怎么用ray tracing画特殊长方体(box)
33.1 怎么用ray tracing画特殊长方体 在光线追踪中被用到的一种常见形态是长方体盒子.这种基本物体被用于可见物体和包围盒,包围盒被用于加速复杂物体的相交测试. 吐槽:单词都认识,就是不知道 ...
- 第十二周项目4-利用遍历思想求解图问题(6-7)
/* Copyright (c)2015,烟台大学计算机与控制工程学院 All rights reserved. 文件名称:第十二周项目4-利用遍历思想求解图问题(6-7) 作 者:佟兴锋 完成日期: ...
- python plt.subplot_Python plt 利用subplot 实现在一张画布同时画多张图
subplot(arg1, arg2, arg3) arg1: 在垂直方向同时画几张图 arg2: 在水平方向同时画几张图 arg3: 当前命令修改的是第几张图 plt.figure()另起一张新的画 ...
- php 图片画图片格式,php 用图片处理函数画一张图
一起来看看下面有一张图: 我们该怎么把这张图给画出来呢. 我们按照步骤能够分析出来: 1.画图 2.准备好画这张图需要的颜色 3.填充背景颜色 4.画两条对角线 5.在上面画一个圆 6.在圆上面画一个 ...
- python matplotlib画多个图_python matplotlib模块 如何画两张图出来
展开全部 python matplotlib模块 如何画两张图出2113来的方法:5261 代码如下所示: import numpy as np import matplotlib.pyplot as ...
最新文章
- IOS开发-地图 (mapkit)实验
- IromPython .Net 的简介和第一个例子
- Oracle - 行转列, 列转行
- mysql列宽设置,mysql – 从.csv文件确定最佳列宽
- jooq_jOOQ API设计缺陷的怪异事件
- 好程序员web分享图片标签、绝对路径和相对路径
- Android模块化之MicroModule(微信Pins工程) 1
- 【优化求解】基于狼群算法WPA求解最优目标matlab代码
- 高等数学微积分公式大全
- 吉客云与金蝶云星空集成方案(吉客云主管库存)
- AUTOCAD——成组命令
- Drain算法:日志解析
- 是时候展示真正的云存储黑科技了!
- 只需3步把VSCode打造成Markdown编辑器
- 无需越狱,iPhone修改微信提示音!
- 关于蓝牙打印机的一些问题
- 人效提高350%,基于KICP搭建的营销套电客服机器人,让欧派家居赢在起点
- 数电课设数字钟设计(基于quartus)
- was部署java项目_web工程was部署
- 腾讯校招课堂|程序员如何在腾讯完成自己的“游戏梦”
热门文章
- mysql常用基础操作语法(九)~~外连接查询【命令行模式】
- 优雅的使用Python之软件管理
- WP8开发日志(3):MVC设计模式进阶——绑定多个数据集
- python基础:os.path的相关操作
- 【Oracle】进阶知识进一步了解
- Spark2.2(三十九):如何根据appName监控spark任务,当任务不存在则启动(任务存在当超过多久没有活动状态则kill,等待下次启动)...
- sqlserver 迁移
- python---图表的使用
- ERROR: ld.so: object '/usr/lib64/libtcmalloc.so.4' from LD_PRELOAD cannot be preloaded: ignored
- CentOS 安装 rz sz