我正在尝试在游戏(赛车游戏)中模拟多普勒效果。我没有使用模拟声音效果的特定声音库,只有混合数据的回调函数。
我已经弄清楚了如何在混频器功能中更改采样频率。
我不知道,根据玩家和发射器的位置和速度,频率应该改变多少。
这是我在游戏中所拥有的:
//player
vec3 p.pos;
vec3 p.vel;
//emitter
vec3 e.pos;
vec3 e.vel;
1)根据维基百科,发射频率与观测频率之间的关系为:
float f = (c + vr) / (c + vs) * fo
其中c为常数,介质(通常为大数)中的速度 vs和vr是相对于介质的源和接收器速度。
所以我猜:
float vr = p.vel.length; //player speed
float vs = e.vel.length; //emitter speed
但是我认为这是错误的,它不会产生任何频率变化,例如:如果vr = 0
(玩家不移动)并且发射器具有恒定速度,则vr
并且vs
不会变化(尽管它们应该)。
也许我应该相对于发射器的速度来计算玩家的速度?
像这样 :
relative_speed = distance(p.pos + p.vel, e.pos + e.vel) -
distance(p.pos, e.pos);
那么如何vr
和vs
应喂?
2)维基百科还提供了另一个公式来模拟观察者通过的车辆的效果:
vr = vs * cos(theta);
//theta is angle between observer and emitter
//theta = atan2(e.pos.y-p.pos.y, e.pos.x-p.pos.x); ?
但是,此公式假定接收器不移动,在此情况并非如此。如果播放器和发射器以相同的速度(或小的差异)移动,则不应有多普勒效应。此功能还特定于一种情况,我想最终公式应该相同而不管这种情况。
编辑:我正在尝试使用SkimFlux post找到正确的公式:
vr,r = vr.vel * cos(shortest_angle_between ( vr.vel , vs.pos - vr.pos));
vs,r = vs.vel * cos(shortest_angle_between ( vs.vel , vr.pos - vs.pos));
//is there a easier/faster way to find them out ?
//note: vr.vel and vs.vel are vectors, the green and red arrows on SkimFlux picture.
编辑2:
对于那些感兴趣的人,这里是最终公式:
vec2 dist = vs.pos - vr.pos;
vr,r = dotproduct(vr.vel, dist) / length(dist)
vs,r = dotproduct(vs.vel, dist) / length(dist)
注意:它使用矢量投影,在这里描述:
然后vr,s
,vs,r
应将其插入第一个维基百科公式:
我对其进行了测试,并成功运行了,并提供了不错的结果。