Java 如何从入射向量和曲面法线中找到折射向量?
我正在用java编写一个光线跟踪器,我正在尝试实现折射,但是我被我在这个主题上找到的信息弄糊涂了。如果我有一个入射光线的3D矢量,作为3D矢量给出的表面法线和两种介质的折射率,为了得到透射光线的矢量,我需要应用什么操作?让V__成为标准化的入射矢量。设Java 如何从入射向量和曲面法线中找到折射向量?,java,vector,raytracing,Java,Vector,Raytracing,我正在用java编写一个光线跟踪器,我正在尝试实现折射,但是我被我在这个主题上找到的信息弄糊涂了。如果我有一个入射光线的3D矢量,作为3D矢量给出的表面法线和两种介质的折射率,为了得到透射光线的矢量,我需要应用什么操作?让V__成为标准化的入射矢量。设n1和n2为两个表面的折射率。您要计算V_折射。设n为归一化法向量 V_refraction = r*V_incedence + (rc - sqrt(1-Math.pow(r,2)(1-Math.pow(c,2))))n where r = n1
n1
和n2
为两个表面的折射率。您要计算V_折射。设n为归一化法向量
V_refraction = r*V_incedence + (rc - sqrt(1-Math.pow(r,2)(1-Math.pow(c,2))))n
where r = n1/n2 and c = -n dot V_incedence.
我在我的rayjava跟踪器中实现了这个
专用静态双钳位(最终双val、最终双最小值、最终双最大值){
返回Math.max(min,Math.min(max,val));
}
私有向量3D getRefractionVector(最终向量3D I、最终向量3D N、最终双ior){
双余弦=钳位(-1,1,I.dot(N));
双etai=1,etat=ior;
矢量3d n=n;
if(cosi<0){
cosi=-cosi;
}否则{
双温=etai;
etai=etat;
etat=温度;
n=n.乘(-1);
}
双eta=etai/etat;
双k=1-(eta*eta)*(1-(cosi*cosi));
if(kBram de Greve写了一篇关于光线跟踪中的反射和折射的好文章。你可以找到它
他的实现(C++)如下所示:
Vector refract(const Vector& normal, const Vector& incident,
double n1, double n2)
{
const double n = n1 / n2;
const double cosI = -dot(normal, incident);
const double sinT2 = n * n * (1.0 - cosI * cosI);
if(sinT2 > 1.0) return Vector::invalid; // TIR
const double cosT = sqrt(1.0 - sinT2);
return n * incident + (n * cosI - cosT) * normal;
}
谢谢你的回答。在第一行中,这是否意味着要加上V_置信度向量。乘以(r)和n的向量。乘以(rc-sqrt(1-r^2(1-c^2))?这是一个近似值吗?似乎偏离了一些小数位这是一个非常有用的方法,尽管我必须写出cosI=abs(dot(normal,incident))才能正确工作。
Vector refract(const Vector& normal, const Vector& incident,
double n1, double n2)
{
const double n = n1 / n2;
const double cosI = -dot(normal, incident);
const double sinT2 = n * n * (1.0 - cosI * cosI);
if(sinT2 > 1.0) return Vector::invalid; // TIR
const double cosT = sqrt(1.0 - sinT2);
return n * incident + (n * cosI - cosT) * normal;
}