3

webgl ピッキングを最初から実装しており、レイ交差テストとは対照的に、GLSL ルートをたどることにしました。

そのため、シーン全体を個別のフレーム バッファーにレンダリングし、各オブジェクトに一意の色を割り当てて、フラグメント シェーダーに均一変数として渡します。シーンがレンダリングされると、バッファーを gl.readPixels() し、クリック座標で色の値を取得します (ブラウザーの座標系とは異なる GL を考慮して座標系を反転させます)。

私が抱えている問題は、シェーダーが gl_FragColor シェーダー出力に渡される色を、カラー チャンネルごとに 0.0-1.0 の範囲で vec4 浮動小数点数として表すのに対し、gl.readPixels() はカラー チャンネルを 0-255 の範囲の整数として返すことです...この変換を行う一部の精度が失われ、ピッキング エラーが発生する可能性があります (シーン内に多数のオブジェクトがある場合 (255 を超える場合)、または整数から浮動小数点への丸めが、異なるオブジェクト ID を区別するために必要な粒度よりも大きい場合)。

誰かがこれを解決する方法を知っていますか、または私を正しい方向に向けますか? readPixels() は 0.0 ~ 1.0 の範囲のカラー チャネルの float 値を返すことができますか? 複数のチャネルにまたがる単一のオブジェクト ID をパックできますか (単一のチャネルに限定されず、255 個のオブジェクトしか選択できないようにするには?)

ご協力ありがとうございました

4

5 に答える 5

2

これは古い質問ですが、提供するだけです...

複数のチャネルにまたがる単一のオブジェクト ID をパックできますか (チャネルが 1 つに限定されず、255 個のオブジェクトしか選択できないようにするため)?

8 ビットの gl.readPixels によって取得されたカラー コンポーネントごとに 8 ビットを確実にエンコードできます。フラグメント シェーダーでは、float redComponent = float(intObjectId) / 255.0 を使用できます。それを gl_FragColor に入れると、0 から 255 の範囲であれば、最初の数値として確実に返されます。丸めは必要ありません。

次のように、mod と除算によって、より大きな整数をエンコードできます。

    int objectId = 12345; // up to 65535...
    float f = float(objectId);
    // put low 8 bits into .r, and next 8 bits into .g
    gl_FragColor = vec4(mod(f,256.) / 255., mod(floor(f / 256.0), 256.0) / 255.0, 0,1);

知っておくべきことは、範囲が float [0.0, 1.0] から int [0,255] にマップされることです。そして、それらは範囲の真ん中にマッピングされるため、0.0 から 0.5/255 までは 0 にマッピングされ、0.5/255 から 1.5/255 までは 1 にマッピングされます。とても安定しています!

于 2013-10-31T03:21:11.020 に答える
0

OpenGL では、ポインタからテクスチャを作成できることを知っています (つまり、ポインタが指しているメモリの一部をテクスチャのコンテンツとして取得します)。逆のプロセスも可能だと思いますが、どのようにしてそれを行うことができるかはよくわかりません. 何かのようなもの:

*p = myTexture;     // texture -> pointer
my_data = p[i][j];  // read byte data

それができれば、コンテンツをバイトデータとして読み取り、それを float (またはあなたに合ったもの) に変換できます。しかし、それが可能であり、JavaScript でどのように正確に行うことができるのか、その疑問は残ります... それでも、これは私が行く方法です。

お役に立てれば。

于 2013-06-03T22:01:39.253 に答える