3D 表現により、平面を通してさまざまな角度から実際のオブジェクトの表示効果を見ることができることがわかっています。
コンピューターの世界では、3D 世界は点で構成されており、2 つの点が直線を形成し、直線上にない 3 つの点が三角形の面を形成し、無数の三角形の面がさまざまな形のオブジェクトを形成します。次の写真です。
Three のモデル パーサーの原理は、モデルの頂点を配列に格納し、次に、three の face 関数を使用して、固定小数点配列内の 3 つまたは 4 つの頂点のインデックスを取得して形成することです。空間面。これを繰り返すことでモデルが完成します。
したがって、オブジェクトが複雑になればなるほど、より多くのメッシュのスプライシングが必要になります。 CSS には座標に基づいて空間平面を確立する機能はありません。
(余談ですが、実はCSSにはclip-pathという座標に関係する属性があります。この属性の特性によりCSS3に一定のモデリング機能が与えられます。実装方法についてはこちらの記事を参照してください。 純粋なクリップで作成した3Dパスモデルレンダラ)
CSS3 を使用して 3D パノラマ
を実現します。前回の記事では、Web3D のいくつかの表現を紹介しました。ここでは、CSS3 を使用して 3D パノラマを実現する方法に焦点を当てます。次に、パノラマを実現するための Three のソリューションを検討します。WebGL の敷居と学習コストはまだ比較的高く、急速な開発には適していません。 Creation Festival の CSS3D Panorama については、このテクノロジーを調査した記事がいくつかありましたが、具体的な実装方法について深く掘り下げた記事はありませんでした。
実装方法を明確に理解するには、CSS3の変換とパースペクティブについて一定の理解が必要です。
原理については詳しく説明しません。CSS3D の概要を理解するには、まずこの記事を読んでください。
CSS 3D で遊ぶ - 原則
CSS パノラマは、列または立方体を作成し、マッピングを使用することで実現できます。球体は機能するのか?と疑問に思う人もいるかもしれません。実際には、球体モデルは無数の小さな平面をつなぎ合わせて構成されており、CSS には平面を歪ませる性質がありません。前述の Clip-3d を使用して球モデルを構築することはできますが、テクスチャの問題は解決できません。
Sky Box
3D パノラマを作成したことがある、または 3D パノラマについて学んだ多くの同僚がこの概念を知っていると思います。実際、Skybox は立方体であり、6 つの側面に異なる絵を貼り付けることで、端がシームレスに収まり、遠近感がボックスの内側に拡張されます。私たちは巨大な立方体の箱の中に立っていると想像でき、視点を動かすことでさまざまな景色が見えます。
1. テクスチャ
カットヘッドが指すエッジは、シームレスにフィットする必要があるエッジを表します。
上の図からわかるように、互いに適合する 2 つのサーフェス上の画像をシームレスに接合できる限り、各サーフェスで特定の回転変換を実行することで、スカイ ボックスを作成できます。
それでは、問題は、このような写真をどうやって撮るかということです。これには、pano2vr、max などの専門的なソフトウェアが必要です。実際、これらのプロフェッショナル ツールを使用して作成されたパノラマには、画質とステッチに対する非常に高い要件があり、CSS3 の変更だけに依存するだけでは良いエクスペリエンスを得ることができません。
しかし、私たちが今日議論しているのは、特定の運用活動のために H5 によって作成されたパノラマです。このパノラマは必ずしも実際に存在するとは限らず、実際のシーンとの間に一定の比率のギャップがある可能性があります。例えば、星空や海の底。このような人為的にフィット感を変えることができるパノラマの作成には、既存の高解像度画像を PS を通じて 6 面パノラマに変換することができます。
記事を投稿する 写真からスカイボックスを作成する
実際、主なアイデアは、
大きな画像上で 6 つの顔の選択範囲の輪郭を描く>
大きな画像内で顔の隣接する顔を選択し、必要なボックスに回転させることです。特定の面にぴったりとフィットさせます>
最も合理的な6面マップを取得した後、新しいエッジが作成されるかどうかを観察し、マスクなどのツールを使用して自然にブレンドします。
2. テクスチャの構築が完了したら、立方体を作成できます。まず、作成した 6 つの面を切り出し、マークされた位置に前、後ろ、左、右... と名前を付けます。
.sence { -webkit-perspective: 1000px; } .cube { width: 500px; height: 500px; margin: 100px auto; transform-style: preserve-3d; } .cube img { width: 130px; height: 130px; position: absolute; } .cube img:nth-child(1) { } .cube img:nth-child(2) { transform: rotateY(180deg); } .cube img:nth-child(3) { transform: rotateY(90deg); } .cube img:nth-child(4) { transform: rotateY(-90deg); } .cube img:nth-child(5) { transform: rotateX(90deg); } .cube img:nth-child(6) { transform: rotateX(-90deg); }
6面を用意してテクスチャを読み込みます。回転すると、各面が対応する位置に回転します。たとえば、左側の面は、最初にこちらを向いていた画像を Y 軸を中心に反時計回りに 90 度回転させることによって得られます。 (Y 軸の反時計回りの回転は正の数であることに注意してください)
このとき、下の写真のような効果が得られます。
ただし、各面の回転中心はその中心にあるので、まだ立方体を形成できません。したがって、各サーフェスに特定の変位を持たせる必要があります。
誰もが理解できるように座標系図を投稿してください。
次に、まず前面をあるべき場所に移動します。パノラマのレンズは立方体の内側にあるため、画像を後方に移動する必要があると想像できます。移動距離は明らかに立方体の辺の長さの半分です。ここでは65pxです。以下の結果を取得します。
<div class="sence"> <div class="cube"> <img src="img/skybox/front.jpg" alt="" /> <img src="img/skybox/back.jpg" alt="" /> <img src="img/skybox/left.jpg" alt="" /> <img src="img/skybox/right.jpg" alt="" /> <img src="img/skybox/top.jpg" alt="" /> <img src="img/skybox/bottom.jpg" alt="" /> </div> </div>
こうやって見ると、後ろの変位がtranslateZ(65px)、左の変位がtranslateX(-65px)、上がtranslateY(-65px)ということになるでしょうか?しかし、結果は私たちが望むものではありません。
上記の空間座標系の地図をもう一度見てみると、平面が回転すると、それに対応する 3 つの軸の位置も変化することがわかります。たとえば、画像が Y を中心に回転すると、Z 軸は画面の水平方向を指します。 X を中心に回転すると、Z 軸は垂直方向を指します。したがって、実際には、ベニアを正しい位置に移動するには、translateZ(-width/2px) を要求するだけでよいことが簡単にわかります。
皆さんに分かりやすくするために、ここではより大きな視点を設定しました。パノラマ効果を得るには、ズームインしてボックス内に入れるだけです。
次に、ジェスチャをバインドすると、ジェスチャを動かすことができます。
コードの一部:
.cube img:nth-child(1) { transform: translateZ(-65px); }
Math.atan2(y,x) メソッド: x 軸から点 (x,y) までの角度を取得します。左の空間系を理解するのは難しいですが、空間の Z 軸を Y 軸とする平面の X 軸の正の方向の周りの回転角度が立方体の回転角度であると想像できます。空間の Y 軸。
円柱
円柱のパノラマはそれほど複雑ではありません。円筒形の作成方法については、こちらの記事「CSS3 3D 変換シリーズ チュートリアル - 3D カルーセル」を参照してください。この基礎を使用して、円筒形のパノラマをすばやく構築する関数を作成できます。
viewer.on('touchstart', function(e) { x1 = e.targetTouches[0].pageX; - $(this).offset().left; y1 = e.targetTouches[0].pageY; - $(this).offset().top; }); viewer.on('touchmove',function(){ var dist_x = x2 - x1, dist_y = y2 - y1, deg_x = Math.atan2(dist_y, perspective) / Math.PI * 180, deg_y = -Math.atan2(dist_x, perspective) / Math.PI * 180, i, c_x_deg += deg_x; c_y_deg += deg_y; cube.css('transform', 'rotateX(' + deg_x + 'deg) rotateY(' + deg_y + 'deg)'); })
<style> body { height: 100%; overflow: hidden; } .scene { width: 100%; height: 1170px; transform: translateX(-50%) translateY(-50%); top: 50%; left: 50%; position: absolute; } .cube { transform-style: preserve-3d; height: 100%; width: 100%; margin: 0px auto; } .cube_bg { transform-style: preserve-3d; height: 100%; width: 128px; margin: 0px auto; } .cube_bg div { height: 100%; /* 这里为圆柱形的每个面都设定了同样的背景图 那么在建造柱形时不再需要手动切图 */ background-image: url("img/zao/zao.png"); background-repeat: no-repeat; position: absolute; top: 0; } </style> <body> <div class="scene"> <div class="cube"> <div class="cube_bg"> <!-- 这里是柱形全景背景贴图 --> </div> <div class="cube_item"> <!-- 这里是柱形全景中的小元件 --> </div> </div> </div> </body>
図を見てください。上の lenZ は、translateZ 値であり、負の値です。
遠近感はレンズからスクリーンまでの距離です。このときレンズは円柱の中にあるため、円柱の後ろの画像は見えません。
遠近感の値が -lenZ の場合、一定の確率でレンズを遮るのを避けるために、円柱の背面をレンズと同じ平面上に置くことができ、レンズに近づけてズームインできます。 -lenZ-5 に設定されます。このとき、レンズが確実に円筒内に収まると同時に、円筒の全景をより広い角度から観察することができます。