【问题标题】:Using a GLTF model as the Scene in Three.js在 Three.js 中使用 GLTF 模型作为场景
【发布时间】:2021-07-15 16:35:35
【问题描述】:

我是 Three.js 的新手。我在使用 gltf 模型作为实际场景而不是 three.js 中场景的一部分时遇到问题。 gltf 模型是一个公寓。我希望从公寓内部而不是公寓外部加载场景。控件也应该在公寓内工作。到目前为止,我已将模型加载到场景中,但无法从模型内部渲染场景。

这是我在 Typescript 中的代码,JavaScript 也已经使用了数周了。任何帮助都感激不尽。非常感谢。

打字稿代码

import * as THREE from '/build/three.module.js'
import { OrbitControls } from '/jsm/controls/OrbitControls'
import { GLTFLoader } from '/jsm/loaders/GLTFLoader'
import Stats from '/jsm/libs/stats.module'

const scene: THREE.Scene = new THREE.Scene()
const axesHelper = new THREE.AxesHelper(5)
//scene.add(axesHelper)

var light = new THREE.SpotLight();
light.position.set(5, 5, 5)
scene.add(light);

const camera: THREE.PerspectiveCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 2

const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer()
//renderer.physicallyCorrectLights = true
//renderer.shadowMap.enabled = true
renderer.outputEncoding = THREE.sRGBEncoding
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

const controls = new OrbitControls(camera, renderer.domElement)

const loader = new GLTFLoader()
loader.load(
    'apartment.glb',
    function (gltf) {
        // gltf.scene.traverse(function (child) {
        //     if ((<THREE.Mesh>child).isMesh) {
        //         let m = <THREE.Mesh>child
        //         m.receiveShadow = true
        //         m.castShadow = true
        //     }
        //     if ((<THREE.Light>child).isLight) {
        //         let l = <THREE.Light>child
        //         l.castShadow = true
        //         //l.shadow.bias = -.003
        //         l.shadow.mapSize.width = 2048
        //         l.shadow.mapSize.height = 2048
        //     }
        // })
        scene.add(gltf.scene);
    },
    (xhr) => {
        console.log((xhr.loaded / xhr.total * 100) + '% loaded')
    },
    (error) => {
        console.log(error);
    }
);


window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
    render()
}

const stats = Stats()
document.body.appendChild(stats.dom)

var animate = function () {
    requestAnimationFrame(animate)

    controls.update()

    render()

    stats.update()
};

function render() {
    renderer.render(scene, camera)
}
animate();



JavaScript 代码



import * as THREE from '/build/three.module.js';
import { OrbitControls } from '/jsm/controls/OrbitControls';
import { GLTFLoader } from '/jsm/loaders/GLTFLoader';
import Stats from '/jsm/libs/stats.module';


const scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(5);
//scene.add(axesHelper)

var light = new THREE.SpotLight();
light.position.set(5, 5, 5);
scene.add(light);

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 2;
const renderer = new THREE.WebGLRenderer();

//renderer.physicallyCorrectLights = true
//renderer.shadowMap.enabled = true

renderer.outputEncoding = THREE.sRGBEncoding;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);


const controls = new OrbitControls(camera, renderer.domElement);
const loader = new GLTFLoader();
loader.load('apartment.glb', function (gltf) {
    // gltf.scene.traverse(function (child) {
    //     if ((<THREE.Mesh>child).isMesh) {
    //         let m = <THREE.Mesh>child
    //         m.receiveShadow = true
    //         m.castShadow = true
    //     }
    //     if ((<THREE.Light>child).isLight) {
    //         let l = <THREE.Light>child
    //         l.castShadow = true
    //         //l.shadow.bias = -.003
    //         l.shadow.mapSize.width = 2048
    //         l.shadow.mapSize.height = 2048
    //     }
    // })
    scene.add(gltf.scene);
}, (xhr) => {
    console.log((xhr.loaded / xhr.total * 100) + '% loaded');
}, (error) => {
    console.log(error);
});

window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    render();
}
const stats = Stats();
document.body.appendChild(stats.dom);
var animate = function () {
    requestAnimationFrame(animate);
    controls.update();
    render();
    stats.update();
};
function render() {
    renderer.render(scene, camera);
}
animate();

【问题讨论】:

  • “无法从模型内部渲染场景”是什么意思?
  • 非常感谢您的提问。我有一个 gltf 格式的公寓模型。问题是当我将它加载到场景中时,它不会出现我必须放大并在场景中移动以定位对象。第二个问题是它从外部展示了整个模型。我希望场景能够加载并查看模型,而无需滚动来查找对象并从公寓内部加载。我希望场景加载模型的内部视图,而不是屏幕上的整个内容。目前在搅拌机中解构模型,看看我是否可以在three.js中重新排列它。

标签: javascript typescript three.js gltf


【解决方案1】:

终于能够解决我的问题。 首先我必须使用没有屋顶的平面模型 其次,与我使用的第一个模型不同,枢轴点正确位于中心,模型位于平面网格上。

打开模型后,房间是在场景中渲染的,而不是整个模型本身,因为轴心点在中间,模型在平面上,而不是在它的下方或上方,我不必看渲染时在场景中。感谢您阅读并尝试提供帮助。

因为我已经解决了这个问题,所以我能够加载多个 glb 模型并将它们放置在场景中我想要的位置。

如果您想使用模型作为场景,我的建议是确保轴心点位于中心并且模型在网格上,而不是在网格之上或之下。还要确保它是一个开放的模型,以便您的灯光和相机可以看到里面。

这是我的最终代码。

import * as THREE from '/build/three.module.js'
import { OrbitControls } from '/jsm/controls/OrbitControls'
import { GLTFLoader } from '/jsm/loaders/GLTFLoader'
// import Stats from '/jsm/libs/stats.module'
// import { GUI } from '/jsm/libs/dat.gui.module'

const scene: THREE.Scene = new THREE.Scene()
const axesHelper = new THREE.AxesHelper(5)
//scene.add(axesHelper)

const light = new THREE.SpotLight(0xffa95c,4);
light.position.set(-50,50,50);
light.castShadow = true;
scene.add( light );

var hemiLight = new THREE.HemisphereLight(0xffeeb1, 0x080820, 4);
scene.add(hemiLight);

 var light3 = new THREE.DirectionalLight( 0xffffff );
        light3.position.set( 0, 200, 100 );
        light3.castShadow = true;
        light3.shadow.mapSize.width = 2048; 
        light3.shadow.mapSize.height = 2048;
        light3.shadow.camera.top = 3000;
        light3.shadow.camera.bottom = -3000;
        light3.shadow.camera.left = -3000;
        light3.shadow.camera.right = 3000;
        light3.shadow.camera.far = 3000;
        scene.add( light );


const camera: THREE.PerspectiveCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 2
camera.position.y = 2
camera.position.x = 2



const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer()
//renderer.physicallyCorrectLights = true
//renderer.shadowMap.enabled = true
renderer.outputEncoding = THREE.sRGBEncoding
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)


// var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
//      mesh.rotation.x = - Math.PI / 2;
//      //mesh.position.y = -100;
//      mesh.receiveShadow = true;
//      //this.scene.add( mesh );

//      var grid = new THREE.GridHelper( 2000, 40, 0x000000, 0x000000 );
//      //grid.position.y = -100;
//      // grid.material.opacity = 0.2;
//      // grid.material.transparent = true;

const raycaster = new THREE.Raycaster();


const controls = new OrbitControls(camera, renderer.domElement)
controls.screenSpacePanning = true
controls.target.set(0, 1, 0)
controls.minDistance = 5;
controls.maxDistance = 10;

// const backGroundTexture = new THREE.CubeTextureLoader().load(["img/py_eso0932a.jpg", "img/ny_eso0932a.jpg", "img/py_eso0932a.jpg", "img/ny_eso0932a.jpg", "img/pz_eso0932a.jpg", "img/nz_eso0932a.jpg"]);
// scene.background = backGroundTexture;

const loader = new GLTFLoader()

loader.load(
    'models3/untitled.glb',
    function (gltf) {

               scene.add(gltf.scene);
               gltf.scene.position.set(0,-2,3)

    },
    (xhr) => {
        console.log((xhr.loaded / xhr.total * 100) + '% loaded')
    },
    (error) => {
        console.log(error);
    }
);

loader.load(
    'models3/man.glb',
    function (gltf1) {

               scene.add(gltf1.scene);
               gltf1.scene.position.set(1,-1.3,0)
               gltf1.scene.scale.set(2,2,2)
           

    },
    (xhr) => {
        console.log((xhr.loaded / xhr.total * 100) + '% loaded')
    },
    (error) => {
        console.log(error);
    }
);


loader.load(
    'models3/jack_daniels.glb',
    function (gltf2) {

        gltf2.scene.traverse(function (child) {
            if ((<THREE.Mesh>child).isMesh) {
                let m = <THREE.Mesh>child
                m.receiveShadow = true
                m.castShadow = true;
                //(<THREE.MeshStandardMaterial>m.material).flatShading = true
                //sceneMeshes.push(m)
            }
            if ((<THREE.Light>child).isLight) {
                let l = <THREE.Light>child
                l.castShadow = true
                l.shadow.bias = -.003
                l.shadow.mapSize.width = 2048
                l.shadow.mapSize.height = 2048
            }

               scene.add(gltf2.scene);
               gltf2.scene.position.set(-1,0.55,-1)
               gltf2.scene.scale.set(0.15,0.15,0.15)})

            },
           
    (xhr) => {
        console.log((xhr.loaded / xhr.total * 100) + '% loaded')
    },
    (error) => {
        console.log(error);
    }
);

// renderer.domElement.addEventListener('dblclick', onDoubleClick, false);
// renderer.domElement.addEventListener('mousemove', onMouseMove, false);

// function onMouseMove(event: MouseEvent) {
//     const mouse = {
//         x: (event.clientX / renderer.domElement.clientWidth) * 2 - 1,
//         y: -(event.clientY / renderer.domElement.clientHeight) * 2 + 1
//     }

//     //console.log(mouse)

//     raycaster.setFromCamera(mouse, camera);




window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
    render()
}



// const stats = Stats()
// document.body.appendChild(stats.dom)

var animate = function () {
    requestAnimationFrame(animate)

    // light.position.set( 
    //     camera.position.x + 10,
    //     camera.position.y + 10,
    //     camera.position.z + 10,
    //   );

    controls.update()

    render()

    // stats.update()
};

function render() {
    renderer.render(scene, camera)
}
animate();
    function onDoubleClick(arg0: string, onDoubleClick: any, arg2: boolean) {
        throw new Error('Function not implemented.')
    }

如果有什么我需要知道的,请随时发表评论。我会虚心改正。谢谢你

【讨论】:

    猜你喜欢
    • 2016-10-28
    • 2021-06-11
    • 2018-08-02
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 2018-08-01
    • 2018-09-26
    相关资源
    最近更新 更多