webgl 用three.js仿soul星球效果

4,893 阅读1分钟

引言

最近有在学 跟月影学可视化,然后就想找个东西练一下手,欢迎大家一起学习。

实现效果

代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>第一个three.js文件_WebGL三维场景</title>
  <style>
    body {
      margin: 0;
      overflow: hidden;
      /* 隐藏body窗口区域滚动条 */
    }
  </style>
  <!--引入three.js三维引擎-->
 
  <script src="https://cdn.bootcdn.net/ajax/libs/three.js/100/three.js"></script>
 
  <script src="./files/OrbitControls.js"></script>
  
</head>

<body>
  <script>
    /**
     * 创建场景对象Scene
     */
    var scene = new THREE.Scene();
   
   
    /**
     * 光源设置
     */
    //点光源
    var point = new THREE.PointLight(0xffffff);
    point.position.set(400, 200, 300); //点光源位置
    //scene.add(point); //点光源添加到场景中
    //环境光
    var ambient = new THREE.AmbientLight(0x444444);
    scene.add(ambient);
    
    /**
     * 相机设置
     */
    var width = window.innerWidth; //窗口宽度
    var height = window.innerHeight; //窗口高度

    camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
		
    camera.position.set(0, 0, 3000);
    function createS (){
      // 将文字放在画布中间
        function makeTextCanvas(text, width, height) {
          var canvas = document.createElement("canvas");
          canvas.width = width;
          canvas.height = height;
          var c = canvas.getContext("2d");
        
          // c.fillStyle = "#FF0000";
          // c.fillRect(0, 0, width, height);
          c.clearRect(0, 0, c.canvas.width, c.canvas.height);
          
          // 文字
          c.beginPath();
          c.translate(width/2,height/2);
          c.fillStyle = "#ffffff"; //文本填充颜色
          c.font = "48px Arial"; //字体样式设置
          c.textBaseline = "middle"; //文本与fillText定义的纵坐标
          c.textAlign = "center"; //文本居中(以fillText定义的横坐标)
          c.fillText(text, 0, 0);
          // document.body.appendChild(canvas)
          return c.canvas;
        }
        var textCanvas = makeTextCanvas("hello", 160, 80);

        
        var texture = new THREE.CanvasTexture(textCanvas);
        texture.generateMipmaps = false;
        texture.minFilter = THREE.LinearFilter;
        texture.magFilter = THREE.LinearFilter;
      
        let pinMaterial = new THREE.SpriteMaterial({
          map: texture,
        
        });
        let mesh= new THREE.Sprite(pinMaterial);

        return mesh
        
    }

    let group = new THREE.Group();
    //var sphere = []
    //var vector = new THREE.Vector3();

    for ( var i = 0, l = 60; i < l; i ++ ) {

      var phi = Math.acos( - 1 + ( 2 * i ) / l );
      var theta = Math.sqrt( l * Math.PI ) * phi;

      var sprite = createS()
      sprite.scale.set(80, 40, 1);
      sprite.position.setFromSphericalCoords( 800, phi, theta )
      
     
      //sphere.push(sprite)
      group.add(sprite);

    }

    scene.add(group);

    /**
     * 创建渲染器对象
     */
    var renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setSize(width, height);//设置渲染区域尺寸
    renderer.shadowMap.enabled = false;
    //renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    renderer.setPixelRatio(window.devicePixelRatio);
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
    //执行渲染操作   指定场景、相机作为参数
    renderer.render(scene, camera);
    var controls = new THREE.OrbitControls(camera,renderer.domElement);
    function render() {
      renderer.render(scene,camera);//执行渲染操作
      group.rotateY(-0.001);//每次绕y轴旋转0.01弧度
      group.rotateX(0.001)
      controls.update()
      
      requestAnimationFrame(render);//请求再次执行渲染函数render
    }
    render();
    
  </script>
</body>
</html>

知识点

1.用到球坐标系 2.精灵平面(Sprite)是一个在3D场景中总是面对着相机的平面。