图形学基础 | 折射光向量refract的计算

转载自: 羊羊2035
原文:几何向量:计算光线折射refract向量

光线折射的产生,其实是因为光线通过不同介质所产生的“偏折”现象。

ps:一般情况下,我们认为真空中(或者说空气中)折射率n = 1,毕竟我们起码要选取一个标准阀值,来推导其他介质的折射率,这里直接规定真空(空气)为标准1,那么其他介质的折射率都比真空要大,也就是>1。在这里插入图片描述
我们通过建立单位圆辅助计算,通过标量推导出向量的模长,然后通过向量平行和同异方向推导出向量,推出OB = OD + DB = -|cosβ|OE + |sinβ/sinθ|(AO + |cosθ|* OE),推导到这里,我们就把OB的公式用cos sin以及入射光向量AO和介质法向量N来计算了,这时候我们就思考如何计算cosβ cosθ,让这两个值使用已知的n1,n2,AO,OE来替换,如下图:

在这里插入图片描述
我们通过斯涅尔定律:n1 * sinθ = n2 * sinβ得到sinβ = n1/n2 * sinθ

点积的概念推出cosθ

cosβ的推导可以先试用sinβ替换,然后替换斯涅尔定律中计算的sinβ得到cosθ的表示,

这个时候我们所有的未知量就全部通过已知值(n1,n2,AO,OE)来表示了,如下图
在这里插入图片描述

代码实现:

// Snell's law
// https://blog.csdn.net/yinhun2012/article/details/79472364
Vec3f refract(const Vec3f& I, const Vec3f& N,float &refractive_index) {
	
	float cosi = -std::max(-1.0f, std::min(1.f, I*N));
	float etai = 1, etat = refractive_index;
	Vec3f n = N;
	if (cosi < 0) {
		// if the ray is inside the object, 
		// swap the indices and invert the normal to get the correct result
		cosi = -cosi;
		std::swap(etai, etat); n = -N;
	}
	float eta = etai / etat;
	float k = 1 - eta*eta*(1 - cosi*cosi);
	return k < 0 ? Vec3f(0, 0, 0) : I*eta + n*(eta * cosi - sqrtf(k));
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值