Graphics 光线跟踪折射看起来像;假;
因此,在我正在构建的光线跟踪器中,我得到了折射,可以处理球体和焦散效果,但是玻璃球体看起来不是特别好。我相信折射的数学是正确的,因为光线看起来是弯曲的,就像你期望的那样,但是它看起来不像玻璃,它只是看起来像纸或其他东西 我读到过,全内反射是玻璃外观的主要原因,但是当我测试折射光线是否超过临界角度时,没有一条超过临界角度,所以我的玻璃球体没有全内反射。我不确定这是正常的还是我做错了什么。我已经在下面发布了我的折射代码,所以如果有人有任何建议,我很乐意听听Graphics 光线跟踪折射看起来像;假;,graphics,3d,transparency,raytracing,aero-glass,Graphics,3d,Transparency,Raytracing,Aero Glass,因此,在我正在构建的光线跟踪器中,我得到了折射,可以处理球体和焦散效果,但是玻璃球体看起来不是特别好。我相信折射的数学是正确的,因为光线看起来是弯曲的,就像你期望的那样,但是它看起来不像玻璃,它只是看起来像纸或其他东西 我读到过,全内反射是玻璃外观的主要原因,但是当我测试折射光线是否超过临界角度时,没有一条超过临界角度,所以我的玻璃球体没有全内反射。我不确定这是正常的还是我做错了什么。我已经在下面发布了我的折射代码,所以如果有人有任何建议,我很乐意听听 /* * Parameter 'dir'
/*
* 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.
}
你是对的,你永远不会在球体中得到完全的内部反射(从外面看)。这是因为对称性:球体内部的光线将以两端相同的角度撞击表面,这意味着,如果它在一端超过临界角度,那么在另一端也必须超过临界角度(因此,首先无法从外部进入球体) 然而,你仍然会得到很多部分反射根据。这看起来不像是你的代码造成的,这可能就是为什么你的眼镜看起来是假的。试着将其包括在内,看看是否有帮助 (是的,这意味着您的光线在碰到折射表面时会一分为二。这在现实中是会发生的,所以您只能接受它。您可以跟踪两条路径,或者,如果您使用随机光线跟踪算法,只需使用适当的权重随机采样其中一条。)
注:如果你不想处理像光偏振这样的问题,你可能只想使用菲涅耳方程。谢谢!我尝试实现Schlick近似,但仍然有bug,但即使如此,我的球体看起来更像玻璃!=)