Babylon.js で試行錯誤してゴルフコースを作ったよ

## はじめに

こんにちはうえむーです！
本題の件、Babylon.jsでゴルフコースを作りました。
今年の11月から作成して色々と試行錯誤して12月の中旬に完成しました。

この記事は[Babylon.js Advent Calendar 2023](https://qiita.com/advent-calendar/2023/babylonjs)の24日目の記事です。


## グリーン・池・バンカー・木作成する。

まずは、いろんなメッシュ・テクスチャ・プロパティでグリーン・池・バンカー・木を作成しました。
この頃はグリーン・池・バンカーは64みたいにカクカクしていて、木も雑に並んでいる状況でした。

https://twitter.com/uemuragame5683/status/1720964142520037530/video/1

## グラデーションを細かくする

あまりにもグラデーションが荒すぎるので
CreateGroundFromHeightMapのsubdivisionsプロパティを設定して
グラデーションを細かくしました。
木は自然ぽっく配置しようと実装しているのですがなかなかうまく出来ず苦戦しておりました。

https://twitter.com/uemuragame5683/status/1723248186977112226/video/1

高低差の設定は以下の公式ドキュメントのチャプターに記載してます。
https://doc.babylonjs.com/features/introductionToFeatures/chap5/hills

最初はCreateGroundFromHeightMapのsubdivisionsの設定を

```

const largeGround = BABYLON.MeshBuilder.CreateGroundFromHeightMap("largeGround", "textures/ground/villageheightmap.png", {width:72, height:72, subdivisions: 20, minHeight:0, maxHeight: 8.5});  

```

から

```

const largeGround = BABYLON.MeshBuilder.CreateGroundFromHeightMap("largeGround", "textures/ground/villageheightmap.png", {width:72, height:72, subdivisions: 200, minHeight:0, maxHeight: 8.5});  

```

に変更しました。

## ラフ・噴水を追加

さらにリアリティ感を出して、ラフや噴水を追加しました。

https://twitter.com/uemuragame5683/status/1726051665516630108

噴水の作成仕方は以下の公式ドキュメントのチャプターに記載してます。

噴水の作成
https://doc.babylonjs.com/features/introductionToFeatures/chap6/fountain

水しぶきを出す
https://doc.babylonjs.com/features/introductionToFeatures/chap6/particlespray


## 夜バージョンを作成

昼バージョンだけでなく、夜バージョンも作成しました。

https://twitter.com/uemuragame5683/status/1729132545823166624/


変更した内容は木・空のテクスチャを昼用・夜用に出しわけしていたのと、
ライト設定を大きく変更しました。

昼は環境光源を設定し、夜は環境光源をなくして、
点光源を設定して位置を設定して球型のメッシュを追加して月を作成しました。

```

const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
      light.intensity = .6;


const spot = new BABYLON.PointLight("spot", new BABYLON.Vector3(5, 5, 5));
      spot.diffuse = new BABYLON.Color3(.7, .7, .7);
      spot.specular = new BABYLON.Color3(0, 0, 0);
      spot.position.y = 20;
      spot.position.x = 45;

const moon = BABYLON.Mesh.CreateSphere("moon", 10, 4);
      moon.material = new BABYLON.StandardMaterial("moon");
      moon.material.emissiveColor = new BABYLON.Color3(1, 1, 0);  
      moon.position.y = 20;
      moon.position.x = 45;

```

## スポットライトを作成

木の大きさを調整して、スポットライトを追加した。

https://twitter.com/uemuragame5683/status/1733276773805424877/

スポットライトの作成は以下の公式ドキュメントのチャプターに記載してます。
https://doc.babylonjs.com/features/introductionToFeatures/chap7/lights

## ライトモード・ダークモード切り替え機能追加

ライトモードとダークモード切り替えるようにしました

https://twitter.com/uemuragame5683/status/1736293869493563701/

Light or Dark をクリックしたら、
一度canvasの要素を削除して、新たにcanvasの要素を生成して、
環境設定・メッシュなどを生成するようにしております。

```
    <main> 
      <canvas id="renderCanvas"></canvas>
      <div class="c-button-wrap">
        <button type="button" class="c-button" id="light">Light</button>
        <button type="button" class="c-button" id="dark">Dark</button>
      </div>  
    </main>  
```

```
        const button_targets = document.getElementsByClassName('c-button');

        for(let i = 0; i < button_targets.length; i++){
          button_targets[i].addEventListener("click",(e) => {
            light_dark(e.target.getAttribute('id'));
          }, false);
        }
    
        function light_dark(target) {
          const canvas = document.getElementById('renderCanvas');
                canvas.remove();
    
          const canvas_element = document.createElement('canvas');
                canvas_element.setAttribute("id",'renderCanvas');
          const main = document.getElementsByTagName("main");
                main[0].prepend(canvas_element);
          const new_canvas = document.getElementById('renderCanvas');
          const engine = new BABYLON.Engine(new_canvas);
          renderfunction(target);
        }

        function renderfunction(light_dark) {
          ... レンダリング処理
        }

```

## 完成

そして、完成したのがこちらになります。
なかなかいいのが出来ました。

https://babylonjs-tau.vercel.app/golf/

昼

![名称未設定2 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517490/074b5068-8884-92b8-dc2f-e7a23cbb22ec.gif)

夜

![名称未設定3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517490/76e0c8df-c480-f27c-8c58-316f1c3cd18d.gif)

GitHubにも公開してるので興味があったらみてください。
https://github.com/uemura5683/babylonjs/blob/main/golf/index.html