gpt4 book ai didi

graphics - 光线追踪折射看起来 "fake"

转载 作者:行者123 更新时间:2023-12-04 17:20:04 26 4
gpt4 key购买 nike

因此,在我正在构建的光线追踪器中,我已经获得了适用于球体的折射以及焦散效果,但是玻璃球看起来并不是特别好。我相信折射数学是正确的,因为光线似乎在以您期望的方式反转时弯曲,但它看起来不像玻璃,它只是看起来像纸或其他东西。

我读到全内反射是造成玻璃看起来像它的大部分原因,但是当我测试看我的折射光线是否超过临界角时,没有一个超过临界角,所以我的玻璃球体没有全内反射。我不确定这是正常现象还是我做错了什么。我已经在下面发布了我的折射代码,所以如果有人有任何建议,我很乐意听取他们的意见。

/*
* Parameter 'dir' lets you know whether the ray is starting
* from outside the sphere going in (0) or from in the sphere
* going back out (1).
*/
void Ray::Refract(Intersection *hit, int dir)
{

float n1, n2;
if(dir == 0){ n1 = 1.0; n2 = hit->mat->GetRefract(); }
if(dir == 1){ n1 = hit->mat->GetRefract(); n2 = 1.0; }

STVector3 N = hit->normal/hit->normal.Length();
if(dir == 1) N = -N;
STVector3 V = D/D.Length();
double c1 = -STVector3::Dot(N, V);
double n = n1/n2;

double c2 = sqrt(1.0f - (n*n)*(1.0f - (c1*c1)));

STVector3 Rr = (n * V) + (n * c1 - c2) * N;

/*These are the parameters of the current ray being updated*/
E = hit->point; //Starting point
D = Rr; //Direction
}

此方法在递归运行的主要光线追踪方法 RayTrace() 期间被调用。下面是它的一小部分,负责折射:

    if (hit->mat->IsRefractive())
{
temp.Refract(hit, dir); //Temp is my ray that is being refracted
dir++;
result += RayTrace(temp, dir); //Result is the return RGB value.
}

最佳答案

你是对的,你永远不会在球体中获得全内反射(从外面看)。这是因为对称性:球体内的光线会在两端以相同的角度撞击表面,这意味着,如果它在一端超过临界角,它也必须在另一端超过临界角(因此一开始就无法从外面进入球体)。

但是,根据 Fresnel's law,您仍然会得到很多部分反射.看起来您的代码并没有说明这一点,这可能就是为什么您的玻璃看起来是假的。尝试包括它,看看它是否有帮助。

(是的,这意味着您的光线在碰到折射表面时会一分为二。这在现实中会发生,所以您只能接受它。您可以追踪两条路径,或者,如果您无论如何,如果我们使用随机光线追踪算法,只需使用适当的权重随机抽取其中一个。)

附言。如果你不想处理像光偏振这样的东西,你可能只想使用 Schlick's approximation到菲涅尔方程。

关于graphics - 光线追踪折射看起来 "fake",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14034525/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com