three.js 在 WebGL 绘制旋转的几何体

实现 three.js 内置几何体的创建,并加入几何体旋转动画。包含几何体有:球形网格、二十面体、八面体、四面体、长方形平面、立方体、圆形平面等,这些都是学习 three.js 的基础

为了方便,我将使用 vite 搭建一个原生 js 项目。

1.创建项目

npm create vite@latest three-demo
选:Vanilla
选:JavaScript

2.初始化项目
 cd three-demo
 cnpm install

3.安装 three.js
 cnpm install three@0.160.0 --save

或者 cd three-demo
curl -O https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.min.js

4.编写示例 three_demo_10.html  如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>learn10 (内置几何体)</title>
    <script src="three.min.js"></script>
    <style>
        body {
            margin: 0;
        }

        canvas {
            width: 100%;
            height: 100%;
            display: block;
        }
    </style>
</head>
<body onload='draw()'>
<script>
    var renderer;
    var initRenderer = () => {
      renderer = new THREE.WebGLRenderer({antialias: true})
      renderer.setSize(window.innerWidth, window.innerHeight)
      // 设置背景色
      renderer.setClearColor(0x000000, 1.0)
      // 物理像素/css像素, 比值越大越清晰
      renderer.setPixelRatio(window.devicePixelRatio)
      document.body.appendChild(renderer.domElement)
    }

    var camera;
    var initCamera = () => {
      camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 )
      camera.position.y = 400
    }

    var scene;
    var initScene = () => {
      scene = new THREE.Scene()
    }

    var light;
    var initLight = () => {
      if (scene) {
        // 添加环境光
        scene.add(new THREE.AmbientLight(0x404040))
      }

      var light = new THREE.DirectionalLight(0xffffff)
      light.position.set(0, 1, 0)
      scene.add(light)
    }

    var initModel = () => {
      // D:\three.js-r160\examples\textures\uv_grid_directx.jpg
      var texture = new THREE.TextureLoader().load('./imgs/uv_grid_opengl.jpg');
      //定义纹理在水平和垂直方向简单的重复到无穷大。
      //map.wrapS = map.wrapT = THREE.RepeatWrapping
      //定义纹理的各向异性
      //map.anisotropy = 16

      //定义兰伯特网孔材质
      var material = new THREE.MeshLambertMaterial({map:texture, side:THREE.DoubleSide})

      //球形网格 (半径长度,水平块的密度,垂直块的密度)
      object = new THREE.Mesh(new THREE.SphereGeometry(75,20,10), material)
      object.position.set( -400, 0, 200 )
      scene.add(object)

      //二十面体 (图形大小半径,大于零将不是二十面体,越大越圆滑)
      object = new THREE.Mesh(new THREE.IcosahedronGeometry(75, 0), material)
      object.position.set(-200, 0, 200)
      scene.add(object)

      //八面体(图形大小半径,大于零将不是八面体,越大越圆滑)
      object = new THREE.Mesh(new THREE.OctahedronGeometry(75, 0), material)
      object.position.set(0, 0, 200)
      scene.add(object)

      //四面体(图形大小半径,大于零将不是四面体,越大越圆滑)
      object = new THREE.Mesh( new THREE.TetrahedronGeometry(75, 0 ), material );
      object.position.set( 200, 0, 200 );
      scene.add(object)

      //长方形平面 (x轴宽度,y轴高度,x方向分段数,y方向分段数)
      object = new THREE.Mesh( new THREE.PlaneGeometry( 100, 100, 1, 1 ), material )
      object.position.set( -400, 0, 0 )
      scene.add( object )

      //立方体 (x轴宽度,y轴高度,z轴深度,沿宽面分段数,沿高度面分段数,沿深度面分段数)
      object = new THREE.Mesh( new THREE.BoxGeometry( 100, 100, 100, 1, 1, 1 ), material )
      object.position.set( -200, 0, 0 )
      scene.add(object)

      //圆形平面 (半径,顶点密度,绘制起点弧度,绘制弧度)
      object = new THREE.Mesh( new THREE.CircleGeometry( 50, 20, 0, Math.PI * 2 ), material )
      object.position.set( 0, 0, 0 )
      scene.add(object)

      // 空心圆平面(内圆半径,外圆半径,分割面越大越圆滑,垂直外边分割面,开始绘制弧度,绘制弧度)
      object = new THREE.Mesh(new THREE.RingGeometry(10, 50, 10, 5, 0, Math.PI * 2 ), material)
      object.position.set( 200, 0, 0 )
      scene.add(object)

      // 圆柱体(头部圆的半径,底部圆半径,高度,上下圆顶点个数,上下面切割线条数,上下面是否显示,开始弧度,绘制弧度)
      object = new THREE.Mesh(new THREE.CylinderGeometry(25, 25, 100, 40, 5), material)
      object.position.set( 400, 0, 0 )
      scene.add(object)

      // 车床模型
      var points = []

      for ( var i = 0; i < 50; i ++ ) {
        points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * Math.sin( i * 0.1 ) * 15 + 50, ( i - 5 ) * 2 ) );
      }

      //(一个vector2的数组分别代表xy轴,生成圆周段的数目,开始弧度,绘制弧度)
      object = new THREE.Mesh(new THREE.LatheGeometry( points, 20 ), material )
      object.position.set( -400, 0, -200 )
      scene.add(object)

      // 救生圈 (救生圈半径,管道直径,基于管道横切顶点数,救生圈横切顶点个数, 越大越圆)
      object = new THREE.Mesh(new THREE.TorusGeometry(50, 20, 20, 20), material)
      object.position.set(-200, 0, -200)
      scene.add(object)

      // 环形扭结模型(图形半径,管道直径,基于管道横切定点数,根据图形半径横切顶点数,绕旋转对称轴的圈数,绕环面的圆的圈数)
      object = new THREE.Mesh(new THREE.TorusKnotGeometry(50, 10, 50, 20), material)
      object.position.set(0, 0, -200)
      scene.add( object )

      // 轴辅助 (每个轴的长度,红线是X轴,绿线是Y轴,蓝线是Z轴)
      object = new THREE.AxesHelper(50)
      object.position.set(200, 0, -200)
      scene.add(object)

      // 箭头辅助(箭头头的方向必须是vecteor3,箭头起点必须是vector3,箭头长度,颜色)
      object = new THREE.ArrowHelper(new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 0 ), 50 ,0x00ffff)
      object.position.set(400, 0, -200)
      scene.add(object)
    }

    var render = () => {
      var timer = Date.now() * 0.0001
      camera.position.x = Math.cos( timer ) * 800
      camera.position.z = Math.sin( timer ) * 800

      camera.lookAt( scene.position )
      for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
        var object = scene.children[ i ];
        object.rotation.x = timer * 5
        object.rotation.y = timer * 2.5
      }
      renderer.render( scene, camera )
    }

    var  animate = () =>  {
      requestAnimationFrame(animate)
      render()
    }

    var onWindowResize = () => {
      camera.aspect = window.innerWidth/window.innerHeight
      camera.updateProjectionMatrix()
      renderer.setSize(window.innerWidth, window.innerHeight)
    }

    //绘制
    function draw() {
      initRenderer()
      initCamera()
      initScene()
      initLight()
      initModel()

      animate()
      // 窗口变动自适应
      window.addEventListener( 'resize', onWindowResize, false )
    }
</script>
</body>
</html>

5.运行 npm run dev 
访问 http://localhost:5173/three_demo_10.html 

从 百度网盘 请输入提取码 下载 three.js-r160.zip  解压到 D:\ 

参考:学习threejs,创建内置几何体,并加入旋转动画

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值