|
@@ -34,6 +34,7 @@
|
|
|
|
|
|
<script src="js/controls/OrbitControls.js"></script>
|
|
|
<script src="js/objects/Water.js"></script>
|
|
|
+ <script src="js/objects/Sky.js"></script>
|
|
|
|
|
|
<script src="js/Detector.js"></script>
|
|
|
<script src="js/libs/stats.min.js"></script>
|
|
@@ -45,14 +46,7 @@
|
|
|
|
|
|
var container, stats;
|
|
|
var camera, scene, renderer, light;
|
|
|
- var controls, water, sphere, cubeMap;
|
|
|
-
|
|
|
- var parameters = {
|
|
|
- oceanSide: 2000,
|
|
|
- size: 1.0,
|
|
|
- distortionScale: 3.7,
|
|
|
- alpha: 1.0
|
|
|
- };
|
|
|
+ var controls, water, sphere;
|
|
|
|
|
|
init();
|
|
|
animate();
|
|
@@ -66,13 +60,11 @@
|
|
|
renderer = new THREE.WebGLRenderer();
|
|
|
renderer.setPixelRatio( window.devicePixelRatio );
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
- renderer.shadowMap.enabled = true;
|
|
|
container.appendChild( renderer.domElement );
|
|
|
|
|
|
//
|
|
|
|
|
|
scene = new THREE.Scene();
|
|
|
- scene.fog = new THREE.FogExp2( 0xaabbbb, 0.001 );
|
|
|
|
|
|
//
|
|
|
|
|
@@ -82,29 +74,77 @@
|
|
|
//
|
|
|
|
|
|
light = new THREE.DirectionalLight( 0xffffff, 0.8 );
|
|
|
- light.position.set( - 30, 30, 30 );
|
|
|
- light.castShadow = true;
|
|
|
- light.shadow.camera.top = 45;
|
|
|
- light.shadow.camera.right = 40;
|
|
|
- light.shadow.camera.left = light.shadow.camera.bottom = -40;
|
|
|
- light.shadow.camera.near = 1;
|
|
|
- light.shadow.camera.far = 200;
|
|
|
scene.add( light );
|
|
|
|
|
|
- var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
|
|
|
- scene.add( ambientLight );
|
|
|
+ // Water
|
|
|
|
|
|
- //
|
|
|
+ var waterGeometry = new THREE.PlaneBufferGeometry( 10000, 10000 );
|
|
|
|
|
|
- setWater();
|
|
|
+ water = new THREE.Water(
|
|
|
+ waterGeometry,
|
|
|
+ {
|
|
|
+ textureWidth: 512,
|
|
|
+ textureHeight: 512,
|
|
|
+ waterNormals: new THREE.TextureLoader().load( 'textures/waternormals.jpg', function ( texture ) {
|
|
|
+ texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
|
|
|
+ }),
|
|
|
+ alpha: 1.0,
|
|
|
+ sunDirection: light.position.clone().normalize(),
|
|
|
+ sunColor: 0xffffff,
|
|
|
+ waterColor: 0x001e0f,
|
|
|
+ distortionScale: 3.7,
|
|
|
+ fog: scene.fog !== undefined
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
- //
|
|
|
+ water.rotation.x = - Math.PI / 2;
|
|
|
|
|
|
- setSkybox();
|
|
|
+ scene.add( water );
|
|
|
+
|
|
|
+ // Skybox
|
|
|
+
|
|
|
+ var sky = new THREE.Sky();
|
|
|
+ sky.scale.setScalar( 10000 );
|
|
|
+ scene.add( sky );
|
|
|
+
|
|
|
+ var uniforms = sky.material.uniforms;
|
|
|
+
|
|
|
+ uniforms.turbidity.value = 10;
|
|
|
+ uniforms.rayleigh.value = 2;
|
|
|
+ uniforms.luminance.value = 1;
|
|
|
+ uniforms.mieCoefficient.value = 0.005;
|
|
|
+ uniforms.mieDirectionalG.value = 0.8;
|
|
|
+
|
|
|
+ var parameters = {
|
|
|
+ distance: 400,
|
|
|
+ inclination: 0.49,
|
|
|
+ azimuth: 0.2
|
|
|
+ };
|
|
|
+
|
|
|
+ var cubeCamera = new THREE.CubeCamera( 1, 20000, 256 );
|
|
|
+ cubeCamera.renderTarget.texture.minFilter = THREE.LinearMipMapLinearFilter;
|
|
|
+
|
|
|
+ function updateSun() {
|
|
|
+
|
|
|
+ var theta = Math.PI * ( parameters.inclination - 0.5 );
|
|
|
+ var phi = 2 * Math.PI * ( parameters.azimuth - 0.5 );
|
|
|
+
|
|
|
+ light.position.x = parameters.distance * Math.cos( phi );
|
|
|
+ light.position.y = parameters.distance * Math.sin( phi ) * Math.sin( theta );
|
|
|
+ light.position.z = parameters.distance * Math.sin( phi ) * Math.cos( theta );
|
|
|
+
|
|
|
+ sky.material.uniforms.sunPosition.value = light.position.copy( light.position );
|
|
|
+ water.material.uniforms.sunDirection.value.copy( light.position ).normalize();
|
|
|
+
|
|
|
+ cubeCamera.update( renderer, scene );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ updateSun();
|
|
|
|
|
|
//
|
|
|
|
|
|
- var geometry = new THREE.IcosahedronGeometry( 20, 2 );
|
|
|
+ var geometry = new THREE.IcosahedronGeometry( 20, 1 );
|
|
|
|
|
|
for ( var i = 0, j = geometry.faces.length; i < j; i ++ ) {
|
|
|
|
|
@@ -112,15 +152,15 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
- var material = new THREE.MeshPhongMaterial( {
|
|
|
+ var material = new THREE.MeshStandardMaterial( {
|
|
|
vertexColors: THREE.FaceColors,
|
|
|
- shininess: 10,
|
|
|
- envMap: cubeMap,
|
|
|
+ roughness: 0.0,
|
|
|
+ flatShading: true,
|
|
|
+ envMap: cubeCamera.renderTarget.texture,
|
|
|
side: THREE.DoubleSide
|
|
|
} );
|
|
|
|
|
|
sphere = new THREE.Mesh( geometry, material );
|
|
|
- sphere.castShadow = true;
|
|
|
scene.add( sphere );
|
|
|
|
|
|
//
|
|
@@ -138,77 +178,28 @@
|
|
|
stats = new Stats();
|
|
|
container.appendChild( stats.dom );
|
|
|
|
|
|
- //
|
|
|
+ // GUI
|
|
|
|
|
|
var gui = new dat.GUI();
|
|
|
|
|
|
- gui.add( parameters, 'distortionScale', 0, 8, 0.1 );
|
|
|
- gui.add( parameters, 'size', 0.1, 10, 0.1 );
|
|
|
- gui.add( parameters, 'alpha', 0.9, 1, .001 );
|
|
|
+ var uniforms = sky.material.uniforms;
|
|
|
|
|
|
- //
|
|
|
+ var folder = gui.addFolder( 'Sky' );
|
|
|
+ folder.add( parameters, 'inclination', 0, 1, 0.0001 ).onChange( updateSun );
|
|
|
+ folder.add( parameters, 'azimuth', 0, 1, 0.0001 ).onChange( updateSun );
|
|
|
+ folder.open();
|
|
|
|
|
|
- window.addEventListener( 'resize', onWindowResize, false );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function setWater() {
|
|
|
-
|
|
|
- var waterGeometry = new THREE.PlaneBufferGeometry( parameters.oceanSide * 5, parameters.oceanSide * 5 );
|
|
|
-
|
|
|
- water = new THREE.Water(
|
|
|
- waterGeometry,
|
|
|
- {
|
|
|
- textureWidth: 512,
|
|
|
- textureHeight: 512,
|
|
|
- waterNormals: new THREE.TextureLoader().load( 'textures/waternormals.jpg', function ( texture ) {
|
|
|
- texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
|
|
|
- }),
|
|
|
- alpha: parameters.alpha,
|
|
|
- sunDirection: light.position.clone().normalize(),
|
|
|
- sunColor: 0xffffff,
|
|
|
- waterColor: 0x001e0f,
|
|
|
- distortionScale: parameters.distortionScale,
|
|
|
- fog: scene.fog !== undefined
|
|
|
- }
|
|
|
- );
|
|
|
-
|
|
|
- water.rotation.x = - Math.PI / 2;
|
|
|
- water.receiveShadow = true;
|
|
|
-
|
|
|
- scene.add( water );
|
|
|
-
|
|
|
- }
|
|
|
+ var uniforms = water.material.uniforms;
|
|
|
|
|
|
- function setSkybox() {
|
|
|
+ var folder = gui.addFolder( 'Water' );
|
|
|
+ folder.add( uniforms.distortionScale, 'value', 0, 8, 0.1 ).name( 'distortionScale' );
|
|
|
+ folder.add( uniforms.size, 'value', 0.1, 10, 0.1 ).name( 'size' );
|
|
|
+ folder.add( uniforms.alpha, 'value', 0.9, 1, .001 ).name( 'alpha' );
|
|
|
+ folder.open();
|
|
|
|
|
|
- var cubeTextureLoader = new THREE.CubeTextureLoader();
|
|
|
- cubeTextureLoader.setPath( 'textures/cube/skyboxsun25deg/' );
|
|
|
-
|
|
|
- cubeMap = cubeTextureLoader.load( [
|
|
|
- 'px.jpg', 'nx.jpg',
|
|
|
- 'py.jpg', 'ny.jpg',
|
|
|
- 'pz.jpg', 'nz.jpg',
|
|
|
- ] );
|
|
|
-
|
|
|
- var cubeShader = THREE.ShaderLib[ 'cube' ];
|
|
|
- cubeShader.uniforms[ 'tCube' ].value = cubeMap;
|
|
|
-
|
|
|
- var skyBoxMaterial = new THREE.ShaderMaterial( {
|
|
|
- fragmentShader: cubeShader.fragmentShader,
|
|
|
- vertexShader: cubeShader.vertexShader,
|
|
|
- uniforms: cubeShader.uniforms,
|
|
|
- side: THREE.BackSide
|
|
|
- } );
|
|
|
-
|
|
|
- var skyBoxGeometry = new THREE.BoxBufferGeometry(
|
|
|
- parameters.oceanSide * 5 + 100,
|
|
|
- parameters.oceanSide * 5 + 100,
|
|
|
- parameters.oceanSide * 5 + 100 );
|
|
|
-
|
|
|
- var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial );
|
|
|
+ //
|
|
|
|
|
|
- scene.add( skyBox );
|
|
|
+ window.addEventListener( 'resize', onWindowResize, false );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -238,9 +229,6 @@
|
|
|
sphere.rotation.z = time * 0.51;
|
|
|
|
|
|
water.material.uniforms.time.value += 1.0 / 60.0;
|
|
|
- water.material.uniforms.size.value = parameters.size;
|
|
|
- water.material.uniforms.distortionScale.value = parameters.distortionScale;
|
|
|
- water.material.uniforms.alpha.value = parameters.alpha;
|
|
|
|
|
|
renderer.render( scene, camera );
|
|
|
|