前言
在vue3中使用threejs画了几个最简单的几何体,自动旋转的立方体,圆柱体,球体,并且加入了光照,几何体影阴部分即光没照到的地方,成果如下,感兴趣的可以看看具体实现过程~
threejs简述
- Three.js是基于原生WebGL封装运行的三维引擎
- 程序结构->场景——相机——渲染器
场景Scene
场景是一个容器,用来放置几何体
相机Camera
相机是用来拍摄的工具,通过控制相机的位置和方向可以获取不同角度的图像。
渲染器Renderer
渲染器利用场景和相机进行渲染,渲染过程好比摄影师拍摄图像,如果只渲染一次就是静态的图像,如果连续渲染就能得到动态的画面。在JS中可以使用requestAnimationFrame实现高效的连续渲染。
[注] 涉及到几何体,材质等具体API没有做很具体的说明,需要可自行查阅CylinderGeometry – three.js中文文档 (webgl3d.cn)
依赖包版本
"vite": "^2.8.0", "three": "^0.138.0", "vue": "^3.2.25"
vue3操作DOM
-threejs底层是对webgl的封装,最终是利用canvas做图形渲染,所以第一步是做操作dom的工作
- 如下,在steup函数中使用ref定义一个响应式常量dom后暴露给template使用,把ref挂载到具体的元素上
- 在initThree中做具体绘制的工作
<template> <div> demo </div> <div class="demo-main" ref="dom"></div> </template> <script lang="ts"> import { defineComponent, onMounted, ref } from "vue"; import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; export default defineComponent({ setup() { const dom = ref<HTMLElement | null>(null); onMounted(() => { initThree(dom.value); }); function initThree(instance: HTMLElement | null) { //dosomething } return { dom }; }, }); </script> <style scoped> .demo-main { height:500px; padding: 9px 14px; margin-bottom: 14px; background-color: #f7f7f9; border: 1px solid #e1e1e8; border-radius: 4px; } </style>
创建场景,相机,渲染器 本节及后续都在initThree方法中写
- 如下我们创建了threejs最基础的一些东西
var hetght = instance.clientHeight - 25; var width = instance.clientWidth - 25; // 创建场景对象Scene var scene = new THREE.Scene(); // 创建相机对象 var camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000); // 创建渲染器对象 var renderer = new THREE.WebGLRenderer(); renderer.setSize(width, hetght); instance.append(renderer.domElement); renderer.render(scene, camera); camera.position.z = 5; renderer.setClearColor(0xeeeeee, 1.0);
立方体
// 立方体网格模型 var cubeGeometry = new THREE.BoxGeometry(1, 1, 1); //材质对象Material //材质决定了几何图形中的表面是如何画的。如果几何图形是骨架,定义了形状,那么材质就是皮肤。three.js 中有许多不同种类的材质,他们拥有不同的属性,像反光,纹理映射,调整透明度。 var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000, opacity: 0.7, transparent: true, }); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); scene.add(cube);
球体
// 球体网格模型 var sphereGeometry = new THREE.SphereGeometry(1, 20, 20); var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0xff00ff, specular: 0x4488ee, shininess: 12, }); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); //网格模型对象Mesh sphere.translateY(120); //球体网格模型沿Y轴正方向平移120 sphere.position.set(0, 0, 5); scene.add(sphere);
圆柱体
// 圆柱网格模型 var cylinderGeometry = new THREE.CylinderGeometry(1, 1, 5, 32); var cylinderMaterial = new THREE.MeshLambertMaterial({ color: 0xffff00, }); var cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial); //网格模型对象Mesh cylinder.position.set(10, 0, 0); //设置cylinder模型对象的xyz坐标为10,0,0 scene.add(cylinder);
坐标系
// 辅助坐标系 参数400表示坐标系大小,可以根据场景大小去设置 var axisHelper = new THREE.AxisHelper(20); scene.add(axisHelper);
点光源
//点光源 var point = new THREE.PointLight(0xffffff); point.position.set(0, 0, 0); scene.add(point); //点光源添加到场景中 // 点光源2 位置和point关于原点对称 var point2 = new THREE.PointLight(0xffffff); point2.position.set(-400, -200, -300); //点光源位置 scene.add(point2); //点光源添加到场景中
鼠标操作旋转,缩放
//鼠标操作旋转、缩放,OrbitControls需要单独引入 new OrbitControls(camera, renderer.domElement);
球体,立方体自动旋转
var animate = function () { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; sphere.rotation.x += 0.01; sphere.rotation.y += 0.01; renderer.render(scene, camera); }; animate();
initThree完整代码
function initThree(instance: HTMLElement | null) { var hetght = instance.clientHeight - 25; var width = instance.clientWidth - 25; // 创建场景对象Scene var scene = new THREE.Scene(); // 创建相机对象 var camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000); // 创建渲染器对象 var renderer = new THREE.WebGLRenderer(); renderer.setSize(width, hetght); instance.append(renderer.domElement); renderer.render(scene, camera); camera.position.z = 5; renderer.setClearColor(0xeeeeee, 1.0); // 立方体网格模型 var cubeGeometry = new THREE.BoxGeometry(1, 1, 1); //材质对象Material var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000, opacity: 0.7, transparent: true, }); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); scene.add(cube); // 球体网格模型 var sphereGeometry = new THREE.SphereGeometry(1, 20, 20); var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0xff00ff, specular: 0x4488ee, shininess: 12, }); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); //网格模型对象Mesh sphere.translateY(120); //球体网格模型沿Y轴正方向平移120 sphere.position.set(0, 0, 5); scene.add(sphere); // 圆柱网格模型 var cylinderGeometry = new THREE.CylinderGeometry(1, 1, 5, 32); var cylinderMaterial = new THREE.MeshLambertMaterial({ color: 0xffff00, }); var cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial); //网格模型对象Mesh cylinder.position.set(10, 0, 0); //设置cylinder模型对象的xyz坐标为10,0,0 scene.add(cylinder); // 辅助坐标系 参数400表示坐标系大小,可以根据场景大小去设置 var axisHelper = new THREE.AxisHelper(20); scene.add(axisHelper); //点光源 var point = new THREE.PointLight(0xffffff); point.position.set(0, 0, 0); scene.add(point); //点光源添加到场景中 // 点光源2 位置和point关于原点对称 var point2 = new THREE.PointLight(0xffffff); point2.position.set(-400, -200, -300); //点光源位置 scene.add(point2); //点光源添加到场景中 //鼠标操作旋转、缩放 new OrbitControls(camera, renderer.domElement); var animate = function () { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; sphere.rotation.x += 0.01; sphere.rotation.y += 0.01; renderer.render(scene, camera); }; animate(); }
总结
到此这篇关于vue3中如何用threejs画一些简单几何体的文章就介绍到这了,更多相关vue3用threejs画几何体内容请搜索阿兔在线工具以前的文章或继续浏览下面的相关文章希望大家以后多多支持阿兔在线工具!