三维空间中创建label标签(three.js实战7)
Posted 点燃火柴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三维空间中创建label标签(three.js实战7)相关的知识,希望对你有一定的参考价值。
使用CSS2DRenderer创建文字说明标签
1. demo效果
如上图,demo中使用CSS2DRenderer创建label,在物体运动中始终保持面向相机,缩放中也正常显示
2. CSS2DRenderer使用流程
2.1 相关文件引入
只需要通过script标签引入CSS2DRenderer文件即可
<script type="text/javascript" src="../three/examples/js/renderers/CSS2DRenderer.js"></script>
2.2 创建CSS2DRenderer渲染器
普通的three.js示例中只需要创建WebGLRenderer渲染器来渲染图形,这一次除了创建WebGLRenderer渲染器还需要创建CSS2DRenderer渲染器,创建过程如下:
//创建CSS2DRenderer渲染器
labelRenderer = new THREE.CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
document.getElementById("WebGL-output").appendChild(labelRenderer.domElement);
注意!!! 在使用轨道控制器OrbitControls时,需要将原来绑定在WebGLRenderer的DOM改为绑定在CSS2DRenderer的DOM上,否则轨道控制器无法正常使用
controls = new THREE.OrbitControls(camera, labelRenderer.domElement)
2.3 为Mesh对象添加label
demo分别为地球和月球添加了label,以添加地球的label为例说明一下,首先创建了一个div标签,然后设置该标签的类名、文字、和行内样式。之后使用这个div创建CSS2DObject对象earthLabel,CSS2DObject封装在我们引入的CSS2DRenderer.js中,最后设置earthLabel的位置并添加的Mesh对象earthMesh上
//添加label
const earthDiv = document.createElement('div');
earthDiv.className = 'label';
earthDiv.textContent = '地球';
earthDiv.style.marginTop = '-1em';
earthDiv.style.background = 'none';
const earthLabel = new THREE.CSS2DObject(earthDiv);
earthLabel.position.set(0, earchRadius, 0);
earthMesh.add(earthLabel);
2.4 在render函数中更新CSS2DRenderer对象
与WebGLRenderer一样都需要在render函数中更新,更新方法如下
labelRenderer.render(scene, camera);
3. demo代码
<!DOCTYPE html>
<html>
<head>
<title>Example 07 - CSS2DRenderer-label</title>
<script type="text/javascript" src="../three/build/three.js"></script>
<script type="text/javascript" src="../three/examples/js/controls/OrbitControls.js"></script>
<script type="text/javascript" src="../three/examples/js/renderers/CSS2DRenderer.js"></script>
<script type="text/javascript" src="../three/examples/js/libs/stats.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
.label {
color: #FFF;
font-family: sans-serif;
padding: 2px;
background: rgba(0, 0, 0, .6);
}
</style>
</head>
<body>
<div id="Stats-output"></div>
<div id="WebGL-output"></div>
<script type="text/javascript">
let stats, controls;
let camera, scene, renderer, labelRenderer;
let earthMesh, marsMesh;
function initScene() {
scene = new THREE.Scene();
//用一张图加载为纹理作为场景背景
scene.background = new THREE.TextureLoader().load("../assets/textures/starry-deep-outer-space-galaxy.jpg")
}
function initCamera() {
camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 20000);
camera.position.set(20, 50, 100);
}
function initLight() {
//添加环境光
var ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(25, 30, 50);
spotLight.castShadow = true;
scene.add(spotLight);
}
function initModel() {
createEarthMesh();
createMarshMesh();
}
function createMarshMesh() {
const moonRadius = 4;
var geom = new THREE.SphereGeometry(moonRadius, 40, 40)
var planetTexture = new THREE.TextureLoader().load("../assets/textures/planets/Mars_2k-050104.png");
var normalTexture = new THREE.TextureLoader().load("../assets/textures/planets/Mars-normalmap_2k.png");
var planetMaterial = new THREE.MeshPhongMaterial();
planetMaterial.normalMap = normalTexture;
planetMaterial.map = planetTexture;
// planetMaterial.shininess = 150;
marsMesh = new THREE.Mesh(geom, planetMaterial);
marsMesh.position.set(18, 3, -80)
scene.add(marsMesh)
//添加label
const moonDiv = document.createElement('div');
moonDiv.className = 'label';
moonDiv.textContent = '月球';
moonDiv.style.marginTop = '-1em';
moonDiv.style.background = 'none';
const moonLabel = new THREE.CSS2DObject(moonDiv);
moonLabel.position.set(0, moonRadius, 0);
marsMesh.add(moonLabel);
}
function createEarthMesh() {
const earchRadius = 10
var geom = new THREE.SphereGeometry(earchRadius, 40, 40)
var planetTexture = new THREE.TextureLoader().load("../assets/textures/planets/Earth.png");
var specularTexture = new THREE.TextureLoader().load("../assets/textures/planets/EarthSpec.png");
var normalTexture = new THREE.TextureLoader().load("../assets/textures/planets/EarthNormal.png");
var planetMaterial = new THREE.MeshPhongMaterial();
planetMaterial.specularMap = specularTexture;
planetMaterial.specular = new THREE.Color(0x4444aa);
planetMaterial.normalMap = normalTexture;
planetMaterial.map = planetTexture;
// planetMaterial.shininess = 150;
earthMesh = new THREE.Mesh(geom, planetMaterial);
scene.add(earthMesh);
//添加label
const earthDiv = document.createElement('div');
earthDiv.className = 'label';
earthDiv.textContent = '地球';
earthDiv.style.marginTop = '-1em';
earthDiv.style.background = 'none';
const earthLabel = new THREE.CSS2DObject(earthDiv);
earthLabel.position.set(0, earchRadius, 0);
earthMesh.add(earthLabel);
}
function initRender() {
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
})
//renderer.shadowMap.enabled = true // 显示阴影
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x0f2d48); //设置背景色
renderer.toneMapping = THREE.ACESFilmicToneMapping;
document.getElementById("WebGL-output").appendChild(renderer.domElement);
//创建CSS2DRenderer渲染器
labelRenderer = new THREE.CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
document.getElementById("WebGL-output").appendChild(labelRenderer.domElement);
}
//初始化轨道控制器
function initControls() {
clock = new THREE.Clock() // 创建THREE.Clock对象,用于计算上次调用经过的时间
controls = new THREE.OrbitControls(camera, labelRenderer.domElement)
//controls.autoRotate = true // 是否自动旋转
}
function initStats() {
stats = new Stats();
stats.setMode(0); // 0: fps, 1: ms
document.getElementById("Stats-output").appendChild(stats.domElement);
}
function render() {
updateFun()
requestAnimationFrame(render);
labelRenderer.render(scene, camera);
renderer.render(scene, camera);
}
function updateFun() {
stats.update();
const delta = clock.getDelta() // 获取自上次调用的时间差
controls.update(delta) // 相机更新
earthMesh.rotation.y += 0.02
const elapsed = clock.getElapsedTime();
marsMesh.position.set(Math.sin(elapsed) * 50, 0, Math.cos(elapsed) * 50);
marsMesh.rotation.y += 0.01
}
//初始化
function init() {
initScene();
initCamera();
initLight();
initRender();
initStats();
initControls();
initModel();
render();
}
window.onload = init;
</script>
</body>
</html>
以上是关于三维空间中创建label标签(three.js实战7)的主要内容,如果未能解决你的问题,请参考以下文章