乐趣区

关于javascript:THREEjs设置背景图和播放动画学习-大帅老猿threejs特训

THREE.js 设置背景图和播放动画学习 | 大帅老猿 threejs 特训

本文能学到什么

作者的 three.js 属于入门的,最近跟着大帅的训练营,学习了 three.js 如何设置全景图背景和播放动画,本文章应用的模型和图片都是当时提供好的,咱们只须要实现加载背景图、加载模型和播放动画即可

成果

具体实现

初始化

首先咱们依照惯例,生成 scene、camera 和 renderer

let scene, camera, renderer
function init() {scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10);
    renderer = new THREE.WebGLRenderer({antialias: true});

    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.position.set(0.6, 0.6, 1);
    document.body.appendChild(renderer.domElement);

}

init()

加载模型


function loadModel() {const gltfLoader = new GLTFLoader()
    gltfLoader.load('../resources/models/donuts.glb', gltf => {scene.add(gltf.scene);
    });
}

loadmodel()

初始化控制器

function initControls() {controls = new OrbitControls(camera, renderer.domElement);
}
initControls()

渲染

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

模仿太阳光

这时候整个场景事彩色的,咱们加个 directionLight,模仿太阳光

function init() {
    ...
    const directionLight = new THREE.DirectionalLight(0xffffff, 0.4);
    scene.add(directionLight);
}

加载背景图

function loadBackground() {const rgbeLoader = new RGBELoader()
    rgbeLoader.load('../resources/hdr/sky.hdr', function (texture) {scene.background = texture;});
}

loadModel()
loadBackground()

首先这里应用 hdr,hdr 比一般的 jpg 和 png,在光洁很强或者很暗的中央,可能展现更多的细节,而一般的 jpg、png 就只能显示红色或者彩色
咱们单纯的给 scene 设置背景,就是固定的背景,咱们心愿变成全景图的背景,须要设置几个值,这几个值的含意如下:

  • THREE.EquirectangularReflectionMapping叫做经纬线映射贴图,设置这个值,就能实现图片全景展现
  • scene.environment = texture;若该值不为 null,则该纹理贴图将会被设为场景中所有物理材质的环境贴图。然而,该属性不可能笼罩已存在的、已调配给 MeshStandardMaterial.envMap 的贴图。默认为 null。
  • renderer.outputEncoding属性管制输入渲染编码。默认状况下,outputEncoding 的值为 THREE.LinearEncoding,看起来还行然而不实在,将值改为 THREE.sRGBEncoding 后成果会更实在
function loadBackground() {
    ...
    rgbeLoader.load('../resources/hdr/sky.hdr', function (texture) {
        scene.background = texture;
        texture.mapping = THREE.EquirectangularReflectionMapping;
        scene.environment = texture;
        renderer.outputEncoding = THREE.sRGBEncoding;
    });
}

播放动画

先补充一些知识点:

  • 咱们应用软件制作模型的时候,通常有两种动画制作的模式:变形动画和骨骼动画。咱们这里用到的是变形动画,就不开展骨骼动画了。
  • 应用变形动画,你须要定义网格变形之后的状态,或者说是要害地位。对于变形指标,所有的顶点地位都会被存储下来。你所须要做的是将所有的顶点从一个地位挪动到另一个定义好的要害地位,并反复该过程。
  • 变形动画长处是可能失去更好的成果,因为它将每一个动作每一个顶点的地位都存储了下来,这样相应的毛病是会造成文件变大。
  • AnimationMixer对象是场景中特定对象的动画播放器。当场景中的多个对象独立动画时,能够为每个对象应用一个 AnimationMixer。咱们须要透过这个对象实现动画。
  • 再用 AnimationMixer 对象的 clipAction 办法生成能够管制执行动画的实例。
  • 咱们的动画只须要执行一次,所以设置action.loop = THREE.LoopOnce
  • 咱们须要在动画完结后,放弃完结动画的状态,须要设置action.clampWhenFinished = true
gltfLoader.load('../resources/models/donuts.glb', gltf => {scene.add(gltf.scene);

        mixer = new THREE.AnimationMixer(gltf.scene);
        const clips = gltf.animations;
        clips.forEach(clip => {const action = mixer.clipAction(clip);
            action.loop = THREE.LoopOnce;
            action.clampWhenFinished = true
            action.play()})
    });

主动旋转

因为是一个观赏性的物品,咱们给咱们的甜甜圈加上主动旋转


function loadModel() {
    ...
    gltfLoader.load('../resources/models/donuts.glb', gltf => {
        donuts = gltf.scene;
        scene.add(donuts);
        mixer = new THREE.AnimationMixer(donuts);
        ...
    });
}

function animate() {
    ...
    if (donuts){donuts.rotation.y += 0.01;}
    ...
}

结尾

咱们的基本功能都实现了,我认为重点是加载背景图和播放动画两个点须要重点学习,尽管代码简略,然而须要了解的内容还是不少的。
附上 github 地址:https://github.com/luch1994/t…
最初,退出猿创营 (v:dashuailaoyuan),一起交流学习

退出移动版