#yyds干货盘点#愚公系列2022年12月 微信小程序-three.js绘制球体

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点#愚公系列2022年12月 微信小程序-three.js绘制球体相关的知识,希望对你有一定的参考价值。

前言

Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。

一个典型的 Three.js 程序至少要包括渲染器(Renderer)、场景(Scene)、照相机(Camera),以及你在场景中创建的物体。

Three.js相关文档:http://docs.thingjs.com/

一、Three.js的使用

安装第三方包:npm i --save threejs-miniprogram

1.球体的绘制

<view style="display:inline-block;">
  <button size="mini" type="primary" class="btn" data-action="Walking" bindtap="play">走</button>
  <button size="mini" type="primary" class="btn"  data-action="WalkJump" bindtap="play">跳</button>
  <button size="mini" type="primary" class="btn"  data-action="Sitting" bindtap="play">坐</button>
  <button size="mini" type="primary" class="btn"  data-action="Standing" bindtap="play">站</button>
</view>
<canvas
  type="webgl"
  id="webgl"
  style="width: 100%; height: 450px;"
  bindtouchstart="touchStart"
  bindtouchmove="touchMove"
  bindtouchend="touchEnd"
></canvas>
import  createScopedThreejs  from threejs-miniprogram

const  renderSphere  = require(../../../lib/test-cases/sphere)

const app = getApp()

Page(
  data: ,
  onLoad: function () 
    wx.createSelectorQuery()
      .select(#webgl)
      .node()
      .exec((res) => 
        const canvas = res[0].node
        this.canvas = canvas
        const THREE = createScopedThreejs(canvas)
        
        renderSphere(canvas, THREE)//球
      )
  ,
  play(e)
    let action = e.currentTarget.dataset.action
    this.fadeToAction(action)
  ,
  touchStart(e) 
    this.canvas.dispatchTouchEvent(...e, type:touchstart)
  ,
  touchMove(e) 
    this.canvas.dispatchTouchEvent(...e, type:touchmove)
  ,
  touchEnd(e) 
    this.canvas.dispatchTouchEvent(...e, type:touchend)
  
)

二、球体相关js文件

export function renderSphere(canvas, THREE) 
  var container, stats;
  var camera, scene, renderer;
  var pointLight;
  var objects = [], materials = [];
  init();
  animate();
  function init() 
    camera = new THREE.PerspectiveCamera(45, canvas.width / canvas.height, 1, 2000);
    camera.position.set(0, 200, 800);
    scene = new THREE.Scene();
    // Grid
    var helper = new THREE.GridHelper(1000, 40, 0x303030, 0x303030);
    helper.position.y = - 75;
    scene.add(helper);
    // Materials
    // var texture = new THREE.Texture(generateTexture());
    // texture.needsUpdate = true;
    // materials.push(new THREE.MeshLambertMaterial( map: texture, transparent: true ));
    materials.push(new THREE.MeshLambertMaterial( color: 0xdddddd ));
    materials.push(new THREE.MeshPhongMaterial( color: 0xdddddd, specular: 0x009900, shininess: 30, flatShading: true ));
    materials.push(new THREE.MeshNormalMaterial());
    materials.push(new THREE.MeshBasicMaterial( color: 0xffaa00, transparent: true, blending: THREE.AdditiveBlending ));
    materials.push(new THREE.MeshLambertMaterial( color: 0xdddddd ));
    materials.push(new THREE.MeshBasicMaterial( color: 0xffaa00, wireframe: true ));
    // materials.push(new THREE.MeshPhongMaterial( color: 0xdddddd, specular: 0x009900, shininess: 30, map: texture, transparent: true ));
    materials.push(new THREE.MeshBasicMaterial( color: 0xffaa00, transparent: true, blending: THREE.AdditiveBlending ));
    materials.push(new THREE.MeshNormalMaterial( flatShading: true ));
    materials.push(new THREE.MeshBasicMaterial( color: 0xffaa00, wireframe: true ));
    materials.push(new THREE.MeshDepthMaterial());
    materials.push(new THREE.MeshLambertMaterial( color: 0x666666, emissive: 0xff0000 ));
    materials.push(new THREE.MeshPhongMaterial( color: 0x000000, specular: 0x666666, emissive: 0xff0000, shininess: 10, opacity: 0.9, transparent: true ));
    materials.push(new THREE.MeshPhongMaterial( color: 0x000000, specular: 0x666666, emissive: 0xff0000, shininess: 10, opacity: 0.9, transparent: true ));
    // materials.push(new THREE.MeshBasicMaterial( map: texture, transparent: true ));
    // Spheres geometry
    var geometry = new THREE.SphereBufferGeometry(70, 32, 16);
    for (var i = 0, l = materials.length; i < l; i++) 
      addMesh(geometry, materials[i]);
    
    // Lights
    scene.add(new THREE.AmbientLight(0x111111));
    var directionalLight = new THREE.DirectionalLight(0xffffff, 0.125);
    directionalLight.position.x = Math.random() - 0.5;
    directionalLight.position.y = Math.random() - 0.5;
    directionalLight.position.z = Math.random() - 0.5;
    directionalLight.position.normalize();
    scene.add(directionalLight);
    pointLight = new THREE.PointLight(0xffffff, 1);
    scene.add(pointLight);
    pointLight.add(new THREE.Mesh(new THREE.SphereBufferGeometry(4, 8, 8), new THREE.MeshBasicMaterial( color: 0xffffff )));
    //
    renderer = new THREE.WebGLRenderer( antialias: true, alpha: true );
    renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
    renderer.setSize(canvas.width ,canvas.height);
  
  function addMesh(geometry, material) 
    var mesh = new THREE.Mesh(geometry, material);
    mesh.position.x = (objects.length % 4) * 200 - 400;
    mesh.position.z = Math.floor(objects.length / 4) * 200 - 200;
    mesh.rotation.x = Math.random() * 200 - 100;
    mesh.rotation.y = Math.random() * 200 - 100;
    mesh.rotation.z = Math.random() * 200 - 100;
    objects.push(mesh);
    scene.add(mesh);
  
  function onWindowResize() 
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  
  function generateTexture() 
    canvas.width = 256;
    canvas.height = 256;
    var context = canvas.getContext(2d);
    var image = context.getImageData(0, 0, 256, 256);
    var x = 0, y = 0;
    for (var i = 0, j = 0, l = image.data.length; i < l; i += 4, j++) 
      x = j % 256;
      y = x == 0 ? y + 1 : y;
      image.data[i] = 255;
      image.data[i + 1] = 255;
      image.data[i + 2] = 255;
      image.data[i + 3] = Math.floor(x ^ y);
    
    context.putImageData(image, 0, 0);
    return canvas;
  
  //
  function animate() 
    render();
    canvas.requestAnimationFrame(animate);
  
  function render() 
    var timer = 0.0005 * Date.now();
    camera.position.x = Math.cos(timer) * 1000;
    camera.position.z = Math.sin(timer) * 1000;
    camera.lookAt(scene.position);
    for (var i = 0, l = objects.length; i < l; i++) 
      var object = objects[i];
      object.rotation.x += 0.01;
      object.rotation.y += 0.005;
    
    // materials[materials.length - 2].emissive.setHSL(0.54, 1, 0.35 * (0.5 + 0.5 * Math.sin(35 * timer)));
    // materials[materials.length - 3].emissive.setHSL(0.04, 1, 0.35 * (0.5 + 0.5 * Math.cos(35 * timer)));
    pointLight.position.x = Math.sin(timer * 7) * 300;
    pointLight.position.y = Math.cos(timer * 5) * 400;
    pointLight.position.z = Math.cos(timer * 3) * 300;
    renderer.render(scene, camera);
  

三、效果图

四、总结

three.js画一个图形主要经历如下八个步骤:

  • 1.创建透视相机
  • 2.创建场景
  • 3.创建光源
  • 4.构造辅助网格
  • 5.创建加载器,加载模型文件
  • 6.创建渲染器,渲染场景
  • 7.创建控制器
  • 8.循环渲染场景

以上是关于#yyds干货盘点#愚公系列2022年12月 微信小程序-three.js绘制球体的主要内容,如果未能解决你的问题,请参考以下文章

#yyds干货盘点#愚公系列2022年12月 微信小程序-WebGL纹理材质的使用

#yyds干货盘点#愚公系列2022年12月 微信小程序-项目篇(公交查询)-06站点查询

#yyds干货盘点#愚公系列2022年12月 微信小程序-three.js绘制球体

#yyds干货盘点#愚公系列2022年12月 微信小程序-WebGL画渐变色正方形

#yyds干货盘点#愚公系列2022年12月 微信小程序-图片加载和全屏适配问题

#yyds干货盘点#愚公系列2022年12月 微信小程序-项目篇(公交查询)-01周边站点