You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							195 lines
						
					
					
						
							5.4 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							195 lines
						
					
					
						
							5.4 KiB
						
					
					
				
								<!-- Licensed under a BSD license. See license.html for license -->
							 | 
						|
								<!DOCTYPE html>
							 | 
						|
								<html>
							 | 
						|
								  <head>
							 | 
						|
								    <meta charset="utf-8">
							 | 
						|
								    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
							 | 
						|
								    <title>Three.js - Fundamentals</title>
							 | 
						|
								    <link href="resources/threejs-tutorials.css" rel="stylesheet" />
							 | 
						|
								    <style>
							 | 
						|
								    html, body {
							 | 
						|
								      margin: 0;
							 | 
						|
								      height: 100%;
							 | 
						|
								    }
							 | 
						|
								    canvas {
							 | 
						|
								      width: 100%;
							 | 
						|
								      height: 100%;
							 | 
						|
								      display: block;
							 | 
						|
								    }
							 | 
						|
								    </style>
							 | 
						|
								  </head>
							 | 
						|
								  <body>
							 | 
						|
								    <canvas id="c"></canvas>
							 | 
						|
								  </body>
							 | 
						|
								<!-- Import maps polyfill -->
							 | 
						|
								<!-- Remove this when import maps will be widely supported -->
							 | 
						|
								<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
							 | 
						|
								
							 | 
						|
								<script type="importmap">
							 | 
						|
								{
							 | 
						|
								  "imports": {
							 | 
						|
								    "three": "../../build/three.module.js",
							 | 
						|
								    "three/addons/": "../../examples/jsm/"
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								</script>
							 | 
						|
								
							 | 
						|
								<script type="module">
							 | 
						|
								import * as THREE from 'three';
							 | 
						|
								import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
							 | 
						|
								import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
							 | 
						|
								
							 | 
						|
								function main() {
							 | 
						|
								  const canvas = document.querySelector('#c');
							 | 
						|
								  const renderer = new THREE.WebGLRenderer({canvas});
							 | 
						|
								  const scene = new THREE.Scene();
							 | 
						|
								
							 | 
						|
								  const aspect = 2;  // the canvas default
							 | 
						|
								  const fov = 35;
							 | 
						|
								  const near = 0.1;
							 | 
						|
								  const far = 5000;
							 | 
						|
								  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
							 | 
						|
								  camera.position.x = -0.;
							 | 
						|
								  camera.position.y = 350;
							 | 
						|
								  camera.position.z = 40.;
							 | 
						|
								
							 | 
						|
								  const useFog = true;
							 | 
						|
								  const useOrbitCamera = false;
							 | 
						|
								  const showHelpers = false;
							 | 
						|
								  const camSpeed = 0.2;
							 | 
						|
								
							 | 
						|
								  if (useOrbitCamera) {
							 | 
						|
								    const controls = new OrbitControls(camera, canvas);
							 | 
						|
								    controls.target.set(0, 100.01, 0.2);
							 | 
						|
								    controls.update();
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  renderer.outputEncoding = THREE.sRGBEncoding;
							 | 
						|
								  renderer.shadowMap.enabled = true;
							 | 
						|
								
							 | 
						|
								  const hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
							 | 
						|
								  hemiLight.color.setHSL(0.6, 1, 0.6);
							 | 
						|
								  hemiLight.groundColor.setHSL(0.095, 1, 0.75);
							 | 
						|
								  hemiLight.position.set(0, 50, 0);
							 | 
						|
								  scene.add(hemiLight);
							 | 
						|
								
							 | 
						|
								  if (showHelpers) {
							 | 
						|
								    const hemiLightHelper = new THREE.HemisphereLightHelper(hemiLight, 10);
							 | 
						|
								    scene.add(hemiLightHelper);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  const dirLight = new THREE.DirectionalLight(0xffffff, 1);
							 | 
						|
								  dirLight.color.setHSL(0.1, 1, 0.95);
							 | 
						|
								  dirLight.position.set(-300, 220, 245);
							 | 
						|
								  scene.add(dirLight);
							 | 
						|
								  dirLight.castShadow = true;
							 | 
						|
								  dirLight.shadow.mapSize.width = 2048;
							 | 
						|
								  dirLight.shadow.mapSize.height = 2048;
							 | 
						|
								  const d = 350;
							 | 
						|
								  dirLight.shadow.camera.left = -d;
							 | 
						|
								  dirLight.shadow.camera.right = d;
							 | 
						|
								  dirLight.shadow.camera.top = d;
							 | 
						|
								  dirLight.shadow.camera.bottom = -d;
							 | 
						|
								  dirLight.shadow.camera.near = 100;
							 | 
						|
								  dirLight.shadow.camera.far = 950;
							 | 
						|
								  dirLight.shadow.bias = -0.005;
							 | 
						|
								
							 | 
						|
								  if (showHelpers) {
							 | 
						|
								    const dirLightHeper = new THREE.DirectionalLightHelper(dirLight, 10);
							 | 
						|
								    scene.add(dirLightHeper);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  const loader = new GLTFLoader();
							 | 
						|
								  const camRadius = 600;
							 | 
						|
								  const camHeight = 160;
							 | 
						|
								  const camTarget = [0, 30, 0];
							 | 
						|
								  const fogNear = 1350;
							 | 
						|
								  const fogFar = 1500;
							 | 
						|
								  loader.load('resources/models/mountain_landscape/scene.gltf', (gltf) => {
							 | 
						|
								    gltf.scene.traverse((child) => {
							 | 
						|
								      if ( child.isMesh ) {
							 | 
						|
								        child.castShadow = true;
							 | 
						|
								        child.receiveShadow = true;
							 | 
						|
								      }
							 | 
						|
								    });
							 | 
						|
								    scene.add(gltf.scene);
							 | 
						|
								  });
							 | 
						|
								
							 | 
						|
								  window.s = scene;
							 | 
						|
								
							 | 
						|
								  if (useFog) {
							 | 
						|
								    const vertexShader = `
							 | 
						|
								    varying vec3 vWorldPosition;
							 | 
						|
								    void main() {
							 | 
						|
								      vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
							 | 
						|
								      vWorldPosition = worldPosition.xyz;
							 | 
						|
								      gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
							 | 
						|
								    }
							 | 
						|
								    `;
							 | 
						|
								
							 | 
						|
								    const fragmentShader = `
							 | 
						|
								    uniform vec3 topColor;
							 | 
						|
								    uniform vec3 bottomColor;
							 | 
						|
								    uniform float offset;
							 | 
						|
								    uniform float exponent;
							 | 
						|
								    varying vec3 vWorldPosition;
							 | 
						|
								    void main() {
							 | 
						|
								      float h = normalize( vWorldPosition + offset ).y;
							 | 
						|
								      gl_FragColor = vec4( mix( bottomColor, topColor, max( pow( max( h , 0.0), exponent ), 0.0 ) ), 1.0 );
							 | 
						|
								    }
							 | 
						|
								    `;
							 | 
						|
								
							 | 
						|
								    const uniforms = {
							 | 
						|
								      topColor:    { value: new THREE.Color(0x88AABB) },
							 | 
						|
								      bottomColor: { value: new THREE.Color(0xEFCB7F) },
							 | 
						|
								      offset:      { value: 730 },
							 | 
						|
								      exponent:    { value: 0.3 },
							 | 
						|
								    };
							 | 
						|
								    uniforms.topColor.value.copy(hemiLight.color);
							 | 
						|
								    scene.fog = new THREE.Fog(scene.background, fogNear, fogFar);
							 | 
						|
								    scene.fog.color.copy(uniforms.bottomColor.value);
							 | 
						|
								    const skyGeo = new THREE.SphereGeometry(4000, 32, 15);
							 | 
						|
								    const skyMat = new THREE.ShaderMaterial( { vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide } );
							 | 
						|
								    const sky = new THREE.Mesh( skyGeo, skyMat );
							 | 
						|
								    scene.add(sky);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  function resizeRendererToDisplaySize(renderer) {
							 | 
						|
								    const canvas = renderer.domElement;
							 | 
						|
								    const width = canvas.clientWidth;
							 | 
						|
								    const height = canvas.clientHeight;
							 | 
						|
								    if (width === canvas.width && height === canvas.height) {
							 | 
						|
								      return false;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    renderer.setSize(width, height, false);
							 | 
						|
								    return true;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  function render(time) {
							 | 
						|
								    time *= 0.001;
							 | 
						|
								    time += 80;
							 | 
						|
								
							 | 
						|
								    if (resizeRendererToDisplaySize(renderer)) {
							 | 
						|
								      camera.aspect = canvas.clientWidth / canvas.clientHeight;
							 | 
						|
								      camera.updateProjectionMatrix();
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if (!useOrbitCamera) {
							 | 
						|
								      const angle = Math.sin(time * camSpeed) + Math.PI * .75;
							 | 
						|
								      camera.position.set(Math.cos(angle) * camRadius, camHeight, Math.sin(angle) * camRadius);
							 | 
						|
								      camera.lookAt(...camTarget);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    renderer.render(scene, camera);
							 | 
						|
								
							 | 
						|
								    requestAnimationFrame(render);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  requestAnimationFrame(render);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								main();
							 | 
						|
								</script>
							 | 
						|
								</html>
							 | 
						|
								
							 | 
						|
								
							 |