ブラウザで3D画像を実現します

HTML 3Dロゴ この記事では、3Dモニターを使用した実験のストーリーを続けたいと思います。 最初の記事では、ビデオストリームから(VLCプレーヤーで)ステレオ画像を出力する方法について説明しましたが、次に、ブラウザーでステレオ画像を直接取得する方法を説明します。 デモでは、Habréですでに多くのことを書いたすばらしいThree.jsライブラリを取り上げました。これにより、WebGLで美しいWebアプリケーションをすばやく簡単に作成できます。 以下に、平面投影ではなく、深い3D画像をユーザーに表示する方法を示します。







Three.jsの最も単純な例をソースデータとして使用します。

-それは回転する立方体になります。 3D効果をより明るくするために、観察者に向かってもう1つ前方への動きを追加しました。



3次元画像の2つの短縮を取得するために、このようなトリックを行います

各フレームのレンダリングループ内:

-カメラから画面ではなくテクスチャにシーンを描画します

-カメラを移動します(2番目の目の位置まで)

-シーンを異なるテクスチャに描画します

-これで、左目と右目用の写真ができました-左目が左の写真と右目を見るようにそれらを混ぜるだけです-3Dモニターの右の写真。



コードで説明する

(webgl_geometry_cubeの例の基本的なコードは意味がありません。追加したもののみを説明します)



更新:アナグリフをデモに追加していただきありがとうございます。赤青メガネを備えたどのモニターでも試用できます。

//        function initORTscene() { //projection to screen rtTexture = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBFormat }); ltTexture = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBFormat }); //      -       materialScreen = new THREE.ShaderMaterial({ uniforms: { lRacurs: { type: "t", value: ltTexture }, rRacurs: { type: "t", value: rtTexture }, height: { type: "f", value: window.innerHeight } }, vertexShader: document.getElementById('vertexShader').textContent, fragmentShader: document.getElementById('fragmentShader').textContent, depthWrite: false }); //        var plane = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight); var offscreenMesh = new THREE.Mesh(plane, materialScreen); offscreenMesh.position.z = -1; //a little behind sceneORT = new THREE.Scene(); //    ,         cameraORT = new THREE.OrthographicCamera(window.innerWidth / -2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / -2, -10000, 10000); sceneORT.add(offscreenMesh); }
      
      







シェーダー

それらの中で、画面のピクセルで2つのテクスチャとフレームの高さを渡します

頂点シェーダーはポイントの位置を計算し、ピクセルシェーダーに渡します

偶数の垂直線があるかどうかを計算します。偶数線の場合は1つのテクスチャを使用し、奇数線の場合は別のテクスチャを使用します( この記事では、この方法で3D画像を作成する方法を書きました)



 <script id="fragmentShader" type="x-shader/x-fragment"> varying vec2 vUv; uniform sampler2D rRacurs; uniform sampler2D lRacurs; uniform float height; void main() { //odd from left racurs, even from right float d = mod((floor(height*(vUv.y+1.0))),2.0); //odd or even, height - is new uniform to get viewport height if(d > 0.1) { gl_FragColor = texture2D( rRacurs, vUv ); } else { gl_FragColor = texture2D( lRacurs, vUv ); } } </script> <script id="vertexShader" type="x-shader/x-vertex"> varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } </script>
      
      







今私たちのシーンを描きます



  var x = camera.position.x; var faceWidth = 5; //   //   camera.position.x = x + faceWidth / 2; renderer.render(scene, camera, rtTexture, true); //   camera.position.x = x - faceWidth / 2; renderer.render(scene, camera, ltTexture, true); camera.position.x = x; //           renderer.render(sceneORT, cameraORT);
      
      







以上です。

パッシブ3Dモニターの幸せな所有者は、 デモを見ることができます(通常のモニターでは、それほど美しくはありません)。 コードはgithubにあります



確かに30行のコードではなく、70行以下であり、3D画像を実装するのに必要なのはこれだけです。



faceWidthパラメーターは変更できます-大きいほど、3Dが強くなりますが、幾何学的な歪みが大きくなります。



このコードは、three.js(WebGL)で記述されたすべてのシーンに使用して、実際の3Dを追加できます。たとえば、javascriptの学習の一環として作成したゲームへのリンクを次に示します。



更新:このデモにアナギフ効果を追加してくれたKOLANICHに感謝します-これで、赤青メガネを備えた任意のモニターで視聴できます。 持っていないので確認できませんが、誰かがバグを確認して発見したら、プルリクエストを受け入れます。



All Articles