> 文章列表 > ThreeJS-炫酷球形机器人(三十一)

ThreeJS-炫酷球形机器人(三十一)

ThreeJS-炫酷球形机器人(三十一)

素材:

链接: https://pan.baidu.com/s/1S8V2gUFwiCjLYIcN9GFu-A

提取码: rjpx 

关键代码:

  //添加底部旋转纹理

    const videoElem = document.createElement('video');

    videoElem.src = 'three/robot-footer.mp4';

    videoElem.loop = true;

    videoElem.muted = true;

    videoElem.play();

    const videoLoader = new THREE.VideoTexture(videoElem);

    const planeGeometry = new THREE.PlaneBufferGeometry(16, 9);

    const meshMaterial = new THREE.MeshBasicMaterial({

      transparent: true,

      alphaMap: videoLoader,

      map: videoLoader,

      side: THREE.DoubleSide

    });

    const mesh = new THREE.Mesh(planeGeometry, meshMaterial);

    mesh.rotation.x = -Math.PI/2;

    mesh.position.set(0, 0.2, 0);

    scene.add(mesh);

    //创建镜面

    const reflectorPlaneGeometry = new THREE.PlaneBufferGeometry(100, 100);

    const reflector = new Reflector(reflectorPlaneGeometry, {

      textureWidth: window.innerWidth,

      textureHeight: window.innerHeight,

      color: 0xffffff,

    });

    reflector.rotation.x = -Math.PI/2;

    scene.add(reflector);

完整代码:

<template>

  <div id="three_div"></div>

</template>

<script>

import * as THREE from "three";

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";

import { Reflector } from "three/examples/jsm/objects/Reflector";

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";

import gsap from "gsap";

export default {

  name: "HOME",

  components: {

    // vueQr,

    // glHome,

  },

  data() {

    return {};

  },

  mounted() {

    //使用控制器控制3D拖动旋转OrbitControls

    //控制3D物体移动

    //1.创建场景

    const scene = new THREE.Scene();

    //2.创建相机

    const camera = new THREE.PerspectiveCamera(

      75,

      window.innerWidth / window.innerHeight,

      0.1,

      20000

    );

    //设置相机位置

    camera.position.set(0, 0, 10);

    //将相机添加到场景

    scene.add(camera);

    const axesHelper = new THREE.AxesHelper(5,5,5);

    scene.add(axesHelper);

    //创建背景星空

    const rgbeLoader = new RGBELoader();

    rgbeLoader.loadAsync('three/robot_background.hdr').then( loader => {

      loader.mapping = THREE.EquirectangularReflectionMapping;

      scene.background = loader;

    });

    //添加机器人模型

    const gltf = new GLTFLoader().setPath('three/glb/');

    //创建解码加载器

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

    //设置解码器

    gltf.setDRACOLoader(dracoLoader);

    //加载模型

    gltf.load('robot.glb', gltf => {

      scene.add(gltf.scene);

    })

    //添加灯光

    const light1 = new THREE.DirectionalLight(0xffffff, 1);

    light1.position.set(10, 10, 5);

    scene.add(light1);

    const light2 = new THREE.DirectionalLight(0xffffff, 1);

    light2.position.set(10, 10, -5);

    scene.add(light2);

    const light3 = new THREE.DirectionalLight(0xffffff, 1);

    light3.position.set(-10, 10, 5);

    scene.add(light3);

    //添加底部旋转纹理

    const videoElem = document.createElement('video');

    videoElem.src = 'three/robot-footer.mp4';

    videoElem.loop = true;

    videoElem.muted = true;

    videoElem.play();

    const videoLoader = new THREE.VideoTexture(videoElem);

    const planeGeometry = new THREE.PlaneBufferGeometry(16, 9);

    const meshMaterial = new THREE.MeshBasicMaterial({

      transparent: true,

      alphaMap: videoLoader,

      map: videoLoader,

      side: THREE.DoubleSide

    });

    const mesh = new THREE.Mesh(planeGeometry, meshMaterial);

    mesh.rotation.x = -Math.PI/2;

    mesh.position.set(0, 0.2, 0);

    scene.add(mesh);

    //创建镜面

    const reflectorPlaneGeometry = new THREE.PlaneBufferGeometry(100, 100);

    const reflector = new Reflector(reflectorPlaneGeometry, {

      textureWidth: window.innerWidth,

      textureHeight: window.innerHeight,

      color: 0xffffff,

    });

    reflector.rotation.x = -Math.PI/2;

    scene.add(reflector);

 

    //初始化渲染器

    const render = new THREE.WebGLRenderer({

      //设置抗锯齿,防失真

      antialis: true,

      //对数深度缓冲区,防止模型闪烁

      logarithmicdepthbuffer: true,

    });

    /*设置场景渲染编码threejs将贴图的编码都默认设置为THREE.LinearEncoding,

     *导致图片色彩失真(色彩不像正常那么鲜艳,会灰蒙蒙的),所以务必将场景中的所有贴图的编码都调整为THREE.sRGBEncoding

     */

    render.outputEncoding = THREE.sRGBEncoding;

    //设置渲染器的尺寸

    render.setSize(window.innerWidth, window.innerHeight);

    //清除默认设置颜色

    render.setClearColor("#000");

    //设置曝光类型(电影类型、文本类型、游戏类型),电影类型

    render.toneMapping = THREE.ACESFilmicToneMapping;

    //曝光强度

    render.toneMappingExposure = 0.5;

    //开启物理灯光,使灯光效果更佳真实Correct(准确)

    render.physicallyCorrectLights = true;

    //创建轨道控制器,可以拖动,控制的是摄像头

    const controls = new OrbitControls(camera, render.domElement);

    //设置控制阻尼,让控制器有更真实的效果

    controls.enableDamping = true;

    //将webgl渲染的canvas内容添加到body上

    document.getElementById("three_div").appendChild(render.domElement);

    //渲染下一帧的时候就会调用回调函数

    let renderFun = () => {

      //更新阻尼数据

      controls.update();

      //需要重新绘制canvas画布

      render.render(scene, camera);

      //监听屏幕刷新(60HZ,120HZ),每次刷新触发一次requestAnimationFrame回调函数

      //但是requestAnimationFrame的回调函数注册生命只有一次,因此需要循环注册,才能达到一直调用的效果

      window.requestAnimationFrame(renderFun);

    };

    // window.requestAnimationFrame(renderFun);

    renderFun();

    //画布全屏

    window.addEventListener("dblclick", () => {

      if (document.fullscreenElement) {

        document.exitFullscreen();

      } else {

        //document.documentElement.requestFullscreen();

        render.domElement.requestFullscreen();

      }

    });

    //监听画面变化,更新渲染画面,(自适应的大小)

    window.addEventListener("resize", () => {

      //更新摄像机的宽高比

      camera.aspect = window.innerWidth / window.innerHeight;

      //更新摄像机的投影矩阵

      camera.updateProjectionMatrix();

      //更新渲染器宽度和高度

      render.setSize(window.innerWidth, window.innerHeight);

      //设置渲染器的像素比

      render.setPixelRatio(window.devicePixelRatio);

    });

  },

  methods: {},

};

</script>

<style scoped lang="scss">

* {

  margin: 0;

  padding: 0;

}

.home-content {

  position: fixed;

  top: 0;

  right: 20px;

}

.select-item-color {

  width: 50px;

  height: 50px;

  border: 1px solid #ccc;

  margin: 10px;

  display: inline-block;

  cursor: pointer;

  border-radius: 10px;

}

.select {

  display: flex;

}

</style>

效果图: