【Three.js】海を表示してみる
こんにちは。kyamashitaです。
今回は three.js のexampleを修正して海を表示してみました。
Three.js の example
にすばらしい例がたくさんありますので、参考にします。
今回は webglshadersocean2 を参考にしました。
https://threejs.org/examples/webglshadersocean2.html
すでに海なのですが、カメラの位置等変更してみます。
構成
Three.jsの公式サイトからダウンロードし、以下のような構成にします。
index.html に webglshadersocean2 のコードをコピーし修正していきます。
build/
docs/
editor/
examples/
files/
src/
test/
utils/
index.html
やったこと
FPSの表示と、コントローラーを削除します。
dat.GUI(パラーメータ調整ライブラリ)にカメラの位置を追加します。
※dat.GUIとは・・・パラーメータ調整ライブラリ https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage
カメラや海のパラメータを変えて調整し、お気に入りの設定を初期値とし、dat.GUIを削除(コメント化)します。
ソース
上記実施後は以下のようになります。※dat.GUI部分はコメント化しています。
ほぼexampleのままで不要箇所削除と初期値の設定しました。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>sample</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script type="module">
import * as THREE from '/build/three.module.js';
// import { GUI } from '/examples/jsm/libs/dat.gui.module.js';
import { Ocean } from '/examples/jsm/misc/Ocean.js';
var lastTime = ( new Date() ).getTime();
var DEMO = {
ms_Renderer: null,
ms_Camera: null,
ms_Scene: null,
ms_Controls: null,
ms_Ocean: null,
Initialize: function () {
this.ms_Renderer = new THREE.WebGLRenderer({ alpha: true });
this.ms_Renderer.setPixelRatio( window.devicePixelRatio );
document.body.appendChild( this.ms_Renderer.domElement );
this.ms_Scene = new THREE.Scene();
this.ms_Camera = new THREE.PerspectiveCamera( 55.0, window.innerWidth / window.innerHeight, 0.5, 300000 );
var gsize = 512;
var res = 1024;
var gres = res / 2;
var origx = - gsize / 2;
var origz = - gsize / 2;
this.ms_Ocean = new Ocean( this.ms_Renderer, this.ms_Camera, this.ms_Scene,
{
USE_HALF_FLOAT: false,
INITIAL_SIZE: 256.0,
INITIAL_WIND: [ 10.0, 10.0 ],
INITIAL_CHOPPINESS: 1.5,
CLEAR_COLOR: [ 1.0, 1.0, 1.0, 0.0 ],
GEOMETRY_ORIGIN: [ origx, origz ],
SUN_DIRECTION: [ - 1.0, 1.0, 1.0 ],
OCEAN_COLOR: new THREE.Vector3( 0.004, 0.016, 0.047 ),
SKY_COLOR: new THREE.Vector3( 3.2, 9.6, 12.8 ),
EXPOSURE: 0.35,
GEOMETRY_RESOLUTION: gres,
GEOMETRY_SIZE: gsize,
RESOLUTION: res
} );
this.ms_Ocean.materialOcean.uniforms[ "u_projectionMatrix" ] = { value: this.ms_Camera.projectionMatrix };
this.ms_Ocean.materialOcean.uniforms[ "u_viewMatrix" ] = { value: this.ms_Camera.matrixWorldInverse };
this.ms_Ocean.materialOcean.uniforms[ "u_cameraPosition" ] = { value: this.ms_Camera.position };
this.ms_Scene.add( this.ms_Ocean.oceanMesh );
// 調整したパラメータ設定
this.ms_Camera.position.set(0, 80, 160);
this.ms_Ocean.size = 100;
this.ms_Ocean.choppiness = 4;
this.ms_Ocean.windX = 15;
this.ms_Ocean.windY = -15;
this.ms_Ocean.sunDirectionX = -1;
this.ms_Ocean.sunDirectionY = 1;
this.ms_Ocean.sunDirectionZ = 1;
this.ms_Ocean.exposure = 0.5;
// const that = this;
// this.controls = new function() {
// this.cpX = that.ms_Camera.position.x;
// this.cpY = that.ms_Camera.position.y;
// this.cpZ = that.ms_Camera.position.z;
// this.crX = that.ms_Camera.rotation.x;
// this.crY = that.ms_Camera.rotation.y;
// this.crZ = that.ms_Camera.rotation.z;
// }
// var gui = new GUI();
// gui.add( this.controls, "cpX", -360, 360 ).onChange( function ( v ) {
// that.ms_Camera.position.set(this.object.cpX, this.object.cpY, this.object.cpZ);
// } );
// gui.add( this.controls, "cpY", -360, 360 ).onChange( function ( v ) {
// that.ms_Camera.position.set(this.object.cpX, this.object.cpY, this.object.cpZ);
// } );
// gui.add( this.controls, "cpZ", -360, 360 ).onChange( function ( v ) {
// that.ms_Camera.position.set(this.object.cpX, this.object.cpY, this.object.cpZ);
// } );
// gui.add( this.ms_Ocean, "size", 100, 5000 ).onChange( function ( v ) {
// this.object.size = v;
// this.object.changed = true;
// } );
// gui.add( this.ms_Ocean, "choppiness", 0.1, 4 ).onChange( function ( v ) {
// this.object.choppiness = v;
// this.object.changed = true;
// } );
// gui.add( this.ms_Ocean, "windX", - 15, 15 ).onChange( function ( v ) {
// this.object.windX = v;
// this.object.changed = true;
// } );
// gui.add( this.ms_Ocean, "windY", - 15, 15 ).onChange( function ( v ) {
// this.object.windY = v;
// this.object.changed = true;
// } );
// gui.add( this.ms_Ocean, "sunDirectionX", - 1.0, 1.0 ).onChange( function ( v ) {
// this.object.sunDirectionX = v;
// this.object.changed = true;
// } );
// gui.add( this.ms_Ocean, "sunDirectionY", - 1.0, 1.0 ).onChange( function ( v ) {
// this.object.sunDirectionY = v;
// this.object.changed = true;
// } );
// gui.add( this.ms_Ocean, "sunDirectionZ", - 1.0, 1.0 ).onChange( function ( v ) {
// this.object.sunDirectionZ = v;
// this.object.changed = true;
// } );
// gui.add( this.ms_Ocean, "exposure", 0.0, 0.5 ).onChange( function ( v ) {
// this.object.exposure = v;
// this.object.changed = true;
// } );
},
Display: function () {
this.ms_Renderer.render( this.ms_Scene, this.ms_Camera );
},
Update: function () {
var currentTime = new Date().getTime();
this.ms_Ocean.deltaTime = ( currentTime - lastTime ) / 1000 || 0.0;
lastTime = currentTime;
this.ms_Ocean.render( this.ms_Ocean.deltaTime );
this.ms_Ocean.overrideMaterial = this.ms_Ocean.materialOcean;
if ( this.ms_Ocean.changed ) {
this.ms_Ocean.materialOcean.uniforms[ "u_size" ].value = this.ms_Ocean.size;
this.ms_Ocean.materialOcean.uniforms[ "u_sunDirection" ].value.set( this.ms_Ocean.sunDirectionX, this.ms_Ocean.sunDirectionY, this.ms_Ocean.sunDirectionZ );
this.ms_Ocean.materialOcean.uniforms[ "u_exposure" ].value = this.ms_Ocean.exposure;
this.ms_Ocean.changed = false;
}
this.ms_Ocean.materialOcean.uniforms[ "u_normalMap" ].value = this.ms_Ocean.normalMapFramebuffer.texture;
this.ms_Ocean.materialOcean.uniforms[ "u_displacementMap" ].value = this.ms_Ocean.displacementMapFramebuffer.texture;
this.ms_Ocean.materialOcean.uniforms[ "u_projectionMatrix" ].value = this.ms_Camera.projectionMatrix;
this.ms_Ocean.materialOcean.uniforms[ "u_viewMatrix" ].value = this.ms_Camera.matrixWorldInverse;
this.ms_Ocean.materialOcean.uniforms[ "u_cameraPosition" ].value = this.ms_Camera.position;
this.ms_Ocean.materialOcean.depthTest = true;
this.Display();
},
Resize: function ( inWidth, inHeight ) {
this.ms_Camera.aspect = inWidth / inHeight;
this.ms_Camera.updateProjectionMatrix();
this.ms_Renderer.setSize( inWidth, inHeight );
this.Display();
}
};
DEMO.Initialize();
window.addEventListener( 'resize', function () {
DEMO.Resize( window.innerWidth, window.innerHeight );
} );
DEMO.Resize( window.innerWidth, window.innerHeight );
var render = function () {
requestAnimationFrame( render );
DEMO.Update();
};
render();
</script>
</body>
</html>
できたもの
ヘッダとか背景に使えないかな~というイメージでした。
感想
如何でしたでしょうか?
ちょっと難しいところもありますが、3Dは面白いですね。