【Three.js基础学习】17.imported-models

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

课程回顾:

    如何在three.js 中引入不同的模型?

    1. 格式  (不同的格式)

    https://en.wikipedia.org/wiki/List_of_file_formats#3D_graphics // 请用外网打开

    如果想要加载一个模型,必须根据不同的标准选择格式

    OBJ FBX STL PLY 3DS GLTF

    COLLADA

    1.GLTF (使用这个) 会得到PBR材料 ,是基于物理的渲染材料,转化成网格标准材质

    https://github.com/KhronosGroup/glTF-Sample-Models

    // 将所需要的模型放到静态文件中,这取决与你要用什么

    例如:static/models/Duck

    这里有四个文件 对应格式 gltf ,gltf-binary(二进制),gltf-draco和gltf-embedded(嵌入式)

    我们要知道怎么用,这些格式各有特点,取决于我们的需求,可以利用对方的特点和优势

    2.如何在3D使用?

    使用加载器 ,实时上我们之前使用了加载器,如:纹理加载器,字体加载器等

    import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js

    gltfLoader.load()

    将模型添加到场景中

    scene.add(gltf.scene)

    3.Draco压缩

    Draco 比默认版本更加轻

    压缩应用于缓冲数据,通常是几何体

    Website: https://google.github.io/draco/

    Git repository: https://github.com/google/draco

    必须在GLTF之前实例化它

    为什么更快?

    draco压缩会将一部分js代码放到CPU上执行 使用WebAssembly和工人。

    相当于两个线程一起工作

    setDecoderPath

    4.将DracoLoader实例给予glTFLoader加载器

    setDRACOLoader

    5. 什么时候使用draco版本

    首先要DRACOLoader.js这个类,其次 在静态中把draco文件copy上去(解码器)

    文件更大时候,更适合使用,这样压缩版本使用 文件更小,节约

    6.冻结

    若是一个巨大的几何体,使用WebAssembly和工人时候,会加载好几秒,也就是冻结

    7.animations

    如何处理动画

    要播放动画需要 动画混合器

    new THREE.AnimationMixer()

    8.three.js3D编辑器

    搜索three.js.edito,点击第一个 或者

    https://threejs.org/editor/

    在这个微型在线模型编辑器中,可以将模型文件拖到这里 快速查看模板是否符合自己需要

    Duck.glb


一、代码

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
import * as dat from 'lil-gui'


/**
 * Base
 */
// Debug
const gui = new dat.GUI()

// Canvas
const canvas = document.querySelector('canvas.webgl')

// Scene
const scene = new THREE.Scene()

/* 
    Models
*/
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('/draco/')  // 要将models中的文件放到静态文件中 (注意要将数据放到models下)

const gltfLoader = new GLTFLoader()
gltfLoader.setDRACOLoader(dracoLoader)

let mixer = null

gltfLoader.load(
    // '/models/Duck/glTF/Duck.gltf', // 2.
    // '/models/FlightHelmet/glTF/FlightHelmet.gltf', // 会遇到将模型放到场景中,显示不全 1. 2.
    // '/models/Duck/glTF-Draco/Duck.gltf',  // draco 压缩 版本 2.
    '/models/Fox/glTF/Fox.gltf',  // 实现动画 会动的狐狸
    (gltf)=>{
        console.log(gltf)
        // 这里注意若使用 for of 会造成循环混乱
        // 1.初级使用, 让我们知道gltf 加载了什么,怎么加载
        // 所以可以使用white 或者拓展运算符
        // const children = [...gltf.scene.children]
        // for(const child of children){
        //     scene.add(child)
        // }

        // 2.当然上面是为了理解,也可以一行代码搞定
        // scene.add(gltf.scene)

        // 3.实现狐狸动画
        mixer = new THREE.AnimationMixer(gltf.scene) // 动画混合器
        const action = mixer.clipAction(gltf.animations[2]) // 动画剪辑器 clipAction  animations[0] 通过控制台可以看到狐狸关键帧数据,抬腿,摇头等等,
        action.play() // 开始 同时需要在更新时间时候 更新关键帧

        gltf.scene.scale.set(0.025,0.025,0.025)
        scene.add(gltf.scene)
    },
    ()=>{
        console.log('progress')
    },
    ()=>{
        console.log('error')
    }
)

/**
 * Floor
 */
const floor = new THREE.Mesh(
    new THREE.PlaneGeometry(10, 10),
    new THREE.MeshStandardMaterial({
        color: '#444444',
        metalness: 0,
        roughness: 0.5
    })
)
floor.receiveShadow = true
floor.rotation.x = - Math.PI * 0.5
scene.add(floor)

/**
 * Lights
 */
const ambientLight = new THREE.AmbientLight(0xffffff, 0.8)
scene.add(ambientLight)

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6)
directionalLight.castShadow = true
directionalLight.shadow.mapSize.set(1024, 1024)
directionalLight.shadow.camera.far = 15
directionalLight.shadow.camera.left = - 7
directionalLight.shadow.camera.top = 7
directionalLight.shadow.camera.right = 7
directionalLight.shadow.camera.bottom = - 7
directionalLight.position.set(5, 5, 5)
scene.add(directionalLight)

/**
 * Sizes
 */
const sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}

window.addEventListener('resize', () =>
{
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})

/**
 * Camera
 */
// Base camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
camera.position.set(2, 2, 2)
scene.add(camera)

// Controls
const controls = new OrbitControls(camera, canvas)
controls.target.set(0, 0.75, 0)
controls.enableDamping = true

/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

/**
 * Animate
 */
const clock = new THREE.Clock()
let previousTime = 0

const tick = () =>
{
    const elapsedTime = clock.getElapsedTime()
    const deltaTime = elapsedTime - previousTime
    previousTime = elapsedTime

    // Updata mixer
    if(mixer != null){
        mixer.update(deltaTime)
    }
    

    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

二、知识点

1.格式以及引用模型

    OBJ FBX STL PLY 3DS GLTF

    COLLADA

 有不同的格式这里使用GLTF

GLTF

对应格式 gltf ,gltf-binary(二进制),gltf-draco和gltf-embedded(嵌入式)

如何使用

   import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js

    gltfLoader.load()

    将模型添加到场景中

    scene.add(gltf.scene)

2.Draco压缩

如何使用

import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'

const dracoLoader = new DRACOLoader()

dracoLoader.setDecoderPath('/draco/')  // 要将models中的文件放到静态文件中 (注意要将数据放到models下)

3.动画

 new THREE.AnimationMixer() 动画混合器

clipAction 动画剪辑器

play 更新关键帧 同时要配合更新的时间使用

4.效果

1.鸭子关键代码 ,没有用到draco压缩

// models

const gltfLoader = new GLTFLoader()


gltfLoader.load(
    '/models/Duck/glTF/Duck.gltf', // 2.
   (gltf)=>{
    console.log(gltf)
    //    const children = [...gltf.scene.children]
    //     for(const child of children){
    //         scene.add(child)
    //     }

    scene.add(gltf.scene)


   }
)

2.人像

const gltfLoader = new GLTFLoader()
// gltfLoader.setDRACOLoader(dracoLoader)

let mixer = null

gltfLoader.load(
    // '/models/Duck/glTF/Duck.gltf', // 2.
   '/models/FlightHelmet/glTF/FlightHelmet.gltf', // 会遇到将模型放到场景中,显示不全 1. 2.
   (gltf)=>{
    console.log(gltf)
    //    const children = [...gltf.scene.children]
        for(const child of gltf.scene.children){
            scene.add(child)
        }

   }
)

会看到加载进去的不完整

const gltfLoader = new GLTFLoader()
// gltfLoader.setDRACOLoader(dracoLoader)

gltfLoader.load(
    // '/models/Duck/glTF/Duck.gltf', // 2.
   '/models/FlightHelmet/glTF/FlightHelmet.gltf', // 会遇到将模型放到场景中,显示不全 1. 2.
   (gltf)=>{
    console.log(gltf)
       const children = [...gltf.scene.children]
        for(const child of children){
            scene.add(child)
        }
        // scene.add(gltf.scene) //两种方式都可以
   }
)

3.draco压缩使用 鸭子

const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('/draco/') 

const gltfLoader = new GLTFLoader()
gltfLoader.setDRACOLoader(dracoLoader)

// let mixer = null

gltfLoader.load(
    '/models/Duck/glTF-Draco/Duck.gltf',  // draco 压缩 版本 2., // 会遇到将模型放到场景中,显示不全 1. 2.
   (gltf)=>{
    console.log(gltf)
    //    const children = [...gltf.scene.children]
        // for(const child of children){
        //     scene.add(child)
        // }
        scene.add(gltf.scene)
   }
)

4.狐狸


// models
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('/draco/') 

const gltfLoader = new GLTFLoader()
gltfLoader.setDRACOLoader(dracoLoader)

let mixer = null

gltfLoader.load(
    // '/models/Duck/glTF/Duck.gltf', // 2.
//    '/models/FlightHelmet/glTF/FlightHelmet.gltf', // 会遇到将模型放到场景中,显示不全 1. 2.
'/models/Fox/glTF/Fox.gltf',  // 实现动画 会动的狐狸
   (gltf)=>{
        console.log(gltf)
        mixer = new THREE.AnimationMixer(gltf.scene) // 动画混合器
        const action = mixer.clipAction(gltf.animations[2]) // 动画剪辑器 clipAction  animations[0] 通过控制台可以看到狐狸关键帧数据,抬腿,摇头等等,
        action.play() // 开始 同时需要在更新时间时候 更新关键帧

        gltf.scene.scale.set(0.025,0.025,0.025)
        scene.add(gltf.scene)
   }
)

注意更新时间

const tick = () =>
{
    const elapsedTime = clock.getElapsedTime()
    const deltaTime = elapsedTime - previousTime
    previousTime = elapsedTime

    // Updata mixer
    if(mixer != null){
        mixer.update(deltaTime)
    }

    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

综合

效果


总结

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值