《一周学完光线追踪》学习 三 光线相机和背景
蒙特卡洛光线追踪技术系列 见 蒙特卡洛光线追踪技术
所有光线跟踪器都有一个光线类,以及计算沿光线看到的颜色。让我们把射线看作一个函数,p(t)=A+t*B,这里p是3D中沿直线的3D位置,a是射线的原点,B是射线的方向。射线参数t是实数(代码中的浮点数)。插入不同的t和p(t)沿射线移动点。
加上负t,你就可以得到3D线上的任何地方。对于正t,你只得到A前面的部分,这就是通常所说的半线或射线。示例C=p(2)如下所示:
现在我们准备好转弯,做一个光线跟踪器。光线跟踪器的核心是通过像素发送光线,并计算在光线方向上看到的颜色。它的形式是计算从眼睛到像素的光线,计算光线与像素相交的部分,并计算该相交点的颜色。在第一次开发光线跟踪器时,我总是用一个简单的相机来启动和运行代码。我还做了一个简单的颜色(光线)函数,返回背景的颜色(一个简单的渐变)。
我经常在使用正方形图像进行调试时遇到麻烦,因为我经常转换x和y,所以我将坚持使用200x100图像(这里我还是用的512*512的图像)。我将把“眼睛”(或者相机中心,如果你想到相机的话)设为(0,0,0)。我让y轴向上,x轴向右。为了尊重右手坐标系的对流,进入屏幕的是负z轴。我将从左下角遍历屏幕,并使用沿屏幕边的两个偏移向量来移动屏幕上的光线端点。请注意,我没有将光线方向设置为单位长度向量,因为我认为不这样做会使代码更简单、速度略快。
在下面的代码中,光线r接近像素中心(我现在不担心精确性,因为我们稍后将添加抗锯齿):
#ifndef RAY_H
#define RAY_H#include "Vector3.h"class Ray {
public:Ray() {}Ray(const Vector3& a, const Vector3& b) { data[0] = a; data[1] = b; data[2] = Vector3(1.0f / b.x(), 1.0f / b.y(), 1.0f / b.z());posneg[0] = (data[1].x() > 0 ? 0 : 1);posneg[1] = posneg[0] ^ 1;posneg[2] = (data[1].y() > 0 ? 0 : 1);posneg[3] = posneg[2] ^ 1; posneg[4] = (data[1].z() > 0 ? 0 : 1);posneg[5] = posneg[4] ^ 1; }Ray(const Ray& r) {*this = r;}Vector3 origin() const {return data[0];}Vector3 direction() const {return data[1];}Vector3 invDirection() const {return data[2];}void setOrigin(const Vector3& v) {data[0] = v;}void setDirection(const Vector3& v) {data[1] = v;data[2] = Vector3(1.0f / v.x(), 1.0f / v.y(), 1.0f / v.z());posneg[0] = (data[1].x() > 0 ? 0 : 1);posneg[1] = posneg[0] ^ 1;posneg[2] = (data[1].y() > 0 ? 0 : 1);posneg[3] = posneg[2] ^ 1; posneg[4] = (data[1].z() > 0 ? 0 : 1);posneg[5] = posneg[4] ^ 1; }Vector3 pointAtParameter(float t) const { return data[0] + t*data[1]; }Vector3 data[3];int posneg[6];
};#endif
写个程序测试一下:
Vector3 lower_left_corner(-2.0, -1.0, -1.0);Vector3 horizontal(4.0,0.0,0.0);Vector3 vertical(0.0,2.0,0.0);Vector3 origin(0.0, 0.0, 0.0);for (int j = HEIGHT-1;j >= 0;j--) {for (int i = 0;i < WIDTH;i++) {int offset = (WIDTH*i + j) * 4;float u = float(i) / float(WIDTH);float v = float(j) / float(HEIGHT);Ray r(origin, lower_left_corner+u*horizontal+v*vertical);Vector3 col((u-0.5)*(u-0.5)+(v-0.5)*(v-0.5),0.0,0.0);Pixels[offset + 0] = (unsigned char)255.99*col[0];Pixels[offset + 1] = (unsigned char)255.99*col[1];Pixels[offset + 2] = (unsigned char)255.99*col[2];Pixels[offset + 3] = 255;}}
得到效果如图:
《一周学完光线追踪》学习 三 光线相机和背景相关推荐
- 《一周学完光线追踪》学习 十一点五 离焦模糊代码原理分析
蒙特卡洛光线追踪技术系列 见 蒙特卡洛光线追踪技术 首先分析一下生成随机Ray的程序: vec3 random_in_unit_disk() {vec3 p;do {p = 2.0*vec3(rand ...
- 十天学完Vue学习总结
一.学习时间的安排 每次学习一门新语言的时候,我会习惯性创建一个文件夹,到我学完Vue基础时一共用了十天的时间.每一天几乎是一个知识点,或者是知识点对于的作业或者是项目. 二.共有多少个知识点可以学习 ...
- 如何两周学完操作系统?我是这样做的
非科班转码用考研书来学习操作系统真的高效又通俗易懂 (怕大家说我是营销号,我把书籍的机构给抹除了) 结合授课视频和辅导书真的能够快速学完操作系统,而且是高质量学完,视频能够讲解算法具体细节,以及相关操 ...
- 《学一辈子光线追踪》 三 光散射
蒙特卡洛光线追踪技术系列 见 蒙特卡洛光线追踪技术 这一小节全都是文字,但是比较重要.虽然之前在 三维渲染 光能辐射基础 三维渲染 BRDF双向反射分布函数 三维渲染 相位函数 三维渲染 体照明模型 ...
- 一周学完MyBatis源码,万字总结
点击下方"IT牧场",选择"设为星标" 之前,我给大家分享给很多MyBatis源码分析的一系列文章.今天,就自己的感受来做一个整体的总结. 众所周知,MyBat ...
- python能开发什么产品_三周学 Python ?不,三周做个产品
我的同事在看到毫无开发经验的我用三周时间,不但从零基础用上了 Python,还做出了一个客户关系管理系统,强烈邀请我分享经验.惶恐,因为我并没有出色的智商,也没有觉得三周学 Python 是一个体现自 ...
- 2019公需科目快速学完_3周考过科目二,是这样做到的!
科目二作为驾培的重要考试科目,每个学员都想快速考过.到底要练多久?多长时间能考过也很困惑. 实践证明,学员跟着教练这样练,3周就能过~ 一. 科目二训练项目 采用学时制,全国大部分地区需要在场地进行至 ...
- C语言学习——从零开始学编程(第三篇:选择与循环)
文章目录 前言--小颖的话 一.语句 1)C语言中的语句有哪些 2)语句 二.选择语句 1) if选择语句 1. if语句 2.if-else语句 3.if - else if - else 多分支语 ...
- 学习Java好找工作吗?Java学完后薪资怎么样?
作为编程届的头牌语言,Java历经数十年仍然占据语言排行榜前三.正是因为如此,很多人在转行的时候首先考虑的就是学习Java.那么,学习Java好找工作吗?Java学完后薪资怎么样?自然是很多人学习后最 ...
最新文章
- nagios 监控NFS
- union all与空字段的一种用法
- Flutter Widget截图
- 用 C++ 跟你聊聊“桥接模式” | 原力计划
- Redhat=》中文
- 杰控连接mysql_杰控组态手册22.数据库连接.pdf
- 信号跟单时提示mt4与服务器断开,MT4平台操作中遇到的一些常见问题和解决方法 -...
- 北斗时钟同步服务器,电力系统卫星时钟-GPS北斗时钟方案
- 如何使用Vegas进行调音?
- 拼多多商家使用拼多多上传图片尺寸软件教程
- 【HAVENT原创】Mac 下编译 ReactNative(CRN) 踩坑记录
- crystaldiskmark使用
- 给衣服加图案photoshop教程
- 22万抢注“活动”双拼域名,95后创业者却因困意失之交臂
- VMware虚拟机运行时报The CPU has been disabled by the guest operating system错误的解决方法
- 关于Unity LitJson写入数据报错的问题
- 呼唤IT企业的个人英雄主义
- 量化交易 多因子打分法策略
- 现有n个阶梯,你有两种上法,一次走一步或着走两步,问一共有多少种上法
- 安装系统正在为首次使用计算机ghost,win7系统安装程序显示正在为首次使用计算机做准备的解决方法...