Створення неба
Для цього практикуму ми створимо нову сцену: автомобіль, який їздить великою трав'янистою рівниною під зоряним небом. Взято з серії чудових постів блогу Джерома, який також створив будівельник шаблону та tQuery, який як jQuery, але для ThreeJS (оригінальна серія).
Почніть з нового шаблону з BoilerPlate Builder. Тепер давайте додамо небо. Найпростіший спосіб зробити це просто поставити картинки неба на сторонах великого куба. Хитрість полягає в тому, що ми встановимо решту світу всередину куба. Почнемо із завантаження зображень в єдину текстуру куба:
<code data-language="javascript">//додаємо карту зоряного неба //завантажуємо зображення неба var urls=[ "images/sky1.png", "images/sky1.png", "images/sky1.png", "images/sky1.png", "images/sky1.png", "images/sky1.png", ]; var textureCube=THREE.ImageUtils.loadTextureCube(urls);
Зображення sky1.png входить у приклад коду для скачування.
Тепер нам потрібен шейдер куба щоб намалювати його стандартним шляхом. Зверніть увагу, що ми встановлюємо текстуру tCube в нашу текстуру. var uniforms=THREE.UniformsUtils.clone(shader.uniforms); uniforms['tCube'].texture=textureCube; var material=new THREE.ShaderMaterial({ fragmentShader : shader.fragmentShader, vertexShader : shader.vertexShader, uniforms : uniforms });
Тепер нам потрібна геометрія куба. Встановіть розмір 10 000. Це буде великий куб. Тепер додамо його до сцени. Ми встановлюємо flipSided як true, тому що стандартний куб містить текстуру, намальовану на зовнішній стороні. У нашому випадку вона потрібна на внутрішній стороні куба. ///створення неба var size=10000; skyboxMesh=new THREE.Mesh( new THREE.CubeGeometry(size,size,size),material); //ВАЖЛИВО!! малювати всередині, а не зовні skyboxMesh.flipSided=true; //у вас має бути це, інакше нічого не побачите scene.add(skyboxMesh);
Тепер додамо світло від сонця. Без світла ми взагалі нічого не побачимо.
<code data-language="javascript">//додаємо світло var light=new light.position.set(0,500,0); scene.add(light);
Ось що у нас є на даний момент:
Додаємо площину землі
Тепер нам потрібна площина землі. Насамперед, необхідно завантажити зображення трави (оригінал) як текстуру. Зображення трави також включено як приклад коду. Встановіть повторення у напрямках x та у. Значення повторення повинні бути такими ж, як і розмір текстури, і, як правило, повинні бути ступенем двійки (наприклад: 256).=THREE.ImageUtils.loadTexture('images/grass.png'); grassTex.wrapS=THREE.RepeatWrapping; grassTex.wrapT=THREE.RepeatWrapping; grassTex.repeat.x=256; grassTex.repeat.y=256; var groundMat=new THREE.MeshBasicMaterial({map:grassTex});
Далі йде геометрія. Це просто велика площина у просторі. Розмір площини 400х400, який є досить великим у порівнянні з камерою, але дуже малий у порівнянні з розміром неба, який заданий як 10000. PlaneGeometry(400,400);
Тепер ми можемо об'єднати їх у сітку. Встановіть position.y в-1.9, щоб площина була нижчою за тор. Встановіть rotation.x в 90 градусів, щоб земля стала горизонтальною (площина вертикальна за замовчуванням). Якщо ви не бачите площину, спробуйте встановити doubleSided у true. Площини за замовчуванням малюються лише на одній стороні.
<code data-language="javascript">var ground=new THREE. ground.position.y=-1.9; //опускаємо ground.rotation.x=-Math.PI/2; //-90 градусів навколо осі x //ВАЖЛИВО, малюємо по обидва боки ground.doubleSided=true; scene.add(ground);
Ось як це має зараз виглядати:
Додаємо модель автомобіля
Щоб замінити тор автомобілем ми завантажимо зовнішню модель, у нашому випадку добре деталізовану модель Bugatti Veyron, створену Troyano. Я взяв її зі сховища прикладів ThreeJS. Оскільки модель зберігається у двійковому форматі, а не JSON, ми завантажимо її за допомогою THREE.BinaryLoader.
<code data-language="javascript">//завантажуємо автомобіль //ВАЖЛИВО: обов'язково використовуйте ./або .bin не зможе правильно завантажитися new THREE.BinaryLoader().load('./VeyronNoUv_bin.js', function(geometry) : 0x995500, opacity: 1.0, transparent: false }), var mesh=new THREE.Mesh( geometry, orange); mesh);car=mesh;});
Зверніть увагу, що використовується MeshLambertMaterial замість MeshNormalMaterial, який був раніше. Це дасть автомобілю гарний суцільний колір (помаранчевий, в даному випадку) та правильні тіні під світлом. Ця сітка є величезною за умовчанням порівняно з тором, так що масштабуємо до 5%, а потім додаємо в сцену. Ось як це виглядає в даний час:
>
Керування з клавіатури
Звичайно, просто стоїть машина це не весело. І надто далеко. Примусимо її рухатися. На даний момент об'єкт cameraControl переміщує камеру навколо. Видаліть її та створіть новий об'єкт KeyboardState, де ініціалізується об'єкт cameraControl. Вам потрібно буде імпортувати vendor/threex/THREEx.KeyboardState.js у верхню частину сторінки.
<script src="vendor/threex/THREEx.KeyboardState. js"></script>
<code data-language="javascript">//створюємо керування камерою //cameraControls=new THREEx .DragPanControls(camera) keyboard=new THREEx.KeyboardState();
Тепер опустимося до функції render(). Об'єкт keyboard дозволяє нам запитувати поточний стан клавіатури. Для пересування автомобіля за допомогою клавіатури замініть cameraControls.update() цим кодом:
<code data-language="javascript">//оновлюємо керування камерою //cameraControls.update(); if(keyboard.pressed("left")) { car.rotation.y +=0.1; } if(keyboard.pressed("right")) { car.rotation.y-=0.1; } if(keyboard.pressed("up")) { car.position.z-=1.0; } if(keyboard.pressed("down")) { car.position.z +=1.0; }
Тепер на автомобілі «можна їхати» за допомогою клавіатури. Звісно, це не дуже реалістично. Автомобіль може ковзати боком. Щоб виправити це, ми маємо представити поточний напрямок автомобіля. Додати змінну angle і змінити код на наступний:
<code data-language="javascript">if(keyboard.pressed("left")) {car.rotation.y+=0.1; angle +=0.1; } if(keyboard.pressed("right")) { car.rotation.y-=0.1; angle-=0.1; } if(keyboard.pressed("up")) { car.position.z-=Math.sin(-angle); car.position.x-=Math.cos(-angle); } if(keyboard.pressed("down")) { car.position.z +=Math.sin(-angle); car.position.x +=Math.cos(-angle); }
Наступні кроки
Ось і весь практикум. Якщо ви хочете продовжити працювати з цим прикладом, ось кілька речей, які ви, можливо, захочете додати.
- Зробити камери, що слідують за автомобілем.
- Зробити автомобіль блискучим.
- Подивіться на оригінальний приклад, на якому ми базувалися.
- Зробіть зупинку автомобіля, коли досягається край світу.
- Додайте в сцену ефект точок екрана з попереднього розділу.
Ви можете переглянути фінальну версію тут.