"use strict"; // 參考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode //////////////////////////////////////////////////////////////////////////////// // 透明喝水鳥作業:使喝水鳥身體變得透明 //////////////////////////////////////////////////////////////////////////////// var camera, scene, renderer; var cameraControls; var clock = new THREE.Clock(); function fillScene() { scene = new THREE.Scene(); scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); // 光源 scene.add( new THREE.AmbientLight( 0x222222 ) ); var light = new THREE.DirectionalLight( 0xFFFFFF, 0.7 ); light.position.set( 200, 500, 500 ); scene.add( light ); light = new THREE.DirectionalLight( 0xFFFFFF, 0.9 ); light.position.set( -200, -100, -400 ); scene.add( light ); Coordinates.drawGround({size:1000}); drawDrinkingBird(); } function drawDrinkingBird() { // 材質 var headMaterial = new THREE.MeshLambertMaterial( ); headMaterial.color.r = 104/255; headMaterial.color.g = 1/255; headMaterial.color.b = 5/255; var hatMaterial = new THREE.MeshPhongMaterial( { shininess: 100 } ); hatMaterial.color.r = 24/255; hatMaterial.color.g = 38/255; hatMaterial.color.b = 77/255; hatMaterial.specular.setRGB( 0.5, 0.5, 0.5 ); var bodyMaterial = new THREE.MeshPhongMaterial( { shininess: 100 } ); bodyMaterial.color.setRGB( 31/255, 86/255, 169/255 ); bodyMaterial.specular.setRGB( 0.5, 0.5, 0.5 ); // 修改這個使其變透明: var glassMaterial = new THREE.MeshPhongMaterial( { color: 0xFFFFFF, shininess: 100 } ); var legMaterial = new THREE.MeshPhongMaterial( { shininess: 4 } ); legMaterial.color.setHex( 0xAdA79b ); legMaterial.specular.setRGB( 0.5, 0.5, 0.5 ); var footMaterial = new THREE.MeshPhongMaterial( { color: 0x960f0b, shininess: 30 } ); footMaterial.specular.setRGB( 0.5, 0.5, 0.5 ); var sphere, cylinder, cube; var bevelRadius = 1.9; // TODO: 2.0 causes some geometry bug. // 建模 // 基底 cube = new THREE.Mesh( new THREE.BeveledBlockGeometry( 20+64+110, 4, 2*77+12, bevelRadius ), footMaterial ); cube.position.x = -45; // (20+32) - 寬度的一半 (20+64+110)/2 cube.position.y = 4/2; // 高的的一半 cube.position.z = 0; // 中心在原點 scene.add( cube ); // 腳掌 cube = new THREE.Mesh( new THREE.BeveledBlockGeometry( 20+64+110, 52, 6, bevelRadius ), footMaterial ); cube.position.x = -45; // (20+32) - 寬度的一半 (20+64+110)/2 cube.position.y = 52/2; // 高的的一半 cube.position.z = 77 + 6/2; // 偏移 77 + 深度的一半 6/2 scene.add( cube ); cube = new THREE.Mesh( new THREE.BeveledBlockGeometry( 20+64+110, 52, 6, bevelRadius ), footMaterial ); cube.position.x = -45; // (20+32) - 寬度的一半 (20+64+110)/2 cube.position.y = 52/2; // 高的的一半 cube.position.z = -(77 + 6/2); // 負的偏移 77 + 深度的一半 6/2 scene.add( cube ); cube = new THREE.Mesh( new THREE.BeveledBlockGeometry( 64, 104, 6, bevelRadius ), footMaterial ); cube.position.x = 0; // X 方向在原點 cube.position.y = 104/2; cube.position.z = 77 + 6/2; // 負的偏移 77 + 深度的一半 6/2 scene.add( cube ); cube = new THREE.Mesh( new THREE.BeveledBlockGeometry( 64, 104, 6, bevelRadius ), footMaterial ); cube.position.x = 0; // X 方向在原點 cube.position.y = 104/2; cube.position.z = -(77 + 6/2); // 負的偏移 77 + 深度的一半 6/2 scene.add( cube ); // 腳 cube = new THREE.Mesh( new THREE.BeveledBlockGeometry( 60, 282+4, 4, bevelRadius ), legMaterial ); cube.position.x = 0; // X 方向在原點 cube.position.y = 104 + 282/2 - 2; cube.position.z = 77 + 6/2; // 負的偏移 77 + 深度的一半 6/2 scene.add( cube ); cube = new THREE.Mesh( new THREE.BeveledBlockGeometry( 60, 282+4, 4, bevelRadius ), legMaterial ); cube.position.x = 0; // X 方向在原點 cube.position.y = 104 + 282/2 - 2; cube.position.z = -(77 + 6/2); // 負的偏移 77 + 深度的一半 6/2 scene.add( cube ); // 身體 sphere = new THREE.Mesh( new THREE.SphereGeometry( 104/2, 32, 16, 0, Math.PI * 2, Math.PI/2, Math.PI ), bodyMaterial ); sphere.position.x = 0; sphere.position.y = 160; sphere.position.z = 0; scene.add( sphere ); // 半球的上蓋 cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 104/2, 104/2, 0, 32 ), bodyMaterial ); cylinder.position.x = 0; cylinder.position.y = 160; cylinder.position.z = 0; scene.add( cylinder ); cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 12/2, 12/2, 390 - 100, 32 ), bodyMaterial ); cylinder.position.x = 0; cylinder.position.y = 160 + 390/2 - 100; cylinder.position.z = 0; scene.add( cylinder ); // 玻璃 sphere = new THREE.Mesh( new THREE.SphereGeometry( 116/2, 32, 16 ), glassMaterial ); sphere.position.x = 0; sphere.position.y = 160; sphere.position.z = 0; scene.add( sphere ); cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 24/2, 24/2, 390, 32 ), glassMaterial ); cylinder.position.x = 0; cylinder.position.y = 160 + 390/2; cylinder.position.z = 0; scene.add( cylinder ); // 頭 sphere = new THREE.Mesh( new THREE.SphereGeometry( 104/2, 32, 16 ), headMaterial ); sphere.position.x = 0; sphere.position.y = 160 + 390; sphere.position.z = 0; scene.add( sphere ); // 帽子 cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 142/2, 142/2, 10, 32 ), hatMaterial ); cylinder.position.x = 0; cylinder.position.y = 160 + 390 + 40 + 10/2; cylinder.position.z = 0; scene.add( cylinder ); cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 80/2, 80/2, 70, 32 ), hatMaterial ); cylinder.position.x = 0; cylinder.position.y = 160 + 390 + 40 + 10 + 70/2; cylinder.position.z = 0; scene.add( cylinder ); } function init() { var canvasWidth = window.innerWidth; var canvasHeight = window.innerHeight; var canvasRatio = canvasWidth / canvasHeight; // RENDERER renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.gammaInput = true; renderer.gammaOutput = true; renderer.setSize(canvasWidth, canvasHeight); renderer.setClearColorHex( 0xAAAAAA, 1.0 ); // 攝影機 camera = new THREE.PerspectiveCamera( 45, canvasRatio, 1, 4000 ); // 控制 cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); camera.position.set( -417, 367, -234); cameraControls.target.set(4,301,92); } function addToDOM() { var container = document.getElementById('container'); var canvas = container.getElementsByTagName('canvas'); if (canvas.length>0) { container.removeChild(canvas[0]); } container.appendChild( renderer.domElement ); } function animate() { window.requestAnimationFrame(animate); render(); } function render() { var delta = clock.getDelta(); cameraControls.update(delta); renderer.render(scene, camera); } document.addEventListener("DOMContentLoaded", function () { try { init(); fillScene(); addToDOM(); animate(); } catch(e) { var errorReport = "你的程式遇到不可復原的錯誤,無法繪製 Canvas。錯誤是:<br/><br/>"; $('#container').append(errorReport+e); } })