モーション入力からジッターを取り除く方法は?


9

Razer Hydraからの入力をサポートするMinecraft modを書いています。非常に正確な位置と回転の情報を提供する1組のモーションコントローラ(各手に1つ)です。

この質問の目的のために、Y軸で右コントローラーを回転させると、プレーヤーのキャラクターが左または右(ヨー)に見え、X軸で回転させると、プレーヤーが上下(ピッチ)に見えます。

コントローラからの入力は、キャラクターの見出しに直接マッピングされます。コントローラーを左に30度回転させると、キャラクターは左に30度回転します。

問題は、入力が「ジッター」することです。コントローラを完全に動かさないようにしようとすると、キャラクタのヘディングが非常に小さな円錐(おそらく1度)内で不規則に移動します。

コントローラーのデータは一見正確であるため、これはおそらく私の手ぶれによるものです。

最後のXフレームからのデータを平均化することで入力をフィルタリングしようとしましたが、これは入力をバターのように見せます。

私の質問は次のとおりです。回転データをフィルター処理して、精度を失うことなくジッターを削除するにはどうすればよいですか?


動きの非常に小さな変化を無視することを検討しましたか?
フィリップ

1
このRazer Hyrdraは興味深いです...初めて聞いたとき、それを補完するMinecraft modを書くのがさらに興味深いです...私の仮定は、ピクセル化された画像のように、必要な「ノイズを減らす」ためです。画像をぼかすには...基本的には、ピクセル化された画像と一緒に暮らすか、ぼやけた画像と一緒に暮らすことができます...これは同じ原則だと思います。好きなものを選択する必要があります。 ...それこそが私が思うことです...
ルークサンアントニオビアレッキ

1
あなたは両方のベストを尽くすことができます。最後の言う50フレームを常に格納します。しかし、入力の動きの量に応じて、それらのいくつかのフレームのみを平均化します。大きな動きの場合は、たとえば最後の5フレームのみに依存し、小さな(それ以外の場合はジッター)動きは最後の30フレームに依存します。
ダニジャー2013年

@sharethisそれは面白いアイデアです。私はそのようなものを実装することになるかもしれません。入力が特定のしきい値を超えると、ジッターは問題になりません。したがって、小さな入力を平均化してジッターを削除し、大きな入力の場合はまったく平均化しません。
りんご

回答:


8

この遅延と応答性の問題は、Hydra、Wiiリモート、Kinect、PlayStation Moveなど、ほぼすべてのモーションコントローラーの状況です。

問題はこれです:

入力ストリームが入ってくると、入力データを信頼するかどうかをフレームごとに決定します。あなたが今見ている傾向があなたが今から数十ミリ秒受け取るデータで継続するかどうか。たとえば、このフレームの右側への突然のシフトがある場合、それが入力データの実際のビットであるかどうか(そしてそれに対処する必要があるか)か、それが単なるジッターであるか(したがって無視する必要があるか)はわかりません。どちらを選択しても、後で間違っていることがわかった場合は、入力ジッターを許可して(最初のケースでは)ゲームに組み込むか、ゲームにラグを導入します(後者の場合)。

これに対する良い解決策はありません。入力が実数であるかジッターであるかを判別するための「正しい」ソリューションには、入力ストリームが将来何をするか、および過去に何をしたかを知ることが必要です。明らかな理由により、ゲームでそれを行うことはできません。 したがって、リアルタイムで入力データを処理するゲームのコンテキストでは、回転データをフィルタリングして、精度を失うことなくジッターを削除する方法はありません。

大手メーカーが、プレーヤーがボタンを押しながらコントロールを回転させることでこの問題に対処し、ゲームがその時点でアンチジッターコードをオフにできるようにすることで開発者がこの問題に対処することを推奨するのを見てきました。(これはお勧めしませんが、これは1つの方法です)。

入力に人為的な遅延を導入することによってこの問題に対処するいくつかのモーション入力ミドルウェアライブラリを見てきました。入力データが入る四分の一秒のバッファーがあり、ゲームは四分の一秒後に入力についてのみ聞きます、ライブラリーは、「現在」の前後で何が起こるかをゲームの観点から知ることにより、ジッターを滑らかにすることができます。すべてに四分の一秒の遅れをもたらすことを除いて、それは素晴らしい働きをします。しかし、これは問題を解決する1つの方法であり、一定の遅延を犠牲にして、ジッターを削除したモーションを正確に表すという素晴らしい仕事をすることができます。

しかし、極端なことをしなくても、理想的ではない方法で動作する「最悪のシナリオ」が常に存在することがわかっていても、大幅に改善された動作を実現するために実行できることがいくつかあります。

コアとなる洞察は、コントローラーがほとんど静止しているときのジッターのみを実際に考慮し、コントローラーが移動しているときのラグのみを実際に考慮しているということです。したがって、私たちの戦略は、コントローラーが静止しているときに遅れが生じ、コントローラーが動いているときにジッターが生じるように対処することです。

これを行うには、次の2つの方法があります。

1つの一般的なアプローチは、「ロック/ロック解除」システムです。このシステムでは、デバイスの向きを追跡し、それがしばらく(0.5秒程度)変化しない場合は、その向きを「ロック」します。再び「ロック解除」するのに十分異なるまで、デバイスの報告された方向に基づくアクション これにより、方向がアクティブに変化しているときに遅れを生じさせることなく、方向ベースのジッターを完全に抑制できます。コードが「ロック解除」モードに切り替える必要があると判断する前に、少しの遅れがあるかもしれませんが、どこにでも遅れがあるよりははるかに良いでしょう。

別のアプローチは、フレームからの入力データを平均化することです。ここで重要な点は、入力データが漠然と類似しているフレームからの入力データのみを平均化することです-これは、小さなジッターがぼやけて和らげられることを意味しますが、大きな変化はぼやけません。前のフレームのデータに十分似ています。

同様の効果を得る他の方法もあります。重要な洞察は、リアルタイムゲームでジッターとラグの両方を同時に持つことはできないということです。これを行うには、将来の知識が必要になるためです。したがって、全体的なエクスペリエンスを可能な限り悪くしないために、コントロールの動作をジッターを受け入れる方向にバイアスするタイミングと、ラグを受け入れる方向にバイアスするタイミングを選択する必要があります。


回答を投稿しました。私の解決策についてご意見をお寄せください。
りんご

2

私は、モーション入力を応答性の高い正確なマウス入力に変換するソフトウェアを開発するとともに、開発者が同等に優れたソリューションを実装するのを支援するWebサイトを維持しています。私は通常、動きのしきい値に対してはお勧めしませんが、プレーヤーがどの程度の応答性と正確さを求めるかによって異なりますが、状況に応じて問題なく機能することをうれしく思います。しかし、ここでは別のソリューションを提供します。

私はSoft Tiered Smoothingと呼ばれるものを使用しています。アイデアは、ジャイロ速度の現在の大きさに応じて、さまざまなスムージングアルゴリズムを介して入力をそらすというものです(実際には、これらのスムージングアルゴリズムの1つは、単に「スムージングなし」です)。それが「階層化された」部分です。「ソフト」な部分は、2つのしきい値との比較方法に応じて、入力をさまざまな平滑化アルゴリズム間でスムーズに分割できることです。

ディスプレイスメントを正しく保持し、速い動きに遅れを与えません。

実際には、2つのしきい値があります。入力速度の大きさが下限しきい値よりも小さい場合は、単純な平滑化アルゴリズム(複数のフレームにわたる平均)を使用しています。それが他のしきい値よりも大きい場合、平滑化アルゴリズムはまったく使用されません。ただし、この場合でも、下限しきい値の平滑化アルゴリズムにゼロを渡します。

入力速度が2つのしきい値の間にある場合、それに応じて2つのアルゴリズム間で入力を分割します。

上記の記事の抜粋を以下に示します。

GetSoftTieredSmoothedInput(Vec2 input, float threshold1, float threshold2) {
    // this will be length(input) for vectors
    float inputMagnitude = Abs(input);

    float directWeight = (inputMagnitude - threshold1) / (threshold2 - threshold1);
    directWeight = clamp(directWeight, 0, 1);

    return GetDirectInput(input * directWeight) +
        GetSmoothedInput(input * (1.0 - directWeight));
}

GetDirectInputは与えられたものを返すだけですが、ここでは別の平滑化アルゴリズムを使用できることを示しています。GetSmoothedInputは速度を受け取り、平滑化された速度を返します。

ソフトティアードスムージングでは、明らかに意図的な動き(大きいしきい値を超える)にはスムージングが適用されず、少量のジッターをカバーするためにスムージングが適用されます。これは、非常に小さい動きにも影響しますが、しきい値を正しく設定すると、それほど大きくありません。目立つ。そして、2つの間に非常にスムーズな移行があります(これがなければ、ジッターは実際に増幅されます)。

他の答えは、入力を受け取った瞬間にジッターを認識するのは難しいと言うのは正しいですが、ジッターはほとんど常に非常に低速であり、平滑化に伴う入力遅延は低速の入力でははるかに目立たないことも事実です。

記事で述べているように、これは、私のオープンソースツールJoyShockMapperのいくつかの場所で使用されています。これは、ジャイロ入力をマウス入力に変換する入力マッパーです。SteamやreWASDなどの他の再マッピングツールを使用している人でも、ジャイロコントロールのためだけにJoyShockMapperを同時に使用する人もいます。

この答えは、絶対的な向き(Razer Hydraが提供しているように聞こえる)ではなく、角速度(モーションコントロールを備えたコントローラーで一般的)で入力が与えられることを前提としています。絶対方向では、現在の方向と以前に報告された方向の差を使用して速度を取得できることを願っていますが、それが機能するかどうか、および角速度を自己報告するコントローラーで動作するかどうかはわかりません。

速度ではなく絶対位置/方向を扱う場合の一般的な平滑化ソリューションは、時間の経過とともに目標の方向に向かって補間することです。これは、このGamasutraの記事で非常に役立つ詳細に説明されています。これは、ソフトティアードスムージングでも機能します。この入力と以前に報告された入力との差を使用して、速度の大きさを計算します。このフレームと最後のフレームの向きの違いに、上記のスニペットで計算された「directWeight」値を掛けた値を適用します。最後のステップは平滑化された入力を追加することですが、補間された方向の平滑化が機能する方法のため、補間された方向の変更を通常どおりに適用するだけです。「directWeight」を考慮する必要はまったくありません。目標の方向(これは、Gamasutraの記事で説明されているスムージングで補間する方向です)をデバイスから取得する方向に設定し、その記事で説明されているように方向を補間します。


1

私自身の質問に答えるのは奇妙に感じますが、自分の解決策を見つけたと思います。

//Pseudo-Java

update()
{
    //deltaYaw is the change in yaw of the controller since last update
    //yawBuffer is initialized to zero, and only modified here
    //coneAngle is the stabilizing cone

    deltaYaw = getData().yaw;

    yawBuffer += deltaYaw;
    if (abs(yawBuffer) >= coneAngle)
    {
        player.yaw += (abs(yawBuffer)-coneAngle) * sign(yawBuffer);
        yawBuffer = coneAngle * sign(yawBuffer);
    }
}

プレイヤーの方向を直接変更する代わりに、特定の角度(私の場合は2.5度)の円錐を単に "プッシュ"します。この手法の小さなHTML5デモを作成しました。

コーンを押し始めると、遅延はなく、完全な精度になります。ただし、コーンを左に押してから右を狙う場合は、コーンの全角を移動して効果を確認する必要があります。

そのため、時間遅延や恐ろしい平滑化の問題は解決しますが、動きのしきい値という新しい問題が発生します。ただし、安定化コーンが正しく調整されている場合、しきい値は気付かれません。


これは別の合理的な方法のようです。以前は、このアプローチを使用してイメージを安定させる(高価な)ビデオカメラがありました。一方向に動き続けると精度が上がりますが、方向を変えると遅れが生じます。それがあなたのゲームでうまくいくなら、絶対にそれを試してください。すべてのゲームに最適な単一のソリューションを見つけることはできません。それは常に、各アプローチのマイナス面を、作成している特定のゲームの特定のニーズと比較検討する必要があるトレードオフです。:)
Trevor Powell
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.