オーシャンを作ってみた

Three.jsサンプルより

Three.jsで海を作るコード。それぞれのパラメータの意味はわからないけれど、自分の環境でサンプル・コードが動きました。

コード

html

各回共通の環境準備のmln.jsの下に、今回のモジュールを追加します。

<div class="mlnTest" id="mlnOutput"></div>
<script type="importmap"> { "imports": { "three": "/js/three/three.module.min.js" } } </script>
<script type="module" src="/js/three/mln.js"></script>
<script type="module" src="/asset/2025/02-18/mlnTest.js"></script>

mlnTest.js (2025.02.18)

/* mlnTest.js  2025/02-18
 * Ocean
 */

import * as THREE from 'three'
import { scene, grid, camera, renderer, controls } from '/js/three/mln.js'

// グリッドを消す
scene.remove(grid)

// 必要なモジュールをインポート
import { Water } from '/js/three/jsm/objects/Water.js'
import { Sky } from '/js/three/jsm/objects/Sky.js'

// 空
const sky = new Sky()
sky.scale.setScalar(10000)
scene.add(sky)

// 太陽
const pmremGenerator = new THREE.PMREMGenerator(renderer)
const sun = new THREE.Vector3()

// Defining the x, y and z value for our 3D Vector
const theta = Math.PI * (0.505 - 0.5),    // (0.49 - 0.5),
      phi = 2 * Math.PI * (0.205 - 0.5)
sun.x = Math.cos(phi)
sun.y = Math.sin(phi) * Math.sin(theta)
sun.z = Math.sin(phi) * Math.cos(theta)
sky.material.uniforms['sunPosition'].value.copy(sun)
scene.environment = pmremGenerator.fromScene(sky).texture
const light = new THREE.DirectionalLight(0xffaa00, 0.5) // 暖色の夕陽っぽい光
light.position.copy(sun)
scene.add(light)

// 海
const waterGeometry = new THREE.PlaneGeometry(10000, 10000),
      water = new Water(waterGeometry, {
            textureWidth: 512,
            textureHeight: 512,
            waterNormals: new THREE.TextureLoader().load(
                            '/js/three/textures/waternormals.jpg',
                            function (texture) {
                                texture.wrapS = texture.wrapT = THREE.RepeatWrapping
                            }),
            alpha: 1.0,
            sunDirection: new THREE.Vector3(),
            sunColor: 0xffffff,
            waterColor: 0x001e0f,
            distortionScale: 3.7,
            fog: scene.fog !== undefined
        })
water.rotation.x = -Math.PI / 2
scene.add(water)

// カメラとコントロールの調整
camera.position.set(0, 10, 200)
camera.lookAt( 0, 10, 0 )
controls.maxPolarAngle = Math.PI * 0.495
controls.target.set(0, 10, 0)
controls.minDistance = 40.0
controls.maxDistance = 200.0
controls.update()

// 波
function animate() {
    requestAnimationFrame(animate)
    water.material.uniforms.time.value += 1.0 / 240.0
    renderer.render(scene, camera)
}
animate()

日本海の夕陽には程遠いけど、スクリプトが動いて嬉しいです。



関連記事