共计 3061 个字符,预计需要花费 8 分钟才能阅读完成。
简介
做展现类我的项目的时候,通常要实现一些圆形抉择的成果。这个借助 css
的rotate
就能够实现. 然而!要实现一个 3D
的带图片的旋转球体该怎么做呢?让咱们开始吧。
残缺代码 codesandbox
残缺代码 gitee
预览地址
备用预览地址
工具
three.js
OrbitControls
绘制
创立一个场景
将场景借助 three.js 来进行显示,咱们须要以下几个对象:场景、相机和渲染器,这样咱们就能透过摄像机渲染出场景。
let camera, scene, renderer;
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera(
10,
window.innerWidth / window.innerHeight,
0.1,
200
);
camera.position.set(30, 5, 20);
//renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
咱们花一点点工夫来解释一下这里产生了什么。咱们当初建设了场景、相机和渲染器。
three.js 里有几种不同的相机,在这里,咱们应用的是PerspectiveCamera
(透视摄像机)。
第一个参数是视线角度(FOV)。视线角度就是无论在什么时候,你所能在显示器上看到的场景的范畴,数值越大越远。
第二个参数是长宽比(aspect ratio)。也就是你用一个物体的宽除以它的高的值。比如说,当你在一个宽屏电视上播放老电影时,能够看到图像好像是被压扁的。
接下来的两个参数是近截面(near)和远截面(far)。当物体某些局部比摄像机的远截面远或者比近截面近的时候,该这些局部将不会被渲染到场景中。或者当初你不必放心这个值的影响,但将来为了取得更好的渲染性能,你将能够在你的应用程序里去设置它。
接下来是渲染器。这里是施展魔法的中央。除了咱们在这里用到的 WebGLRenderer
渲染器之外,Three.js
同时提供了其余几种渲染器,当用户所应用的浏览器过于老旧,或者因为其余起因不反对 WebGL
时,能够应用这几种渲染器进行降级。
除了创立一个渲染器的实例之外,咱们还须要在咱们的应用程序里设置一个渲染器的尺寸。比如说,咱们能够应用所须要的渲染区域的宽高,来让渲染器渲染出的场景填充斥咱们的应用程序。因而,咱们能够将渲染器宽高设置为浏览器窗口宽高。对于性能比拟敏感的应用程序来说,你能够应用 setSize
传入一个较小的值,例如 window.innerWidth/2
和window.innerHeight/2
,这将使得应用程序在渲染时,以一半的长宽尺寸渲染场景。
如果你心愿放弃你的应用程序的尺寸,然而以较低的分辨率来渲染,你能够在调用 setSize
时,将 updateStyle
(第三个参数)设为false
。例如,假如你的<canvas>
标签当初曾经具备了 100% 的宽和高,调用setSize(window.innerWidth/2, window.innerHeight/2, false)
将使得你的应用程序以一半的分辨率来进行渲染。
最初一步很重要,咱们将 renderer
(渲染器)的dom
元素(renderer.domElement)增加到咱们的 HTML
文档中。这就是渲染器用来显示场景给咱们看的 <canvas>
元素。
“嗯,看起来很不错,那你说的那个球体在哪儿?”接下来,咱们就来增加球体。
创立球体
let earth;
const earthGeometry = new THREE.SphereGeometry(2, 16, 16);
const earthMaterial = new THREE.MeshBasicMaterial({
specular: 0x333333,
shininess: 5,
map: textureLoader.load("./img/earth_atmos_2048.jpg"),
specularMap: textureLoader.load("./img/earth_specular_2048.jpg"),
normalMap: textureLoader.load("./img/earth_normal_2048.jpg"),
normalScale: new THREE.Vector2(0.85, 0.85),
});
earth = new THREE.Mesh(earthGeometry, earthMaterial);
scene.add(earth);
// controls
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.minDistance = 5;
controls.maxDistance = 100;
controls.enablePan = false;
要创立一个球体,咱们须要一个 SphereGeometry(球缓冲几何体)对象. 这个对象该几何体是通过扫描并计算围绕着 Y 轴(程度扫描)和 X 轴(垂直扫描)的顶点来创立的
接下来,对于这个球体,咱们须要给它一个材质,并退出图片。Three.js 自带了几种材质,在这里咱们应用的是 MeshBasicMaterial。如果须要一些光照和物理材质能够应用 MeshPhysicalMaterial
第三步,咱们须要一个 Mesh(网格)。网格蕴含一个几何体以及作用在此几何体上的材质,咱们能够间接将网格对象放入到咱们的场景中,并让它在场景中自在挪动。
第四步,退出控制器,以便咱们能够拖动抉择球体
渲染场景
当初,如果将之前写好的代码复制到 HTML 文件中,你不会在页面中看到任何货色。这是因为咱们还没有对它进行真正的渲染。为此,咱们须要应用一个被叫做“渲染循环”(render loop)或者“动画循环”(animate loop)的货色
function animate() {requestAnimationFrame(animate);
renderer.render(scene, camera);
}
使球体动起来
在开始之前,如果你曾经将下面的代码写入到了你所创立的文件中,你能够看到一个地球。让咱们来做一些更加乏味的事 —— 让它旋转起来。
将下列代码增加到 animate()
函数中 renderer.render
调用的上方:
earth.rotation.x += 0.001;
earth.rotation.y += 0.001;
这段代码每帧都会执行(失常状况下是 60 次 / 秒),这就让球体有了一个看起来很不错的旋转动画。基本上来说,当利用程序运行时,如果你想要挪动或者扭转任何场景中的货色,都必须要通过这个动画循环。当然,你能够在这个动画循环里调用别的函数,这样你就不会写出有上百行代码的 animate 函数。
退出背景图像
// 加载背景纹理
var texture = textureLoader.load("./img/eQ9y7xBeY4.jpg");
scene.background = texture;
这样咱们就实现了一个基于图片笼罩的旋转球体
残缺代码 codesandbox
残缺代码 gitee
预览地址
备用预览地址