上个月学习Peter Shirley-Ray Tracing in One Weekend的系列三本书,收获真的很多。这个系列的书真的是手把手教你如何从零开始构建一个光线跟踪渲染器,对新手(像我)非常友好。但是书中有很多章节需要有一定的数学功底才能看懂,本文想分享一下关于in One Weekend-chapter 8:Metal中一笔带过的折射公式推导,内容主要来自于《Mathematics for 3D Game Programming and Computer Graphics, 3rd Edition》[1],加上我个人的理解,如有错误,欢迎指出。

(配图为raytracer构建后渲染)


问题简述

已知入射向量 \(L\) 和交点法线 \(N\),和入射光线所在介质折射率 \(\eta _ { \mathrm { L } }\) 及折射光线所在介质折射率 \(\eta _ { \mathbf { T } }\) ,求折射向量 \(T\)。如图:

  • 设入射角为 \(\theta _ { \mathrm { L } }\) ,折射角为 \(\theta _ { \mathbf { T } }\)
  • 设 \(L\) 和 \(N\) 已经标准化为单位向量,所求 \(T\) 也为单位向量
  • 注意此处 \(L\) 的方向指向外,保留与书上一致(实际入射方向应为\(-L\))
  • L、T可以理解为light和transmission的缩写

图 1


推导过程

(若推导过程感觉理解困难可以先考虑二维情况再考虑三维,其实入射光线和折射光线都在一个二维平面上)

关键公式:折射定律或斯涅尔定律(Snell's Law),用于计算折射角 \(\theta _ { \mathbf { T } }\) :

推导思路:
将 \(T\) 分解为平行于 \(N\)(-\(N\)) 和垂直于 \(N\) 的向量 (\(-G\)),见图 1。(用这两个向量的线性组合\(a*-N+b*G\)表示 \(T\),问题就在于求两个系数a、b和向量 \(G\),将问题转换为求\(a\)、\(b\)、\(G\))

1. 求 \(a\)

求\(a\)实际上就是求向量\(T\)在向量\(-N\)上的投影,利用点乘公式即可计算出\(a=\cos \theta _ { \mathrm { T } }\),由于所求 \(T\) 和 \(-N\) 都为单位向量,所以其点乘展开式最终化简为\(\cos \theta _ { \mathrm { T } }\)。

\(T \cdot (-N) = |T| |-N| \cos \theta _ { \mathrm { T } }=\cos \theta _ { \mathrm { T } }\)

\(T \cdot (-N) = |-N|\cdotp Proj = Proj\)

联立上式即可

2. 求 \(b\)

基本思路和求 \(a\) 一样,这里求出 \(b = \sin \theta _ { \mathrm { T } }\)

(实际此处先求出的是cos<T,-G>,根据由于垂直关系,两角互余,等值于 \(\sin \theta _ { \mathrm { T } }\) )

3. 求 \(G\)

\(G\) 同 \(\operatorname { perp } _ { \mathrm { N } } \mathbf { L }\)平行(\(\operatorname { perp } _ { \mathrm { N } } \mathbf { L }\)为\(L\)垂直于\(N\)的分量,见图 1),由于 \(L\) 为单位向量,\(\left\| \operatorname { perp } _ { \mathbf { N } } \mathbf { L } \right\| = \sin \theta _ { \mathbf { L } }\),\(G\) 可表示为:

(求 \(\operatorname { perp } _ { \mathrm { N } } \mathbf { L }\) 的过程有点像施密特正交化的过程,都是一个向量去除某个方向的分量,除以 \(\sin \theta _ { \mathbf { L } }\) 即标准化为单位向量)

4. 所以 \(T\) 可以表示为:

利用斯涅尔定律替换\(\frac { \sin \theta _ { \mathrm { T } } } { \sin \theta _ { \mathrm { L } } }\):

将 \(\cos \theta _ { \mathrm { T } }\) 用 \(\sqrt { 1 - \sin ^ { 2 } \theta _ { \mathrm { T } } }\)代替,\(\sin \theta _ { \mathrm { T } }\) 用 \(\left( \eta _ { \mathrm { L } } / \eta _ { \mathrm { T } } \right) \sin \theta _ { \mathrm { L } }\) 代替:

最后,将 \(\sin ^ { 2 } \theta _ { \mathrm { L } }\) 用 \(1 - \cos ^ { 2 } \theta _ { \mathrm { L } } = 1 - ( \mathbf { N } \cdot \mathbf { L } ) ^ { 2 }\) 带入可得最终 \(T\) 的表达式:

(如果 \(\eta _ { \mathbf { L } } > \eta _ { \mathbf { T } }\),方程式中根号内的量可能为负,光线发生全反射,应用反射公式计算向量方向。即当 \(\sin \theta _ { \mathrm { L } } \leq \eta _ { \mathrm { T } } / \eta _ { \mathrm { L } }\),上式才可用于计算折射向量。)

其他

最后放一张in one weekend中计算折射向量的函数,参数 v 即为入射光线方向,只要将上诉公式加以对照即可写出。(记得上述 \(-L=v\))

参考文献

  1. Eric Lengyel. Mathematics for 3D Game Programming and Computer Graphics, 3rd Edition. Course Technology PTR, 2011.
  2. Peter Shirley. Ray Tracing in One Weekend. Amazon Digital Services LLC, January 26, 2016.

折射向量计算(Refraction Vector Calculation)的更多相关文章

  1. 【3D数学基础】三维空间折射向量计算

    问题:在三维空间中,已知折射率 e .入射角 L 和法线 N. 要求:计算出折射向量 T. 其中: L. N 和 T 都为单位向量. 如图片所示,下面所有的公式都看着这张图片来求解的: 首先,我们必须 ...

  2. 由浅入深学习PBR的原理和实现

    目录 一. 前言 1.1 本文动机 1.2 PBR知识体系 1.3 本文内容及特点 二. 初阶:PBR基本认知和应用 2.1 PBR的基本介绍 2.1.1 PBR概念 2.1.2 与物理渲染的差别 2 ...

  3. shader函数

    Intrinsic Functions (DirectX HLSL) The following table lists the intrinsic functions available in HL ...

  4. unity shader 常用函数列表

    此篇博客转自csdn的一位大牛. 中间排版出了一些问题 Intrinsic Functions (DirectX HLSL) The following table lists the intrins ...

  5. DirectX HLSL 内置函数

    Intrinsic Functions (DirectX HLSL) The following table lists the intrinsic functions available in HL ...

  6. HLSL Shader编程基础总结

    转自:https://blog.csdn.net/Blues1021/article/details/47093487 基本前提概念 Shader是一种映射到GPU硬件汇编语言上的高级语言,Shade ...

  7. 【SIGGRAPH】用【有说服力的照片真实】技术实现最终幻想15的视觉特效

    原文:西川善司 http://www.4gamer.net/games/075/G007535/20160726064/   最终幻想15的演讲会场.相当大,听众非常多.      在本次计算机图形和 ...

  8. Nvidia Anisotropic Lighting

    http://http.download.nvidia.com/developer/SDK/Individual_Samples/DEMOS/Direct3D9/HLSL_Aniso.zip Anis ...

  9. Nvidia VertexTextureFetch Water

    http://http.download.nvidia.com/developer/SDK/Individual_Samples/samples.html http://http.download.n ...

随机推荐

  1. UIKit 框架之UIActionSheet

    UIAlertView和UIActionSheet相似,区别很小, 很容易理解. // // ViewController.m // UIActionSheet // // Created by Ci ...

  2. 点击CheckBox让Gridview控件在编辑与正常状态之间切换

    昨晚快休息时,还有一位网友咨询Insus.NET,他想在开发时,实现一个小功能,就是想让用户在点击Gridview控件第一列的CheckBox之后,GridView进入编辑状态,取消选中的CheckB ...

  3. Cookies读写

    /** * Minified by jsDelivr using Terser v3.14.1. * Original file: /npm/js-cookie@2.2.0/src/js.cookie ...

  4. 最短路(hdu2544)Dijkstra算法二

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  5. JS 创建自定义对象的方式方法

    一.概述 还记得刚开始做项目的时候,看到别人封装的js工具类百思不得其解,看来看去看不懂,深挖一下,其实就是自己没有耐下心去看,但是遇到问题不解决,总会遇到的,今天还是遇到了,就去找了找帖子,重新思考 ...

  6. 使用kafka consumer api时,中文乱码问题

    使用Intelli idea调试kafka low consumer时,由于broker存储的message有中文, idea中console端是可以正确显示的 然后mvn package打包到服务器 ...

  7. tilestache + mbutil应用

    1. 安装pip. 我们同样需要在Python的官网上去下载,下载地址是: https://pypi.python.org/pypi/pip#downloads 2. 解压. 解压pip-9.0.1. ...

  8. JMeter4.0的界面汉化

    1.安装好之后 2.界面汉化 options->choose language->chinese(simplified) 3.汉化完成

  9. python turtle 例子 海归绘图

          太阳花 1 # coding=utf-8 2 import turtle 3 import time 4   5 # 同时设置pencolor="red", fillc ...

  10. 【jdk源码3】HashMap源码学习

    可以毫不夸张的说,HashMap是容器类中用的最频繁的一个,而Java也对它进行优化,在jdk1.7及以前,当将相同Hash值的对象以key的身份放到HashMap中,HashMap的性能将由O(1) ...