GLSL的反射函数说明是否可用?

11
我正在尝试调试我的简单光线追踪器,模拟从一个点射出的光线穿过透镜的过程。我只需要实现折射效果。
我曾试图手工实现它,但最终我在 GLSL 中找到了文档中描述为 refract 的函数,这在 GLSL 1.1 中是这样的:
//For a given incident vector I, surface normal N and ratio of 
//indices of refraction, eta, refract returns the refraction vector, R. 
//R is calculated as:

k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));
if (k < 0.0)
    R = genType(0.0); // or genDType(0.0)
else
    R = eta * I - (eta * dot(N, I) + sqrt(k)) * N;

//The input parameters I and N should be normalized in order to 
//achieve the desired result.

我想知道这些方程是从哪里来的。我在互联网和我拥有的书籍(Real Time Rendering圣经或Phisically Based Rendering最新版)中搜索,它们都引用了这个实现,但没有解释,或者只是给出了答案。

尝试使用几何图形手动计算会得到其他答案,但显然这对于像GLSL这样常见的函数来说是很费力的。所以我更喜欢使用这种优化表示法。

我只有这个:

a.b = |a||b|cos(angle) (Dot product)
angleOut = eta * sin(angleIn) (Snell's Law).

你知道这来自哪里吗?有没有任何文档或参考可以阅读?

3个回答

9

您可以在该书的第16.5节中找到解释:

FOLEY,James D.(编辑)。计算机图形学:原理与实践,C语言第二版。Addison-Wesley Professional,1996年。

这些是相关页面,它们来自于此Google图书搜索(于2013-12-29T10:15:00+01:00参考):

enter image description here enter image description here

参考文献[HECK84]是

HECKBERT, Paul S.; HANRAHAN, Pat. 1984年ACM SIGGRAPH计算机图形学论文集上的"Beam tracing polygonal objects"。ACM,页码119-127。

并且有一个名为“Reflection and Refraction Transformations”的详细附录。


很酷!非常感谢这个参考资料。在 Google Books 上搜索是个好主意。你告诉我的书只有 56 页……可惜了。它肯定是我收到的最好的 ^_^ 谢谢! - Darkgaze
1
@darkgaze 我实际上拥有Foley 1996年的一本书,我首先检查了它的索引,然后进行了Google Books搜索,希望能找到预览... - Alessandro Jacopson
太酷了,谢谢你的时间。 :-) 一定要好好保管那本Foley的书,它确实是一本非常好的书。 - Darkgaze
请注意,该书的第三版于去年夏天发布:http://www.amazon.com/Computer-Graphics-Principles-Practice-Edition/dp/0321399528(虽然我认为折射并没有得到更好的解释,但自1996年以来,计算机图形学中的其他主题已经发生了很大变化 :-)) - Mortennobel
@Mortennobel 我同意。我有第三版,但是我找不到公式的解释... - Alessandro Jacopson

4

smallpt的代码是一个全局光照渲染器,其中包含了refract函数的实现;我认为这个实现与你问题中的实现相似。这篇文章详细解释了该实现,它来自于David Cline的演示幻灯片;我在此附上相关幻灯片:

enter image description here

根据维基百科的解释,该公式在以下书籍中有详细说明:
GLASSNER, Andrews (ed.). An introduction to ray tracing. Morgan Kaufmann, 1989.
Glassner的书中第7章的第5节(由Paul Heckbert撰写)标题为“折射公式的推导”,该部分可在Heckbert's page上找到;在该部分中,Heckbert推导了这两篇论文中使用的公式: WHITTED, Turner. An improved illumination model for shaded display. Comm. ACM, 1980, 23.6.

HECKBERT, Paul S.; HANRAHAN, Pat. "多边形物体的光线跟踪". 在:ACM SIGGRAPH计算机图形学. ACM,1984年。第119-127页。


哇,我一定会看看的,伙计。非常感谢你!让我看看它是否回答了我的问题,然后我将把答案标记为有效! - Darkgaze
1
嗯,这本书非常昂贵,也无处可找,只为了看到那一页上的解释。 此外,对我来说,这些公式仍然是难以理解的。我从B(切线)=正弦/余弦开始。然后它说角A的正弦是B的分母...这条规则讲不通啊。所以我又被卡住了。请帮忙! - Darkgaze
我猜dot(D,N)是cos(theta b),因为dot是abcos(angle),如果向量被归一化,a和b的长度都为1,我是对的吗?这根本没有解释... - Darkgaze
除此之外,N、B和T变量与Binormal/Tangent/Normal名称有关吗?这意味着B垂直于ND平面?O_O - Darkgaze
@darkgaze,我添加了一个新答案,请看看是否适合你。 - Alessandro Jacopson

1

这应该是斯涅尔定律。有一个涉及材料中想象的“波前”的速度变化的推导,这是一件不错的物理学成果,但可能不是必要的来理解如何在渲染中使用它。它相当通用,适用于大多数情况,尽管在光学中有些情况下它并不足够。


是的,我知道。但我想了解为什么 :-) 原因是我遇到了一些严重的球面像差问题,我想要理解其中的原因。这在普通透镜中很常见,当光线穿过它们时会发生,但我想检查是否使用斯涅尔定律而不是透镜制造公式来解决这个问题。但还是谢谢! - Darkgaze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接