三种启用阴影渲染的js缓慢

时间:2019-09-26 14:17:21

标签: three.js

我正在使用GLTFLoader将建筑模型加载到场景并应用一些纹理,还添加了两个启用了阴影的PointLight源。我正在为建筑物使用自阴影,即建筑物本身应从光源创建阴影。

但是,当我加载页面时,页面出现性能问题,状态的帧速率太慢,整个系统都处于挂起状态。 但是,如果禁用阴影,一切都会按预期进行。这是预期的还是我可以在编码方面进行改进。

这是工作中的小提琴

http://jsfiddle.net/n9eg3kox/

var camera, scene, renderer, stats;
var mesh;
var controls;
var BuildingObj;
var OutFloor;
var enableShadow = true; // if I make it false the code work fine   
var pointLight2, pointLight3;

function init() {

    var webglEl = document.getElementById('webgl');
    if (!Detector.webgl) {
        Detector.addGetWebGLMessage(webglEl);
        alert("WebGL no Support");
        return;
    }

    THREE.ImageUtils.crossOrigin = '';
    renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
    renderer.setPixelRatio(window.devicePixelRatio * 1.5);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.physicallyCorrectLights = true;
    renderer.gammaInput = true;
    renderer.gammaOutput = true;
    renderer.shadowMap.enabled = enableShadow;
    renderer.toneMapping = THREE.ReinhardToneMapping;
    webglEl.appendChild(renderer.domElement);
    renderer.setClearColor(0x555555, 1);

    var width = window.innerWidth, height = window.innerHeight;
    camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 2000);
    camera.position.x = 0;
    camera.position.y = 4;
    camera.position.z = 30;
    scene = new THREE.Scene();

    var axesHelper = new THREE.AxesHelper(100);
    scene.add(axesHelper);

    var intensity = 5;
    var distance = 40;
    var decay = 1.0;

    pointLight2 = new THREE.PointLight(0xFFFFFF, intensity);
    pointLight2.add(new THREE.Mesh(new THREE.SphereBufferGeometry(3, 16, 16), new THREE.MeshPhongMaterial({ color: 0xfffdfb, emissive: 0xfffdfb, emissiveIntensity: 100 })));
    pointLight2.position.set(-60, 80, 40);
    pointLight2.castShadow = enableShadow;
    pointLight2.visible = true;
    pointLight2.shadow.mapSize.width = 1024;
    pointLight2.shadow.mapSize.height = 1024;
    scene.add(pointLight2);

    pointLight3 = new THREE.PointLight(0xFFFFFF, intensity);
    pointLight3.add(new THREE.Mesh(new THREE.SphereBufferGeometry(3, 16, 16), new THREE.MeshPhongMaterial({ color: 0xfffdfb, emissive: 0xfffdfb, emissiveIntensity: 100 })));
    pointLight3.position.set(60, 80, 40);
    pointLight3.castShadow = enableShadow;
    pointLight3.shadow.mapSize.width = 1024;
    pointLight3.shadow.mapSize.height = 1024;
    pointLight3.visible = true;
    scene.add(pointLight3);

    //var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 21 );
    //scene.add( light );

    controls = new THREE.OrbitControls(camera, webglEl);
    stats = new Stats();
    webglEl.appendChild(stats.dom);
    loadObject();
    animate();
}

function animate() {
    controls.update();
    stats.update();
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}

function loadObject() {

    var loader = new THREE.GLTFLoader();
    loader.load(
        //'./Model/GLTF/test.glb',
        './test/test.glb',
        function (gltf) {
            gltf.scene.traverse(function (node) {
                if (node.isGroup) {
                    if (node.name === "Building") {
                        BuildingObj = node;

                    } else if (node.name === "Cube") {
                        OutFloor = node;
                    }
                }
            });
            scene.add(OutFloor);
            scene.add(BuildingObj);
            applyMaterialToObject();
        },
        function (xhr) {
            console.log((xhr.loaded / xhr.total * 100) + '% loaded');
        },

        function (error) {
            console.log('An error happened---' + error);
        }
    );
}

function applyMaterialToObject(object) {

    for (var i = 0; i < BuildingObj.children.length; i++) {
        var obj = BuildingObj.children[i];
        var material = new THREE.MeshStandardMaterial({ roughness: 0.8, metalness: 0.3, bumpScale: - 0.05, color: 0xffffff, });
        loadTexturesToMaterial(BuildingObj.children[i], material, "./test/brick.jpg", "./test/brick_b.jpg", "./test/brick_r.jpg", 25, 70, Math.PI / 2);
    }

    for (var i = 0; i < OutFloor.children.length; i++) {
        var obj = OutFloor.children[i];
        var material = new THREE.MeshStandardMaterial({ roughness: 0.5, metalness: 0.8, bumpScale: - 0.05, color: 0xffffff });
        loadTexturesToMaterial(obj, material, "./test/tile2.jpg", "./test/tile2_b.jpg", "./test/tile2_r.jpg", 35, 100, Math.PI / 2);
    }
}

function loadTexturesToMaterial(obj, material, map_img, bumpMap_img, roughnessMap_img, v_count, h_count, rotation) {

    obj.receiveShadow = enableShadow;
    obj.castShadow = enableShadow;
    obj.material = material;
    obj.material.side = THREE.DoubleSide;

    var textureLoader = new THREE.TextureLoader();
    textureLoader.load(map_img, function (map) {
        map.wrapS = THREE.RepeatWrapping;
        map.wrapT = THREE.RepeatWrapping;
        map.rotation = rotation;
        map.repeat.set(v_count, h_count);
        obj.material.map = map;
        obj.material.needsUpdate = true;
    });

    textureLoader.load(bumpMap_img, function (map) {
        map.wrapS = THREE.RepeatWrapping;
        map.wrapT = THREE.RepeatWrapping;
        map.rotation = rotation;
        map.repeat.set(v_count, h_count);
        obj.material.bumpMap = map;
        obj.material.needsUpdate = true;
    });

    textureLoader.load(roughnessMap_img, function (map) {
        map.wrapS = THREE.RepeatWrapping;
        map.wrapT = THREE.RepeatWrapping;
        map.rotation = rotation;
        map.repeat.set(v_count, h_count);
        obj.material.roughnessMap = map;
        obj.material.needsUpdate = true;
    });
}

注意:我已经使用Blender创建了模型。

编辑:纹理和模型链接

https://github.com/SourceCodeZone/3D

0 个答案:

没有答案