Svelte で3D表示を行うライブラリ Threlte #2: エクストラパッケージを使用する

# シリーズ

### Main

* [Svelte で 3D 表示を行うライブラリ Threlte #1: パッケージの作成とライブラリ概要](https://qiita.com/takavfx/items/0d4c6b831628d628b468)
* Svelte で 3D 表示を行うライブラリ Threlte #2: エクストラパッケージを使用する
* [Svelte で 3D 表示を行うライブラリ Threlte #3: glTF シーンを扱う](https://qiita.com/takavfx/items/aa05a313ef9e450b3731)
* [Svelte で 3D 表示を行うライブラリ Threlte #4: シーンコントロールツールセット Theatre.js for Threlte](https://qiita.com/takavfx/items/b91ba3c47e5137723a5f)
* [Svelte で3D表示を行うライブラリ Threlte #5: XR への対応](https://qiita.com/takavfx/items/6a499286c8a125c7b65d)

### Extra

* [Svelte で 3D 表示を行うライブラリ Threlte Ex1: Svelte5 対応を試す](https://qiita.com/takavfx/items/13feec35d60fe629eb26)

# エクストラパッケージの概要

エクストラパッケージには以下の様な機能が内包されている。

* トランスフォームコントロール (オブジェクト操作を可能にする。)
* オービットコントロール(カメラ操作を可能にする機能)
* 背景 (Environment) の追加
* オーディオ再生
* グリッド表示
* ギズモ表示
* GLTF の使用
* スカイオブジェクトの使用
* HTML オブジェクト (3D シーンの中で HTML を扱うもの)


:::note info
以上のように、3D で描画しているんだったらこれをは入れたいよねって基本的な拡張パッケージとなっている。
個人的には最初っから入れる選択をしていいものだと思うので、`@threlte/core` のインストールと一緒にこちらもインストールしておきたい。
:::

# エクストラパッケージの利用

ここでは上記からいくつかの利用用途を記載しておく。

## エクストラパッケージをインストールする

Threlte のエクストラパッケージは `@threlte/extra` というパッケージでまとめられている。

```bash
npm install -D @threlte/extra
```

## オービットコントロール

ビューポート上で

以下の例では、`autoRotate` と `autoRotateSpeed={}` 属性が設定されているため、ターンテーブルの様にオブジェクトの周りを周回するような動きを設定しています。

```diff_svelte:Scene.svelte
<script>
  import { T, Canvas } from '@threlte/core'
+  import { OrbitControls } from '@threlte/extras'
</script>

<!-- 各種シーン設定は省略 -->

<T.PerspectiveCamera
  makeDefault
  position={[-10, 10, 10]}
  fov={15}
>
  <!-- カメラのオービットコントロールを設定 -->
  <!-- autoRotate と autoRotateSpeed を追加、enableZoom を false に設定 -->
+  <OrbitControls
+    autoRotate
+    enableDamping
+    autoRotateSpeed={0.5}
+    target.y={1.5}
+  />
</T.PerspectiveCamera>
```

![output1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/54807ebe-25b9-55ed-da4d-0bd676601e38.gif)

https://threlte.xyz/docs/reference/extras/orbit-controls

## グリッドの表示

ビューポート上にグリッド表示を追加します。
`cellColor` 属性でグリッドの色を設定したり、`fadeDistance` 属性でカメラの距離に応じてフェイドを書ける処理を設定できます

```diff_svelte:Scene.svelte
<script>
  import { T, Canvas } from '@threlte/core'
+  import { Grid } from '@threlte/extras'
</script>

<!-- 各種シーン設定は省略 -->

+<Grid
+	position.y={-0.001}
+	cellColor="#ffffff"
+	sectionColor="#ffffff"
+	sectionThickness={0}
+	fadeDistance={25}
+	cellSize={2}
+/>
```

| グリッド無し| グリッド有り | フェード在り |
|:-----------:|:------------:|:------------:|
| ![cFcOe0F2n2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/29d06f07-a726-9d31-8307-9d8238d387cc.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/be789f95-7c64-7d00-728f-7520568fa393.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/1c4aa0ca-03e4-b5ef-1cdc-30f97decca31.png) |


https://threlte.xyz/docs/reference/extras/grid

## ギズモを追加する

ギズモを追加するには `<Gizmo>` コンポーネントを使用する。

```diff_svelte:Scene.svelte
<script lang="ts">
	import { T } from '@threlte/core';
+	import { Grid, OrbitControls, ContactShadows, Gizmo } from '@threlte/extras';
</script>

<!-- 各種シーン設定は省略 -->

+<Gizmo horizontalPlacement="lef" />
```

![2024-01-29 23.06.27 localhost 71079ccc17ae.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/8e626ac0-b6a3-f411-720c-10b8e0231fdb.png)

## エッジ表示を行う

エッジの描画色を変更するコンポーネント。
`<Edges>` コンポーネントを使用する。

この際、エッジの色が対象オブジェクトの色で隠れてしまうため、場合によって対処が必要。

```diff_svelte:Scene.svelte
<script lang="ts">
	import { T } from '@threlte/core';
+	import { Edges } from '@threlte/extras';
</script>

<T.Mesh position={[0, 2, 0]}>
	<T.SphereGeometry />
	<T.MeshStandardMaterial />
+	<Edges color="white" />
</T.Mesh>
```

![2024-01-29 23.13.02 localhost e4749d6a5033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/7e5bd364-e483-4b18-164e-ea14e32a29f2.png)


## スカイオブジェクトの追加

スカイ (Sky) オブジェクトは、ライティング及び背景に対して影響を及ぼすオブジェクト。
もともと、Three.js の [Sky 実装](https://github.com/mrdoob/three.js/blob/dev/examples/jsm/objects/Sky.js)をもとにしているとのこと。
これの配置には `<Sky>` を使用する。

```diff_svelte:Scene.svelte
<script lang="ts">
	import { T } from '@threlte/core';
	import { OrbitControls, Sky } from '@threlte/extras';
</script>

<T.PerspectiveCamera makeDefault position={[-15, 0, 15]} fov={15} far={10000}>
	<OrbitControls enableZoom={true} enableDamping target.y={1.5} />
</T.PerspectiveCamera>

<Sky />

<T.Mesh position.y={1.2}>
	<T.SphereGeometry />
	<T.MeshStandardMaterial roughness={0.0} metalness={1.0} />
</T.Mesh>
```

![2024-01-28 19.14.26 localhost bf5dc4b2a802.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/203aa553-38dd-a067-7768-985454af7573.png)

パラメーターを変えることで、日中から真夜中まで表現できる。

```svelte:Scene.svelte
<Sky
	setEnvironment={true}
	elevation={0.15}
	turbidity={10.0}
	rayleigh={3.0}
	azimuth={180.0}
	mieCoefficient={0.005}
	mieDirectionalG={0.7}
/>
```

![2024-01-28 19.21.35 localhost 38be7d41b21f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/fcd1da0d-84bd-4261-420a-f63792ebc42b.png)

## 背景 (Environment) の追加

背景 (Environment) は、シーンに対して球面状に背景を設定します。
また、対応画像からのライティングにも対応するので、HDRI を使用したライティングにも対応します。

以下では、

```svelte:Scene.svelte
<script>
  import { T, Canvas } from '@threlte/core'
+  import { Environment } from '@threlte/extras'
</script>

<!-- 各種シーン設定は省略 -->

<!-- files に対象ファイルのパスを指定。今回は Three.js のサンプルから直接ロード -->
<Environment
	files={'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/equirectangular/venice_sunset_1k.hdr'}
	isBackground={true}
/>

<!-- 分かりやすいように反射率高め設定 (roughness={0}) の球体を配置 -->
<T.Mesh position.y={1.2}>
	<T.SphereGeometry />
    <T.MeshStandardMaterial color="grey" roughness={0.0} />

</T.Mesh>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/92bc6d1d-dcfd-7063-3613-8f9926ee4b19.png)


---

:point_right:次のシリーズを読む
[Svelte で 3D 表示を行うライブラリ Threlte #3: glTF シーンを扱う](https://qiita.com/takavfx/items/aa05a313ef9e450b3731)