#javascript #three.js
#javascript #three.js
Вопрос:
Я настраиваю средство просмотра 3D-ресурсов в Three.js. Я запускаю код на сервере Plesk, предоставленном университетом, и связываю его через Dreamweaver. Я абсолютный новичок в JS, и во многих темах и публикациях предлагалось, чтобы я заключал свой код в 'init();'
функцию. После этого и устранения всех ошибок, которые были в коде, теперь отображается черный экран, а не 3D-модель, которую он показывал бы раньше.
Я потратил целый день на проверку ошибок, устраняя проблемы, которые у меня возникали, которые включали в себя ‘canvas’, не созданный внутри 'container'
div, и 'onWindowResize'
функцию. Все эти проблемы были решены, и, по-видимому, ошибок в коде нет. У меня есть окружающее освещение в коде, и там был рабочий скайбокс, так что я уверен, что это не проблема с положением камеры или отсутствием освещения.
Я знаю, что вам нужно как можно меньше кода, но я понятия не имею, откуда берется проблема, поэтому большая часть кода на странице находится здесь :
<div id="container" ></div>
<script>
let container;
let camera;
let controls;
let scene;
let renderer;
init();
animate;
function init(){
// Renderer - WebGL is primary Renderer for Three.JS
var renderer = new THREE.WebGLRenderer({antialias : true});
renderer.setClearColor(0xEEEEEE, 0.5);
// Selects and applies parameters to the 'Container' div
var container = document.querySelector("#container");
container.appendChild(renderer.domElement);
renderer.setSize(container.clientWidth, container.clientHeight);
// Perspective Camera (FOV, aspect ratio based on container, near, far)
var camera = new THREE.PerspectiveCamera( 75, container.clientWidth / container.clientHeight, 0.1, 1000);
camera.position.x = 750;
camera.position.y = 500;
camera.position.z = 1250;
// Scene will contain all objects in the world
var scene = new THREE.Scene();
//Lighting (Colour, intensity)
var light1Ambient = new THREE.AmbientLight(0xffffff , 0.3);
scene.add(light1Ambient);
var light1Point = new THREE.PointLight(0xfff2c1, 0.5, 0, 2);
scene.add(light1Point);
var light2Point = new THREE.PointLight(0xd6e3ff, 0.4, 0, 2);
scene.add(light2Point);
// All basic Geomety
var newPlane = new THREE.PlaneGeometry(250,250,100,100);
const mesh = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshBasicMaterial( {color: 0x00ff00} )
);
scene.add(mesh);
// Water
water = new THREE.Water(newPlane,
{
textureWidth: 512,
textureHeight: 512,
waterNormals: new THREE.TextureLoader().load( 'http://up826703.ct.port.ac.uk/CTPRO/textures/waternormals.jpg', function ( texture ) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
} ),
alpha: 1.0,
sunDirection: light1Point.position.clone().normalize(),
sunColor: 0xffffff,
waterColor: 0x001e0f,
distortionScale: 0.5,
fog: scene.fog !== undefined
}
);
water.rotation.x = - Math.PI / 2;
scene.add( water );
// All Materials (Normal for Debugging) (Lambert: color)
var material = new THREE.MeshLambertMaterial({color: 0xF3FFE2});
var materialNew = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
// Skybox
var skybox = new THREE.BoxGeometry(1000,1000, 1000);
var skyboxMaterials =
[
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("http://up826703.ct.port.ac.uk/CTPRO/skybox/blue/bluecloud_ft.jpg"), side: THREE.DoubleSide }),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("http://up826703.ct.port.ac.uk/CTPRO/skybox/blue/bluecloud_bk.jpg"), side: THREE.DoubleSide }),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("http://up826703.ct.port.ac.uk/CTPRO/skybox/blue/bluecloud_up.jpg"), side: THREE.DoubleSide }),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("http://up826703.ct.port.ac.uk/CTPRO/skybox/blue/bluecloud_dn.jpg"), side: THREE.DoubleSide }),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("http://up826703.ct.port.ac.uk/CTPRO/skybox/blue/bluecloud_rt.jpg"), side: THREE.DoubleSide }),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("http://up826703.ct.port.ac.uk/CTPRO/skybox/blue/bluecloud_lf.jpg"), side: THREE.DoubleSide }),
];
var skyboxMaterial = new THREE.MeshFaceMaterial(skyboxMaterials);
var skyMesh = new THREE.Mesh (skybox, skyboxMaterial);
scene.add(skyMesh);
//Grid Helper Beneath Ship
scene.add(new THREE.GridHelper(250, 250));
//OBJ Model Loading
var objLoader = new THREE.OBJLoader();
objLoader.load('http://up826703.ct.port.ac.uk/CTPRO/models/ship1.obj', function(object){
scene.add(object);
});
// Object positioning
water.position.y = -2.5;
// Misc Positioning
light1Point.position.z =20;
light1Point.position.x = 25;
// z - front-back position
light2Point.position.z = -400;
// x - left-right
light2Point.position.x = -25;
// y - up- down
light2Point.position.y = 250;
window.addEventListener("resize", onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(container.clientWidth, container.clientHeight);
};
};
// Canvas adapts size based on changing windows size
//Render loop
var animate = function(){
water.material.uniforms[ "time" ].value = 1.0 / 120.0;
function drawFrame(ts){
var center = new THREE.Vector2(0,0);
window.requestAnimationFrame(drawFrame);
var vLength = newPlane.geometry.vertices.length;
for (var i = 0; i < vLength; i ) {
var v = newPlane.geometry.vertices[i];
var dist = new THREE.Vector2(v.x, v.y).sub(center);
var size = 2.0;
var magnitude = 8;
v.z = Math.sin(dist.length()/-size (ts/900)) * magnitude;
}
newPlane.geometry.verticesNeedUpdate = true;
};
requestAnimationFrame(animate)
renderer.render(scene, camera);
controls.update();
}
</script>
Я не профессионал, поэтому прошу прощения, если это слишком грубо для тех из вас, у кого есть опыт!
Я должен указать, что перед тем, как обернуть все это в init();
функцию, она работала идеально.
При работе я должен видеть грубо смоделированный корабль, сидящий в воде, с облачным скайбоксом. Элементы управления работали, и он автоматически поворачивался.
Прямо сейчас он ничего этого не делает. Загрузчик obj работает, как показано в журнале консоли Chrome OBJLoader: 1661.970703125ms
но опять же, на самом деле ничего не отображается, это просто черный экран.
Спасибо всем, кто может мне помочь с этим!
Ответ №1:
эта строка
animate;
требуется вызов функции
animate();
Также вам, вероятно, нужно изменить приведенный ниже код, из которого вы создаете функцию animate
var animate = function(){
К этому
function animate(){
Причина в том, что именованные функции определяются при загрузке кода, но переменные var
создаются при выполнении кода. Итак, с таким кодом, как этот
init();
animate();
var animate = function(){ ...
animate
на самом деле не существует в тот момент, когда код пытается его вызвать, тогда как с этим
init();
animate();
function animate(){ ...
он существует
Вы также могли бы изменить порядок кода, чтобы, например, определить, animate
прежде чем использовать, он должен работать.
var animate = function(){
...
};
init();
animate();
Также кажется, что некоторые из них объявлены внутри, init
что означает, что они недоступны для animate
. Так, например
var renderer = new THREE.WebGLRenderer({antialias : true});
объявляет новую переменную, renderer
которую может видеть только init
пользователь. Вы хотели установить renderer
переменную, которая находится за пределами init
, поэтому измените код на
renderer = new THREE.WebGLRenderer({antialias : true});
controls
никогда не определяется, поэтому вам, вероятно, нужно определить его или закомментировать
controls.update();
Для
// controls.update();
примечание: вы можете найти эти руководства полезными, хотя, если вы новичок в JavaScript, вам, вероятно, следует потратить время на изучение JavaScript
Комментарии:
1. Привет, спасибо, что так быстро ответили! Я внедрил предложенные вами изменения, и теперь я вижу, что эта ошибка отображается для каждого кадра. Есть идеи относительно того, почему это может быть?
Uncaught TypeError: Cannot read property 'render' of undefined
2. похоже, что в animate нет ссылок на контейнер и камеру, но да, код в беспорядке. Надеюсь, спрашивающий воспользуется советом прочитать несколько руководств по JavaScript. 😉
3. Спасибо за обновления, чувак. После того, что вы упомянули об удалении слова ‘var’, чтобы его можно было прочитать вне init, после этого возник ряд проблем, из-за которых я делал это на протяжении всего документа (следуя руководству). Кроме того, элементы управления orbit, у меня было кое-что для этого, что означало ‘update();’ должно работать, но я случайно удалил это. Но теперь это работает, большое спасибо за помощь, приятель, я действительно ценю это!