smallpt: Global Illumination in 99 lines of C++讲解
smallpt: Global Illumination in 99 lines of C++
- 光线追踪
- 正向光线追踪
- 逆向光线追踪介绍
- 蒙特卡罗光线追踪算法
- 非透明材质
- 漫反射材质
- 镜面反射材质
- 透明材质
- 反射与折射
- 折射光线方向的计算:斯涅尔定律
- 折射光线与反射光线混合:菲涅耳公式
smallpt: Global Illumination in 99 lines of C++
光线追踪
正向光线追踪
正向光线追踪符合常识:光线从发光物体出发出,“撞击”到被观察物体上,经过一系列光线传输进入人眼。
因此正向光线追踪的基本流程可以简述为:
- 追踪从发光体发射的所有光线
- 检测光线是否“撞击”物体
- 如果没有“撞击”物体,直接抛弃
- 如果撞击到物体。看反射光线是否直接射入人眼
-如果没有直接射入人眼,则其可能经过一系列传输才射入人眼(间接射入人眼),需要进步判断
-如果直接射入人眼,则计算当前反射光线的颜色,作为该撞击点的颜色
从上述流程不难可以看出,正向光线追踪需要追所有光线。而在这所有光线中,只有一部分光线会“撞击”到观察体,“撞击”到观察体的光线也只有部分会射入人眼。因此追踪所有光线,计算量大且做无用功较多。
逆向光线追踪介绍
追踪光线的方向与正向相反:从眼睛处射出光线,追踪光线射击到物体后,是否能回到光源。如果能则说明该点被光源照亮,否则物体上该点可能被间接照亮,需要进一步判断。
逆向光线追踪为什么比正向光线追踪号好呢?
因为从图形学的角度来看
人眼发射出的光线是有限的,而光源发射出的光线是无限的:人眼接收图像是二维的像素组成的。每个像素记录着该点的颜色。也即对于每个像素计算其颜色, 代表着该像素上一次光线追踪的结果。
因此逆向光线追踪的基本流程可以简述为:
FOR 每个像素点 :构造人眼入射光线Ray光线追踪Ray :计算与光线Ray相交的最近的物体ObjIF obj == null :该像素点颜色为缺省值:全局环境光AmbientColorContinueELSE 看反射光Reflection是否能直接与光源相连(未被其他物体遮挡)IF 没有被遮挡该像素点颜色为光源颜色在该材质上的作用ELSE IF 被遮挡 该像素点颜色根据反射光的光线追踪结果得到。
蒙特卡罗光线追踪算法
个人理解,不对欢迎指正
蒙特卡洛思想介绍
蒙特卡罗光线追踪对逆向光线追踪模型进行改进,其中最大的区别在于把概率模型引入光线追踪。
- 逆向光线追踪中物体的表面材质很单一。引入俄罗斯赌盘轮,可以设定漫反射、镜面反射、甚至折射的概率。丰富表面材质的显示
- 每个像素点只采样一条光线计算出的颜色,正确率不高。引入蒙特卡罗可以多次采样求平均,优化渲染结果。
根据上述分析光线追踪算法中最重要的步骤可以分解成两个:
- 射线与多边形物体的求交判断(空间划分kdTree)
- 光线追踪这个递归子算法(包括对各种材质的处理)
下面由于准备材料不够,我先只主要介绍方面2:
非透明材质
漫反射材质
漫反射材质表现为表面不规则,因此反射光线的方向无法确定判断。它朝可能的任意方向反射。
我们假定对于漫反射材质,反射光线的方向范围可以限定在以撞击点为圆心,撞击点法相为中心的半圆内。
假设:
入射光线为Ray(x0, d0)。其中x0表示光线起点 d代表光线方向
入射光线与物体表面的相交点为x
入射光线与物体表面相交点x出的法向为n
目标:求反射光线Reflection Ray(x, d1).
1.构建以x点为中心,n为一个坐标轴的笛卡尔直角坐标系
w = n
u=((fabs(w.x)>.1?Vec(0,1,0):Vec(1,0,0)) * w).norm()
v=w * u
u/v/w即组成一个笛卡尔直角坐标系
2.将反射光线方向d1分解为u/v/w表示形式
如下图所示
d1 = |d1| * cosα * cosθ * u + |d1| * sinα * w + |d1| * cosα * sinθ * v
其中α为 [0, PI/2]中的随机数;θ为[0,2*PI]中的随机数
这两个步骤对应smallpt: Global Illumination in 99 lines of C++中代码片段56-60:
if (obj.refl == DIFF){ // Ideal DIFFUSE reflection double r1=2*M_PI*erand48(Xi), r2=erand48(Xi), r2s=sqrt(r2); Vec w=nl, u=((fabs(w.x)>.1?Vec(0,1):Vec(1))%w).norm(), v=w%u; Vec d = (u*cos(r1)*r2s + v*sin(r1)*r2s + w*sqrt(1-r2)).norm(); return obj.e + f.mult(radiance(Ray(x,d),depth,Xi)); }
镜面反射材质
镜面反射比较简单,反射光线可假定严格按照反射定律来求(入射角定于反射角)
假设:
入射光线为Ray(x0, d0)。其中x0表示光线起点 d代表光线方向
入射光线与物体表面的相交点为x
入射光线与物体表面相交点x出的法向为n
目标:求反射光线Reflection Ray(x, d1).
具体计算步骤如下图所示
d1 = d0 - n * 2 * (n * d0)
这两个步骤对应smallpt: Global Illumination in 99 lines of C++中代码片段61-62:
else if (obj.refl == SPEC) // Ideal SPECULAR reflection return obj.e + f.mult(radiance(Ray(x,r.d-n*2*n.dot(r.d)),depth,Xi));
透明材质
反射与折射
非透明材质在光线追踪的过程中,要不是漫反射,要不是镜面反射。与非透明材质不同,透明材质在光线作用下,反射和折射是同时存在的(全反射除外)。因此在光线追踪透明材质时,需要同时考虑这两种发射情况。
折射光线方向的计算:斯涅尔定律
简单介绍一下斯涅尔定律,它主要是描述清楚了入射角与折射角之间的关系:
n1sinθ1 = n2sinθ2
其中n1/n2是两个介质的折射率;θ1/θ2分别是入射角/折射角
折射光线方向计算:
假设:
入射光线为Ray(x0, d0)。其中x0表示光线起点 d代表光线方向
入射光线与物体表面的相交点为x
入射光线与物体表面相交点x出的法向为n
两种介质的折射率分别为n1、n2
目标:求折射光线Reflection Ray(x, d1).
这个步骤对应smallpt: Global Illumination in 99 lines of C++中代码片段68:
Vec tdir = (r.d*nnt - n*((into?1:-1)*(ddn*nnt+sqrt(cos2t)))).norm();
考虑全反射:入射角大于某一临界角θc(光线远离法线)时,折射光线将会消失,所有的入射光线将被反射。
当折射角等于90°时,入射角即达到临界角。
这部分步骤对应smallpt: Global Illumination in 99 lines of C++中代码片段63-67:
Ray reflRay(x, r.d-n*2*n.dot(r.d)); // Ideal dielectric REFRACTION
bool into = n.dot(nl)>0; // Ray from outside going in?
double nc=1, nt=1.5, nnt=into?nc/nt:nt/nc, ddn=r.d.dot(nl), cos2t;
if ((cos2t=1-nnt*nnt*(1-ddn*ddn))<0) // Total internal reflection 全反射return obj.e + f.mult(radiance(reflRay,depth,Xi));
折射光线与反射光线混合:菲涅耳公式
这部分步骤对应smallpt: Global Illumination in 99 lines of C++中代码片段69-73
double a=nt-nc, b=nt+nc, R0=a*a/(b*b), c = 1-(into?-ddn:tdir.dot(n));
double Re=R0+(1-R0)*c*c*c*c*c,Tr=1-Re,P=.25+.5*Re,RP=Re/P,TP=Tr/(1-P);
return obj.e + f.mult(depth>2 ? (erand48(Xi)<P ? // Russian roulette 俄罗斯赌盘radiance(reflRay,depth,Xi)*RP:radiance(Ray(x,tdir),depth,Xi)*TP) : radiance(reflRay,depth,Xi)*Re+radiance(Ray(x,tdir),depth,Xi)*Tr);
待更新
参考:
1.smallpt: Global Illumination in 99 lines of C++
2.scratchapixel: Introduction to Ray Tracing: a Simple Method for Creating 3D Images
3.scratchapixel:Rendering an Image of a 3D Scene: A Light Simulator
4.百度百科:斯涅尔定律、菲涅耳公式
5.知乎:如何用 C++ 实现光线跟踪软渲染器?
smallpt: Global Illumination in 99 lines of C++讲解相关推荐
- 全局光照技术解析Global Illumination Explained
解析全局光照Global Illumination Explained 前言:Global Illumination全局光照技术是实时渲染的必然发展方向.我参考了一些研究成果,琢磨了一下,让更多的人可 ...
- Real-Time Rendering——Chapter 9 Global Illumination
radiance is the final quantity computed by the rendering process. 渲染的最终结果是计算辐射率.我们使用反射率方程进行求解. so fa ...
- 实时高清渲染:全局光照(Global Illumination)[1]
目录 基础知识: Radiance: Irradiance: Radiant flux: Radiant Intensity: Solid Angle: Lambertian surface: Lam ...
- Unity Global Illumination(Unity 全局光照 ) 官方手册笔记系列之Enlighten
Enlighten 本文档主要是对Unity官方手册的个人理解与总结(其实以翻译记录为主:>) 仅作为个人学习使用,不得作为商业用途,欢迎转载,并请注明出处. 文章中涉及到的操作都是基于Unit ...
- UE建筑可视化全局照明学习 Unreal Engine: Global Illumination for Arch. Visualization
虚幻引擎:建筑可视化的全局照明 你会学到: 使用轻量级地理信息引擎 聚焦胃肠计算 生成灯光贴图Uv 轻度烘焙 控制光反弹 使用环境遮挡 动画和地理信息 暴露 保存高分辨率图像 课程获取:UE建筑可视化 ...
- SVO实时全局光照优化(里程碑MK2):Sparse Voxel Octree based Global Illumination (SVO GI)...
自主实现的实时渲染引擎,对标对象ue4/ce5,超越u3d/klayge.MK2版本侧重于质量与速度的均衡,以下上传示范均为实测截图,均为全分辨率(网页上显示缩小了)1080p/60fps. 转载于: ...
- Q89:全局光照(Global Illumination)——Path Tracing(只用于间接光照)
89.1 Path Tracing只用于间接光照 根据Path Trace的算法,只有当最终的反射光线撞击到发光材质物体时,才会对最初的撞击点进行"有效"着色,否则着色为" ...
- Q88:全局光照(Global Illumination)——Path Tracing算法生成反射焦散效果的图形
由于在镜面反射中,光线几乎可以保持来自光源的全部能量,并在表面曲度和折射率的作用下,产生聚焦或者发散,当这种光线接触到场景中其它对象的表面时,又会产生新的照明效果,于是焦散便产生了. 简而言之,即是: ...
- Q88:全局光照(Global Illumination)——Path Tracing
88.1 引入(Introduction) 截至当前,回忆一下我们学过的针对直接光照和间接光照的不同反射模型. 直接光照: Phong反射模型.包含漫反射部分和高光反射部分. 间接光照: 对于镜面材料 ...
最新文章
- iOS App上架流程(2016详细版)
- 概率论 第四章 随机变量的数字特征
- 火狐浏览器百度网盘服务器响应,火狐浏览器打不开百度网盘怎么解决?解决百度网盘打不开的步骤分享...
- printf(%d,5.01)和printf(%f,5)的输出结果
- 手机射频电路全面解析
- 学生健康管理软件/中小学体检数据管理系统
- Java 拾遗补阙 ----- 数据类型
- arduino和单片机的区别是什么
- c语言16进制转2进制代码
- 【供应链架构day4】途牛进销存架构的演进之路 - 从诞生到发展
- 华为海思总裁:压在保密柜里面的芯片可以拿出来了
- mysql binlog grep_通过mysqlbinlog和grep命令定位binlog文件中指定操作
- 色度学:RGB颜色空间与CMYK颜色空间的比较与图示
- Tf2.0+基于注意力的神经机器翻译训练发布过程
- 微信登录画面_每次打开微信登录界面,都会看到一个小人,他是谁呢?
- WPF 开机启动因为触摸初始化锁住界面显示
- FEBE恢复Firefox配置方法[Z]
- 50天50个前端小项目(纯html+css+js)第六天(页面滚动动画)
- Echarts自定义地图和添加图标
- 对模式的迷信,大部分是幻觉和妄想
热门文章
- bde oracle 商友的流程_BDE动态连接Oracle数据库
- 【LOD for 3D Graphics】LOD技术背景调查
- 51单片机实战教程(34 线缆摇摆测试机设计)
- 技嘉Gigabyte主板Z370HD3安装1080ti+ubuntu17.10+Cuda9.1+cudnn7+tensorflow
- luogu P2852 [USACO06DEC]牛奶模式Milk Patterns
- 爱学习的小虫子——Who Am I ?
- TDA4 J721 EVM开发板开发学习
- 一般网站需要多少流量多大空间才够用
- 【数字信号】基于matlab GUI多音双频(DTMF)拨号音频解码仿真系统【含Matlab源码 1084期】
- Consul微服务注册与发现