为什么我的画布元素仅显示黑屏?

时间:2019-03-29 18:33:08

标签: javascript three.js

我正在Three.js中设置3d资产查看器。我正在大学提供的Plesk服务器上运行代码,并通过Dreamweaver进行链接。我是JS的新手,很多线程和帖子都建议我将代码包装在'init();'函数中。这样做并清除代码中的所有错误后,它现在显示黑屏,而不是以前显示的3d模型。

我花费了一整天的时间检查错误,以解决自己遇到的问题,其中包括未在'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();函数中之前,它运行良好。

工作时,我应该看到一艘粗造的船坐在一些水中,上面有一个云天窗。控件正在工作,它将自动旋转。

现在,它什么都不做。如chrome控制台日志OBJLoader: 1661.970703125ms所示,obj加载程序正在工作,但实际上没有任何显示,只是黑屏。

感谢所有能够帮助我解决这个问题的人!

1 个答案:

答案 0 :(得分:2)

此行

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();

注意:您可能会发现these tutorials helpful,尽管如果您不熟悉JavaScript,则可能应该花时间learning JavaScript