ホームページ > ウェブフロントエンド > jsチュートリアル > 基本入門: Three.js を使用した WebGL 開発

基本入門: Three.js を使用した WebGL 開発

WBOY
リリース: 2023-08-30 13:25:05
オリジナル
1542 人が閲覧しました

ブラウザの 3D グラフィックスは、最初に導入されて以来、大きな話題となっています。ただし、純粋な WebGL を使用してアプリケーションを作成したい場合は、長い時間がかかります。最近、非常に便利なライブラリがいくつか登場したのはそのためです。 Three.js は最も人気のあるものの 1 つであり、このシリーズでは、これを最大限に活用してユーザーに素晴らしい 3D エクスペリエンスを作成する方法を説明します。

座標やベクトルなどについては説明しないので、始める前に、このチュートリアルを始める前に 3D 空間の基本を理解していることを期待します。


ステップ 1: 準備

まず、index.htmlmain.js、および style.css の 3 つのファイルを作成します。ここで、Three.js (サンプルとソース コードを含む zip ファイル全体、または別の JavaScript ファイル、お好みで選択) をダウンロードします。ここで、index.html を開いて次のコードを挿入します:

リーリー

このファイルに必要なのはこれだけです。スクリプトとスタイルシートの宣言だけです。すべての魔法は main.js で行われますが、その前に、アプリケーションの見栄えを良くするためのもう 1 つのトリックが必要です。 style.css を開き、次のコードを挿入します:

リーリー

body にはデフォルトで 8px の余白があるため、これによりキャンバスが左上隅に配置されます。次に、JavaScript コードに進みます。


ステップ 2: シーンとレンダラー

Three.js は表示リストの概念を使用します。これは、すべてのオブジェクトがリストに保存され、画面に描画されることを意味します。

Three.js は表示リストの概念を使用します。これは、すべてのオブジェクトがリストに保存され、画面に描画されることを意味します。この場合、それは

THREE.Scene オブジェクトです。画面上に描画したいオブジェクトをシーンに追加する必要があります。シーンは好きなだけ持つことができますが、レンダラーが一度に描画できるシーンは 1 つだけです (もちろん、表示されるシーンを切り替えることはできます)。

レンダラーは、シーン内のすべてを WebGL キャンバスに描画するだけです。 Three.js は SVG または 2D Canvas での描画もサポートしていますが、ここでは WebGL に焦点を当てます。

まず、ウィンドウの幅と高さを変数に保存しましょう。後で使用します。

リーリー

ここでレンダラーとシーンを定義します。

リーリー

最初の行は WebGL レンダラーを定義します。最初のパラメータでレンダラー オプションをマップとして渡すことができます。ここでは、オブジェクトのエッジをギザギザではなく滑らかにしたいため、

antialias を true に設定します。

2 行目でレンダラーのサイズをウィンドウのサイズに設定し、3 行目でレンダラーの

canvas 要素をドキュメントに追加します (ライブラリを使用してこれを行うこともできます)。例: jQuery: $( 'body').append(renderer.domElement))。

最後の定義シーンにはパラメーターは必要ありません。


ステップ 3: キューブ

次に、描きたいものを追加しましょう。最も単純な 3D オブジェクトである立方体としましょう。 Three.js では、画面上に描画されるオブジェクトをグリッドと呼びます。各メッシュには独自のジオメトリとマテリアルが必要です。ジオメトリは、オブジェクトを作成するために接続する必要がある点のセットです。マテリアルは、オブジェクトを覆う単なるペイント (またはペイントですが、それはこのチュートリアルのトピックではありません) です。それでは、キューブを作成しましょう。幸いなことに、Three.js にはプリミティブ (単純な形状) を作成するためのヘルパー関数がいくつかあります。 リーリー

ご覧のとおり、最初にジオメトリを作成します。パラメーターは立方体のサイズ (幅、高さ、奥行き) を定義します。

次に、立方体の材質を定義します。 Three.js にはいくつかのマテリアル タイプがありますが、後で照明が必要になるため、今回は

THREE.MeshLambertmaterial

を使用します (このマテリアルは照明計算に Lambert のアルゴリズムを使用します)。レンダラーの場合と同じように、最初の引数でオプションをマップとして渡すことができます。これは、Three.js のより複雑なオブジェクトのほぼ規則です。ここでは、16 進数として渡される色のみを使用します。 3 行目では、以前に作成したジオメトリとマテリアルを使用してメッシュを作成します。次に、立方体を Y 軸上で 45 度回転させて見栄えを良くします。度をラジアンに変更する必要があります。これは、高校の物理の授業で覚えた方程式

Math.PI * 45 / 180

で処理されます。最後に、立方体がシーンに追加されます。 これで、ブラウザで

index.html

を開いて結果を確認できますが、シーンはまだレンダリングされていないため、何も表示されません。


ステップ 4:

カメラ! 何かをレンダリングするには、まずシーンにカメラを追加して、レンダラーがどの角度からコンテンツをレンダリングすべきかを認識できるようにする必要があります。 Three.js にはいくつかの種類のカメラがありますが、おそらく

THREE.PerspectiveCamera

のみを使用するでしょう。このタイプのカメラは、私たちが見ている世界の風景を映し出します。作成しましょう: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:javascript;toolbal:false;"> var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000); </pre><div class="contentsignin">ログイン後にコピー</div></div> <blockquote class="pullquote pqRight"> <p> “要渲染某些内容,首先我们需要将相机添加到场景中,以便渲染器知道应该从哪个角度渲染内容。”</p> </blockquote> <p>创建相机比我们迄今为止所做的其他事情要复杂一些。第一个参数定义 FOV(视野),即从相机所在位置可以看到的角度。 45 度的 FOV 看起来很自然。接下来,我们定义相机的比率。这始终是渲染器的宽度除以高度,除非您想实现一些特殊效果。最后两个数字定义了对象与要绘制的相机的距离。</p> <p>现在我们必须稍微向后和向上移动相机,因为在 Three.js 中创建的所有对象都将其位置设置在场景中间(x: 0, y: 0, z: 0)默认:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:javascript;toolbal:false;"> camera.position.y = 160; camera.position.z = 400; </pre><div class="contentsignin">ログイン後にコピー</div></div> <p><code>z 坐标在观看者的方向上为正,因此具有较高 z 位置的对象会显得离您更近(在这种情况下,由于我们移动了相机,所有对象都会显得更远)来自您)。

现在,让我们将相机添加到场景并渲染它:

scene.add(camera);

renderer.render(scene, camera);
ログイン後にコピー

添加相机就像添加立方体一样。下一行使用该相机渲染场景。现在您可以打开浏览器,您应该看到以下内容:

基本入門: Three.js を使用した WebGL 開発

您应该只能看到立方体的顶部。这是因为我们将相机向上移动,但它仍然看起来在它的正前方。这个问题可以通过让相机知道它应该看什么位置来解决。在设置相机位置的行之后添加此行:

camera.lookAt(cube.position);
ログイン後にコピー

传入的唯一参数是相机将看到的位置。现在,场景看起来更好了,但立方体仍然是黑色,无论您在创建立方体时设置了什么颜色:

基本入門: Three.js を使用した WebGL 開発


第 5 步: 灯!

立方体是黑色的,因为场景中没有灯光,所以它就像一个完全黑的房间。您会看到白色背景,因为除了立方体之外没有任何东西可以绘制。为了避免这种情况,我们将使用一种称为天空盒的技术。基本上,我们将添加一个大立方体来显示场景的背景(如果是开放空间,通常是一些远处的地形)。那么,让我们创建这个盒子。此代码应位于 renderer.render 调用之前:

var skyboxGeometry = new THREE.CubeGeometry(10000, 10000, 10000);
var skyboxMaterial = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.BackSide });
var skybox = new THREE.Mesh(skyboxGeometry, skyboxMaterial);

scene.add(skybox);
ログイン後にコピー

此代码与创建多维数据集的代码类似。但这一次的几​​何形状要大得多。我们还使用了 THREE.MeshBasicMaterial 因为我们不需要照亮天空盒。另外,请注意传递给材料的附加参数:side: THREE.BackSide。由于立方体将从内部显示,因此我们必须更改绘制的侧面(通常,Three.js 只绘制外墙)。

现在渲染的场景是全黑的。为了解决这个问题,我们必须向场景添加灯光。我们将使用 THREE.PointLight,它像灯泡一样发出光。在天空盒后添加这些行:

var pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(0, 300, 200);

scene.add(pointLight);
ログイン後にコピー

如您所见,我们创建了白色的点光源,然后将其位置设置为向上和向后一点,以照亮立方体的正面和顶部。最后,灯光像任何其他对象一样添加到场景中。打开浏览器,您应该会看到一个彩色阴影立方体:

基本入門: Three.js を使用した WebGL 開発

但是立方体仍然很无聊。让我们为其添加一些动作。


第 6 步: 行动!

现在我们将为场景添加一些运动。让我们让立方体绕 Y 轴旋转。但首先,我们必须改变渲染场景的方式。一次 renderer.render 调用,渲染场景的当前状态一次。因此,即使我们以某种方式为立方体设置动画,我们也不会看到它移动。要改变这一点,我们必须将渲染循环添加到我们的应用程序中。这可以使用专门为此目的创建的 renderAnimationFrame 函数来实现。大多数主要浏览器都支持它,对于那些不支持它的浏览器,Three.js 附带了自己的 polyfill。那么,让我们改变一下:

renderer.render(scene, camera);
ログイン後にコピー

对此:

function render() {
	renderer.render(scene, camera);
	
	requestAnimationFrame(render);
}

render();
ログイン後にコピー

实际上,那里没有循环,因为它会冻结浏览器。 requestAnimationFrame 函数的行为有点像 setTimeout,但它会在浏览器准备就绪时调用该函数。因此,显示的场景没有任何变化,立方体仍然没有移动。让我们解决这个问题。 Three.js自带了THREE.Clock,可以用来实现对象的平滑动画。首先在render函数定义之前进行初始化:

var clock = new THREE.Clock;
ログイン後にコピー

现在,每次调用 clock.getDelta 时,它都会返回自上次调用以来的时间(以毫秒为单位)。这可以用来旋转立方体,如下所示:

cube.rotation.y -= clock.getDelta();
ログイン後にコピー

render 函数中的 renderer.renderrequestAnimationFrame 调用之间添加此行。它只是减去立方体在 Y 轴上旋转所花费的时间(记住它以弧度为单位)来顺时针旋转立方体。现在打开浏览器,您应该看到立方体顺时针平稳旋转。


结论

在本系列的这一部分中,您学习了如何准备场景、添加对象和灯光以及如何为事物设置动画。您可以尝试该应用程序,添加更多或不同的对象、灯光。由你决定。下次我将向您展示如何使用纹理以及如何使用粒子创建一些漂亮的效果。如果遇到任何问题,请不要忘记查看文档。

以上が基本入門: Three.js を使用した WebGL 開発の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート