简体   繁体   中英

Using a GLTF model as the Scene in Three.js

I am new to Three.js. I am having issues using a gltf model as the actual scene and not part of the scene in three.js. The gltf model is an apartment. I want the scene to load from inside the apartment and not outside the apartment. the controls should work within the apartment too. So far, I have loaded the model on the scene but I can't get the scene to render from inside the model.

Here is my code in Typescript and also JavaScript been at it for weeks now. Any help will be much appreciated. Thank you so much.

Typescript code

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 code



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

Finally was able to solve my issue. firstly I had to use a plane model that is with no roof secondly the pivot point was properly at the center and the model was on the plane grid, unlike the first model I was working with.

with the model opened the room was what was rendered in the scene and not the entire model itself and because the pivot point was in the middle and the model on the plane, not below or above it, I did not have to look for it in the scene when it rendered. Thank you for reading and trying to help.

because I had solved this problem I was able to load multiple glb models and place them where I wanted in the scene without hassle.

my advice if you want to use a model as your scene make sure the pivot point is at the center and the model is on the grid, not over or below it. also make sure its an open model so your light and camera can see inside.

here was my final code.

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.')
    }

PLEASE FEEL FREE TO COMMENT IF THERE IS SOMETHING I NEED TO KNOW. I WILL HUMBLY TAKE CORRECTIONS. THANK YOU

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM