javascript - 为什么我的 Canvas 元素只显示黑屏?

标签 javascript three.js

我正在 Three.js 中设置 3d 资源查看器。我在大学提供的 Plesk 服务器上运行代码,并通过 Dreamweaver 链接它。我是 JS 的新手,许多线程和帖子都建议我将代码包装在 'init();' 函数中。执行此操作并清除代码中的任何错误后,它现在显示黑屏,而不是之前显示的 3D 模型。

我花了一整天的时间进行错误检查,以消除遇到的问题,其中包括未在 'container' div 内创建“canvas”,以及 '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 所示,但实际上什么也没有显示,只是黑屏。

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

最佳答案

这一行

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

声明一个只有init才能看到的新变量renderer。您想要设置 init 外部的 renderer 变量,因此将代码更改为

 renderer = new THREE.WebGLRenderer({antialias : true});

controls 从未定义,因此您可能需要定义它或注释掉

 controls.update();

 // controls.update();

注意:您可能会发现 these tutorials helpful不过,如果您是 JavaScript 新手,您可能应该花时间 learning JavaScript

关于javascript - 为什么我的 Canvas 元素只显示黑屏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55423634/

相关文章:

javascript - 在样式化组件中使用 Ant Design 变量

javascript - 如何使 Facebook 的 Chrome 扩展重复执行?

javascript - 拖动条件绘制 - Openlayers

javascript - 仅当我打开开发人员工具栏时加载模型

php - 如何在表单中显示从数据库中取出的数据

javascript - 三个js物体绕球体旋转

unity3d - 统一 : how to embed a VR Cardboard game into a website

javascript - Three.js 未在 Vue.js 中渲染

javascript - 如何确定 Object3D 的宽度/高度/深度(就好像它没有旋转一样)?

javascript - Date.now() 在浏览器中的准确性