背景
虎年 🐅
春节将至,本文使用 React
+ Three.js
技术栈,实现趣味 3D
创意页面。本文包含的知识点主要包括:ShadowMaterial
、 MeshPhongMaterial
两种基本材质的使用、使用 LoadingManager
展示模型加载进度、OrbitControls
的缓动动画、TWEEN
简单补间动画效果等。
实现
👀
在线预览,已适配移动端:dragonir's
引入资源
其中 GLTFLoader
、FBXLoader
用于加在模型、OrbitControls
用户镜头轨道控制、TWEEN
用于生成补间动画。
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";
场景初始化
这部分内容主要用于初始化场景和参数,详细讲解可点击文章末尾链接阅读我之前的文章,本文不再赘述。
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
// 场景
scene = new THREE.Scene();
scene.background = new THREE.TextureLoader().load(bgTexture);
// 雾化效果
scene.fog = new THREE.Fog(0xdddddd, 100, 120);
// 摄像机
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(100, 100, 100);
camera.lookAt(new THREE.Vector3(0, 0, 0));
// 平行光
const cube = new THREE.Mesh(new THREE.BoxGeometry(0.001, 0.001, 0.001), new THREE.MeshLambertMaterial({ color: 0xdc161a }));
cube.position.set(0, 0, 0);
light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(20, 20, 8);
light.target = cube;
scene.add(light);
// 环境光
const ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);
// 聚光灯
const spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-20, 20, -2);
scene.add(spotLight);
💡
Fog 场景雾化
本例中,打开页面时模型由远及近加载,颜色由白色变为彩色的功能就是通过 Fog
实现的。Fog
类定义的是线性雾,雾的密度是随着距离线性增大的,即场景中物体雾化效果随着随距离线性变化。
构造函数:Fog(color, near, far)
。
color
属性: 表示雾的颜色,比如设置为红色,场景中远处物体为黑色,场景中最近处距离物体是自身颜色,最远和最近之间的物体颜色是物体本身颜色和雾颜色的混合效果。near
属性:表示应用雾化效果的最小距离,距离活动摄像机长度小于near
的物体将不会被雾所影响。far
属性:表示应用雾化效果的最大距离,距离活动摄像机长度大于far
的物体将不会被雾所影响。
创建地面
本例中使用了背景图,我需要一个既能呈现透明显示背景、又能产生阴影的材质生成地面,于是使用到 ShadowMaterial
材质。
var planeGeometry = new THREE.PlaneGeometry(100, 100);
var planeMaterial = new THREE.ShadowMater