2017-10-07 19 views
1

からコピーされたwebglで遊んでいます。私はライトの位置を制御するためにマウスを使用したい。Webgl - 動的なマウスの位置

私はちょうどそれが動作しますjsからfragment shaderに静的な値を送信する場合:

function updateMousePosition(e){ 
    console.log(e.pageX); 
    mousex = e.pageX; 
    mousey = e.pageY; 
} 

たときにマウスの移動と呼ばれる:

mouseLocation = gl.getUniformLocation(program, "mouse"); 
gl.uniform2f(mouseLocation, 0,0); 

私はマウスの位置を更新する機能を持っています:

canvas.addEventListener('mousemove', updateMousePosition, false); 

fragment shaderすべてのフレーム:

gl.uniform2f(mouseLocation, mousex,mousey); 

その後、私はfragment shaderからマウスの位置を取得します:

uniform vec2 mouse; 

void main(void) { 
    //mp - mouse position 
    vec2 mp = vec2(mouse.x/resolution.x, 1.0 - mouse.y/resolution.y); 

    //lp depend on mp 
    vec3 lp = vec3(mp.x, mp.y, -1.0); 

    //other calculation ... 
} 

それは動作しませんでした。 しかし、ときに私がupdateMousePosition(e)console.logから静的な値を下に送る:

gl.uniform2f(mouseLocation, 679, 590);//number taken from console.log 

それが動作します。

私は何がうまくいかないのか分かりませんが、数字の形式またはタイプが疑わしいのですが、jsは厳密には入力しませんが、glslです。

どうすれば解決できますか?

+0

もっとコードを表示する必要があります。あなたが示したものに何も問題はありません。 – gman

答えて

0

Finalyはこの回答(編集済み)を決定しました。

Gmanがコメントしたように、あなたのコードには間違いがありません。技術的には、これはうまくいくはずです。しかし、あなたはOpenGLと比較して、WebGL/Javascriptのカップルの本当のトリッキーな側面を指摘しました。また、Javascriptの変数がどのように動作するかによって、奇妙なバグが簡単に生成されます。

このabsurdeような状況を想像:C、C++、または他の強い型付けされた言語で

var x = 55; 
var y = 128; 

// some code here... 

x = "blah"; // oups ! 

// some code here... 

gl.uniform2f(mouseLocation, x, y); 

を、そのような不条理を行うことはほとんど不可能である(これはポインタを介し可能であるが、これは別の主題である)、コンパイラので、それを厳格に禁じて、誤りを投げる。しかしjavascriptでは問題ありません。この場合、数値変数xは文字列変数になり、WebGLに渡されるとNaNになります。 x変数を正しくトラッキングしていないと、これがなぜ機能しないのか長い時間を検索します。

すべてのWebGL関数は、最後の段階がGPUであり、GPUが低レベルであるため、最後の段階で入力されたデータのみを受け入れます。つまり、純粋なJavascript Number変数をWebGL関数に渡しても、このJavascript変数は前に型付きデータに変換されます。しかし実際には、Javascriptは間違った変数型に関するエラーを投げることはありません:それは型付きデータに変換し(キャスト)、あなたがしようとしていることがばかげても警告しません。 「NaN」に変換する。

幸い、任意のあいまいさを避けるために、WebGLのは、新しいJavaScriptオブジェクトの束が付属しています:型付き配列:型付き配列でhttps://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/TypedArray

は、あなたがあなたのjavascriptのコード内で知ることができるものをデータ格納され、それがどうしたデータそれを送信する前にGPUに送信されます。 つまり、型付き配列を使用して、Javascript変数をGPUに送信する前に既知の型指定データに変換(キャスト)することができます。上記の例で

var mousePos = new Float32Array(2); 

function updateMousePosition(e){ 
    mousePos[0] = e.pageX; 
    mousePos[1] = e.pageY; 
} 

// do something 

console.log(mousePos); 
gl.uniform2fv(mouseLocation, mousePos); 

、変数e.pageXe.pageY直接WebGLの互換性の型付きデータに変換されます。こうすれば、変数をconsole.logで印刷すると、実際にWebGLに送信される内容が表示されます。デバッグ目的のために、gl.uniform2fvへの呼び出しの直前にconsole.logを置くことで、何も問題が発生していないことを確認することができます。

この例では、データが間違って変換された場合、出力ログにNaN,NaNのようなものが表示されるため、コード内のどこかで間違いを検索する必要があることがわかります。

+0

私は実際に何が起こったのか理解しましたが、答えを更新するのを忘れました。あなたの答えは正しいです。しかし、私の解決策は似ていますが簡単です。私は 'var x = 0.0'のような変数を宣言して初期化するだけで、すべてが魅力的に機能します。とにかく、私は詳細な説明のためにあなたの答えを受け入れる。 – sooon

関連する問題