实现光线追踪
C++实现光线追踪之详解
[参考文章]http://www.cnblogs.com/miloyip/archive/2010/03/29/1698953.html
1. 本文简介
作者正大三,刚好选修到计算机图形学这门课,基于兴趣,便试着实现全局光照的效果,由此,写下此篇文章。
2. 光线追踪
所谓光线追踪,是指从眼睛出发,经过图像平面每一像素,投射光线到场景中,求该光线与场景中几何图形的最近交点,然后求该交点的颜色属性,并将该颜色值记录下来,再根据相交点的材质判断性地进行反射、折射等现象继续追踪计算,最终把多次追踪交点颜色值的结果混合得到最终该像素的颜色值。(本文皆是介绍反向追踪)
-
3. 场景说明
4.1 摄像机
此次实验,本人将摄像机放置于世界坐标系下的Vec3(0,5,15)下,图像平面置于Vec3(0,0,-1)处。注,为了简化,直接将图像设置width,height一致,均为600。
图一
特别注意:\(|front| = 1\)
4.2 场景
本实验中,场景由两个球以及一个无限平面组成。
Sphere1:
Sphere(Vec3(-10,10,-10),float(10))
参数一:球心
参数二:球径
Sphere2:
Sphere(Vec3(-10,10,-10),float(10))
Plane:
在数学表达上,无限平面可表示为\(nP=d\),其中n为平面法向量,d为原点到平面的最短距离。
Plane(Vec3(0,1,0),float(0))
4.3 图像中坐标的转换
最初,图像是600*600的平面,左上角为原点。现先转换为以左下角为原点的[0,1]范围内的平面。
左上角为原点且范围为[0,600]:
\(X = X\)...(1)
\(Y = Y\)...(2)
左下角为原点且范围为[0,1]:
\(X = X/width\)...(2)
\(Y = 1-Y/height\)...(2)
图像中心为原点且范围为[-1,1]:
\(X = 2X-1\)...(3)
\(Y=2Y-1\)...(3)
4. 过程详解
(1)对于图像平面,自左向右,自上而下的经过每一像素投射光线
(2)计算光线与场景中几何图形的最近交点,都无交点即直接返回黑色,进行(5),否则进(3)
(3)取样 即计算最近交点的颜色属性
(4)计算反射光线继续追踪,回到(2)。
(5)赋像素予颜色值,回到(1)
4.1 步骤一之生成光线
由图一可知,
\(Ray.dire = SampleVector+front\)...(4)
\(SampleVector=Vec3(X,Y,0)\)...(5)[注:此时是以中心为原点了]
即可得到初始化的Ray对象Ray(eye.origin,Ray.dire);
转换为中心为原点计算光线原因如下:
4.2 步骤二之计算最近交点
- 光线
\(R(t)=eye.origin+tD\)(t为参数) - 平面
\(nP=d\)
1)判断光线与法向量n是否垂直
2)不垂直即可计算交点
光线与无限平面的法向量位置情况:
由上图可知,当\(n·Ray.dire>=0\)时,没有交点;否则,有交点。
3)交点的计算:
\(D=(d-eys.origin·n)/(t·n)\)
- 球
推导过程复杂,作者不在此详细阐述,有兴趣的朋友可去这里查看
原文地址:https://www.cnblogs.com/LeeQMoon/p/11927538.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- [DeeplearningAI 笔记]第一章2.11-2.16 向量化与 python/numpy 向量说明
- 自己动手作图深入理解二叉树、满二叉树及完全二叉树
- Matlab矩阵加入新元素
- 每个Python程序员都应该知道的10个缩写
- 《剑指offer》第九天:斐波那契数列
- [tensorflow损失函数系列]sigmoid_cross_entropy_with_logits
- 0794-5.16.2-Hive和Imapla查询decimal类型结果不同异常
- 利用TFRecords存储于读取带标签的图片
- matlab sum函数
- [tensorflow损失函数系列]softmax_cross_entropy_with_logits
- RESTful API 设计最佳实践
- Spring 是如何解决循环依赖的?
- 移动webhead参数
- 看了这篇泛型,下次设计链表别傻傻的用int 表示node节点的值了
- 标准TensorFlow格式 TFRecords