1.先创建一个canvas画布
<div className="earth_digital">
<canvas className="webgl"></canvas>
</div>
2.在useEffect里面获取webgl元素,并创建渲染器对象
const canvas = document.querySelector('.webgl');
// 创建渲染器对象
const renderer = new THREE.WebGLRenderer({
canvas: canvas as HTMLCanvasElement,
antialias: true,
alpha: false,
});
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));//设置设备像素比
3.创建相机、场景、添加镜头轨道控制器
1.创建相机分两种,一种是正投影相机(OrthographicCamera)和透视投影相机(perspectiveCamera)。 透视投影照相机对应投影到的物体的大小是随着距离逐渐变小的,而正投影照相机投影到的物体大小是不受距离影响的,简单来说就是透视投影相机就像我们的眼睛,是近大远小的,正投影相机近远距离的物体都是一样大。
2.perspectiveCamera会有四个参数,fov、aspect、near、far。fov表示摄像机视锥体垂直视野角度,最小值为0,最大值为180,默认值为50,实际项目中一般都定义45,因为45最接近人正常睁眼角度;aspect表示摄像机视锥体长宽比,默认长宽比为1,即表示看到的是正方形,实际项目中使用的是屏幕的宽高比;near表示摄像机视锥体近端面,这个值默认为0.1,实际项目中都会设置为1;far表示摄像机视锥体远端面,默认为2000,这个值可以是无限的,说的简单点就是我们视觉所能看到的最远距离。
3.透视投影相机的位置和position,up,lookAt有关系。position用来指定相机在三维坐标中的位置,up用来指定相机拍摄时相机头顶的方向,lookAt表示相机拍摄时指向的中心点
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.01,
50,
);
camera.position.set(0, 0, 15.5);
// 添加镜头轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enablePan = false;
// 页面缩放监听并重新更新场景和相机
window.addEventListener(
'resize',
() => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
// renderer.setSize(window.innerWidth, window.innerHeight);
},
false,
);
// 页面重绘动画
renderer.setAnimationLoop((_) => {
const earth = new THREE.Mesh();
// TWEEN.update();
earth.rotation.y += 0.001;
renderer.render(scene, camera);
});
let params = {
colors: { base: '#f9f002', gradInner: '#8ae66e', gradOuter: '#03c03c' },
reset: () => {
controls.reset();
},
};
let uniforms = {
impacts: { value: 1 },
// 陆地色块大小
maxSize: { value: 14 },
// 海洋色块大小
minSize: { value: 0.025 },
// 冲击波高度
waveHeight: { value: 0.1 },
// 冲击波范围
scaling: { value: 1 },
// 冲击波径向渐变内侧颜色
gradInner: { value: new THREE.Color(params.colors.gradInner) },
// 冲击波径向渐变外侧颜色
gradOuter: { value: new THREE.Color(params.colors.gradOuter) },
};
3.创建一个球体,把世界地图的平面图贴上就可以了
//贴图
const textureLoader = new THREE.TextureLoader();
const doorColorTexture = textureLoader.load(kxzsqa);
let m = new THREE.MeshBasicMaterial({
map: doorColorTexture,
});
m.onBeforeCompile = (shader) => {
shader.uniforms.impacts = uniforms.impacts;
shader.uniforms.maxSize = uniforms.maxSize;
shader.uniforms.minSize = uniforms.minSize;
shader.uniforms.waveHeight = uniforms.waveHeight;
shader.uniforms.scaling = uniforms.scaling;
shader.uniforms.gradInner = uniforms.gradInner;
shader.uniforms.gradOuter = uniforms.gradOuter;
// shader.uniforms.tex = { value: new THREE.TextureLoader().load(kxzsqa) };
shader.vertexShader = 'uniform float time;\n' + shader.vertexShader;
};
// 创建球体
var globeGgeometry = new THREE.SphereGeometry(4.9995, 100, 100); //创建几何球体
var globeMesh = new THREE.Mesh(globeGgeometry, m); //创建网格模型
var point = new THREE.PointLight(0xffffff); //设置光源
point.rotation.set(0, -0.4, 0);
scene.add(globeMesh);
第一次尝试写threejs,仅供参考,自己只是记录一下按照别人的模版改了改。
参考链接: