射线弹跳:如何反转速度矢量来表示完美的弹跳?

问题描述 投票:0回答:1

我正在用 JavaScript 开发体素光线追踪系统,这听起来很奇怪,但以简单的形式却是可行的。我正在尝试弄清楚如何制作虚拟光线反弹,但无法完全理解算法。

概念很简单:每条射线都是一个虚拟点,具有两个属性:位置和速度,两者都存储为

x, y, z
向量,即字典。每个刻度都会将速度添加到该位置,也会在该点搜索新点的体素。相关部分是以下内容:

for(let step = 0; step < dist_max; step++) {
    pos.x += vel.x;
    pos.y += vel.y;
    pos.z += vel.z;
    if(solid_at(pos)) {
        // A voxel was hit
    }
}

当成功命中时,我需要对

vel
做一些事情来反转射线的方向并使其像橡皮球一样弹跳。在不使其失去或增加速度的情况下,只需改变其方向即可。表面可以被认为没有角度,因此不需要考虑任何对撞机属性,它只需要弹起,就好像它撞击到面向光线的平面一样......如果介于 0 和 0 之间的值将很有用1 可以控制应用效果的程度,以便半透明体素可以相应地反射/折射。

显然,秘诀不是将所有速度乘以

-1
,因为这只会使其向后移动:我认为我只需要反转它的一个或两个轴,或者将一个轴的速度与另一个轴的速度交换其他。但是,当光线可以向任何方向传播并且在 X、Y 和 Z 上具有任意速度(正数或负数)时,我如何知道应该翻转哪一个?

javascript math vector game-engine raytracing
1个回答
0
投票

我采用了一个简单但不完整的解决方案作为测试:要使地板充当镜子,您只需使用

+vel.x, -vel.y, +vel.z
。在我的引擎中,Y 轴是垂直的,而 X 和 Z 是水平位置:通过水平翻转光线,您可以让水平面像镜子一样工作。

可悲的是,这只是暂时的胜利,我将被迫恢复它:这个技巧在垂直的墙上不起作用。由于 X 和 Z 的速度不变,因此它们将直接穿过表面。

因此,我留下了一个不切实际的解决方案,即在给定的角度误差内将光线发送回相机:您只能看到身后的东西,而不是正常的前向反射,但至少使用

-vel.x, -vel.y, -vel.z
可以从任何角度进行预测并形成图像。

如果有人有更好的想法,请告诉我。我的光速是 1,这意味着速度矢量在至少一个轴上总是为 -1 或 +1,而另外两个轴可能有该范围内的任何值:我可以通过翻转轴来使其在任何地方都可以工作速度最高时,问题是如果光线突然在 X 方向而不是 Z 方向上移动得更快,例如它会立即捕捉到不同的反射指数。

© www.soinside.com 2019 - 2024. All rights reserved.