レイキャスティング方法
three.js に付属する Raycaster を使用してオブジェクトを選択するのは非常に簡単です。コードは次のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
[関連コースの推奨事項: JavaScript ビデオ チュートリアル ]
バウンディング ボックス フィルタリングを使用して、投影光線と各三角形のサーフェス要素を計算します。交差点が達成されます。
ただし、モデルが 400,000 個の面など非常に大きい場合、オブジェクトの選択とトラバースによる衝突ポイントの位置の計算は非常に遅くなり、ユーザー エクスペリエンスは良くありません。
しかし、GPU を使用してオブジェクトを選択すると、この問題は発生しません。シーンやモデルがどんなに大きくても、オブジェクトの位置とマウスポイントの交点を1フレーム内で取得できます。
GPU を使用してオブジェクトを選択する
実装方法は非常に簡単です:
1. 選択マテリアルを作成し、各モデルのマテリアルを置き換えます。色の違うシーン。
2. マウス位置のピクセルの色を読み取り、その色に基づいてマウス位置のオブジェクトを決定します。
具体的な実装コード:
1. 選択したマテリアルを作成し、シーンを走査し、シーン内の各モデルを別の色に置き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
2. WebGLRenderTarget 上にシーンを描画し、マウス位置の色を読み取り、選択されているオブジェクトを決定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
説明: offsetX と offsetY はマウスの位置、height はキャンバスの高さです。 readRenderTargetPixels 行の意味は、幅 1、高さ 1 のマウス位置 (offsetX、高さ - offsetY) のピクセルの色を選択することです。
pixel は Uint8Array(4) で、rgba カラーの 4 つのチャネルがそれぞれ格納され、各チャネルの値の範囲は 0 ~ 255 です。
完全な実装コード: https://gitee.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/event/GPUPickEvent.js
GPU を使用して取得します交差点の位置
実装方法も非常に簡単です:
1. 深度シェーダー マテリアルを作成し、シーンの深度を WebGLRenderTarget にレンダリングします。
2. マウス位置の深さを計算し、マウスの位置と深さに基づいて交差位置を計算します。
具体的な実装コード:
1. 深度シェーダー マテリアルを作成し、特定の方法で深度情報をエンコードし、それを WebGLRenderTarget にレンダリングします。
深度マテリアル:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
重要な注意事項:
a. gl_Position.z はカメラ空間の深度であり、線形で、cameraNear から CameraFar までの範囲です。シェーダの可変変数は補間に直接使用できます。
b. gl_Position.z/far の理由は、色として出力しやすいように値を 0 ~ 1 の範囲に変換するためです。
c. スクリーン空間で深度を使用することはできません。透視投影後、深度は -1 ~ 1 になり、そのほとんどは 1 に非常に近い値 (0.9 以上) です。線形ではなく、ほとんど変化しません。出力色はほとんど変化せず、非常に不正確です。
d. フラグメント シェーダーで深度メソッドを取得します: カメラ空間深度は gl_FragCoord.z、スクリーン空間深度は gl_FragCoord.z / gl_FragCoord.w です。
e. 上記はすべて透視投影の場合ですが、正投影では gl_Position.w は 1 となり、カメラ空間とスクリーン空間の深度は同じになります。
f. 奥行きをできるだけ正確に出力するために、rgb の 3 つの成分を使用して奥行きを出力します。 gl_Position.z/far の範囲は 0 ~ 1 で、0xffffff を乗算し、RGB カラー値に変換します。r 成分 1 は 65535、g 成分 1 は 255、b 成分 1 は 1 を表します。
完全な実装コード: https://gitee.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/event/GPUPickEvent.js
2. マウス位置の読み取り色、読み取ったカラー値をカメラ空間深度値に復元します。
a. WebGLRenderTarget で「暗号化された」深度を描画します。カラーの読み取り方法
1 2 3 4 5 6 7 |
|
説明: offsetX と offsetY はマウスの位置、height はキャンバスの高さです。 readRenderTargetPixels 行の意味は、幅 1、高さ 1 のマウス位置 (offsetX、高さ - offsetY) のピクセルの色を選択することです。
pixel は Uint8Array(4) で、rgba カラーの 4 つのチャネルがそれぞれ格納され、各チャネルの値の範囲は 0 ~ 255 です。
b.「暗号化された」カメラ空間深度値を「復号」して、正しいカメラ空間深度値を取得します。
1 2 3 4 5 6 |
|
3. 画面上のマウスの位置とカメラ空間の深さに基づいて、交差点のワールド座標系の座標を補間および逆計算します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
完全なコード: https://gitee.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/event/GPUPickEvent.js
関連アプリケーション
GPU を使用してオブジェクトを選択し、交差位置を計算します。これは主に、非常に高いパフォーマンスが必要な状況で使用されます。例:
1. マウスが 3D モデルに移動したときのホバー効果。
2. モデルを追加するとき、モデルはマウスで移動し、シーンにモデルを配置した効果がリアルタイムでプレビューされます。
3. 距離測定や面積測定などのツール、直線や多角形を平面上でマウスを動かすとリアルタイムにプレビューでき、長さや面積を計算できます。
4. シーンとモデルは非常に大きく、レイ キャスティング方法の選択速度は非常に遅く、ユーザー エクスペリエンスは非常に悪いです。
これは、GPU を使用してオブジェクトを選択し、マウス ホバー効果を実現する図です。赤い境界線は選択効果、黄色の半透明の効果はマウス ホバー効果です。
######わからない?もしかしたら、three.js のさまざまな投影操作に慣れていないかもしれません。以下にthree.jsにおける射影演算式を示します。
1.modelViewMatrix = Camera.matrixWorldInverse * object.matrixWorld
2. viewMatrix = Camera 。 matrixWorldInverse
3.modelMatrix = object.matrixWorld
4.project = applyMatrix4( Camera.matrixWorldInverse ).applyMatrix4( Camera.projectionMatrix )
5. unproject = applyMatrix4( Camera .projectionMatrixInverse ).applyMatrix4( Camera.matrixWorld )
6. gl_Position = projectMatrix *modelViewMatrix *position
* viewMatrix * modelMatrix *position
参考資料:
1. 完全な実装コード: https://gitee.com/tengge1/ShadowEditor/blob/master/ShadowEditor.Web/src/event /GPUPickEvent.js
2. オープンソースの 3 次元シーン エディターthree.js に基づく: https://github.com/tengge1/ShadowEditor
3. シェーダーを使用して OpenGL で深度値を描画する :https://stackoverflow.com/questions/6408851/draw- the- Depth-value-in-opengl-using-shaders
4. glsl で、実際のフラグメント シェーダー深度値を取得します: https://gamedev.stackexchange.com/questions/93055/getting-the- real-fragment- Depth-in-glsl
この記事は
js チュートリアル列から引用したものです。ぜひ学習してください。
以上がthree.js は GPU を使用してオブジェクトを選択し、交差位置を計算しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。