首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Three.js基础

Three.js基础

作者头像
小刀c
发布于 2024-04-03 00:24:31
发布于 2024-04-03 00:24:31
48600
代码可运行
举报
文章被收录于专栏:cc logcc log
运行总次数:0
代码可运行

Intro

场景

场景基础

场景中显示东西,必要组件:

组件

说明

摄像机

决定屏幕上哪些东西需要渲染

光源

决定材质如何显示以及用于产生阴影

对象

摄像机透视图中主要的渲染兑现,如方块、球体

渲染器

webGL,webGPU等

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function init() {

    var stats = initStats();

    // create a scene, that will hold all our elements such as objects, cameras and lights.
    var scene = new THREE.Scene();

    // create a camera, which defines where we're looking at.
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);

    // create a render and set the size
    var renderer = new THREE.WebGLRenderer();

    renderer.setClearColor(new THREE.Color(0x000000));
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;

    // create the ground plane
    var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
    var planeMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.receiveShadow = true;

    // rotate and position the plane
    plane.rotation.x = -0.5 * Math.PI;
    plane.position.x = 0;
    plane.position.y = 0;
    plane.position.z = 0;

    // add the plane to the scene
    scene.add(plane);

    // position and point the camera to the center of the scene
    camera.position.x = -30;
    camera.position.y = 40;
    camera.position.z = 30;
    camera.lookAt(scene.position);

    // add subtle ambient lighting
    var ambientLight = new THREE.AmbientLight(0x3c3c3c);
    scene.add(ambientLight);

    // add spotlight for the shadows
    var spotLight = new THREE.SpotLight(0xffffff, 1.2, 150, 120);
    spotLight.position.set(-40, 60, -10);
    spotLight.castShadow = true;
    scene.add(spotLight);

    // add the output of the renderer to the html element
    document.getElementById("webgl-output").appendChild(renderer.domElement);

    // call the render function
    var step = 0;

    var controls = new function () {
        this.rotationSpeed = 0.02;
        this.numberOfObjects = scene.children.length;

        this.removeCube = function () {
            var allChildren = scene.children;
            var lastObject = allChildren[allChildren.length - 1];
            if (lastObject instanceof THREE.Mesh) {
                scene.remove(lastObject);
                this.numberOfObjects = scene.children.length;
            }
        };

        this.addCube = function () {

            var cubeSize = Math.ceil((Math.random() * 3));
            var cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
            var cubeMaterial = new THREE.MeshLambertMaterial({
                color: Math.random() * 0xffffff
            });
            var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
            cube.castShadow = true;
            cube.name = "cube-" + scene.children.length;


            // position the cube randomly in the scene

            cube.position.x = -30 + Math.round((Math.random() * planeGeometry.parameters.width));
            cube.position.y = Math.round((Math.random() * 5));
            cube.position.z = -20 + Math.round((Math.random() * planeGeometry.parameters.height));

            // add the cube to the scene
            scene.add(cube);
            this.numberOfObjects = scene.children.length;
        };

        this.outputObjects = function () {
            console.log(scene.children);
        }
    };

    var gui = new dat.GUI();
    gui.add(controls, 'rotationSpeed', 0, 0.5);
    gui.add(controls, 'addCube');
    gui.add(controls, 'removeCube');
    gui.add(controls, 'outputObjects');
    gui.add(controls, 'numberOfObjects').listen();

    // attach them here, since appendChild needs to be called first
    var trackballControls = initTrackballControls(camera, renderer);
    var clock = new THREE.Clock();

    render();
    
    function render() {

        trackballControls.update(clock.getDelta());
        stats.update();

        // rotate the cubes around its axes
        scene.traverse(function (e) {
            if (e instanceof THREE.Mesh && e != plane) {
                e.rotation.x += controls.rotationSpeed;
                e.rotation.y += controls.rotationSpeed;
                e.rotation.z += controls.rotationSpeed;
            }
        });

        // render using requestAnimationFrame
        requestAnimationFrame(render);
        renderer.render(scene, camera);
    }
}
  • scene.add 场景中添加对象
  • scene.remote 场景中移除对象
  • scene.children 获取场景中对象
  • scene.getObjectByName 根据name获取场景中对象。
  • scene.traverse 传入回调函数,便利场景中每个对象。

场景雾化效果

show code

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function init() {

    var stats = initStats();

    // create a scene, that will hold all our elements such as objects, cameras and lights.
    var scene = new THREE.Scene();
    // scene.fog = new THREE.FogExp2(0xffffff, 0.015);
    scene.fog = new THREE.Fog(0xffffff, 10, 100);

    // create a camera, which defines where we're looking at.
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

    // create a render and set the size
    var renderer = new THREE.WebGLRenderer();

    renderer.setClearColor(new THREE.Color(0x000000));
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;

    // create the ground plane
    var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
    var planeMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.receiveShadow = true;

    // rotate and position the plane
    plane.rotation.x = -0.5 * Math.PI;
    plane.position.x = 0;
    plane.position.y = 0;
    plane.position.z = 0;

    // add the plane to the scene
    scene.add(plane);

    // position and point the camera to the center of the scene
    camera.position.x = -40;
    camera.position.y = 20;
    camera.position.z = 40;
    camera.lookAt(scene.position);

    // add subtle ambient lighting
    var ambientLight = new THREE.AmbientLight(0x0c0c0c);
    scene.add(ambientLight);

    // add spotlight for the shadows
    var spotLight = new THREE.SpotLight(0xffffff, 1, 150, 120);
    spotLight.position.set(-40, 60, -10);
    spotLight.castShadow = true;
    scene.add(spotLight);

    // add the output of the renderer to the html element
    document.getElementById("webgl-output").appendChild(renderer.domElement);

    // call the render function
    var step = 0;

    var controls = new function () {
        this.rotationSpeed = 0.02;
        this.numberOfObjects = scene.children.length;

        this.removeCube = function () {
            var allChildren = scene.children;
            var lastObject = allChildren[allChildren.length - 1];
            if (lastObject instanceof THREE.Mesh) {
                scene.remove(lastObject);
                this.numberOfObjects = scene.children.length;
            }
        };

        this.addCube = function () {

            var cubeSize = Math.ceil((Math.random() * 3));
            var cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
            var cubeMaterial = new THREE.MeshLambertMaterial({
                color: 0xFF0000
            });
            var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
            cube.castShadow = true;

            // position the cube randomly in the scene
            cube.position.x = -30 + Math.round((Math.random() * planeGeometry.parameters.width));
            cube.position.y = Math.round((Math.random() * 5));
            cube.position.z = -20 + Math.round((Math.random() * planeGeometry.parameters.height));

            // add the cube to the scene
            scene.add(cube);
            this.numberOfObjects = scene.children.length;
        };

        this.outputObjects = function () {
            console.log(scene.children);
        }
    };

    var gui = new dat.GUI();
    gui.add(controls, 'rotationSpeed', 0, 0.5);
    gui.add(controls, 'addCube');
    gui.add(controls, 'removeCube');
    gui.add(controls, 'outputObjects');
    gui.add(controls, 'numberOfObjects').listen();

    var trackballControls = initTrackballControls(camera, renderer);
    var clock = new THREE.Clock();

    render();

    function render() {

        trackballControls.update(clock.getDelta());
        stats.update();

        // rotate the cubes around its axes
        scene.traverse(function (e) {
            if (e instanceof THREE.Mesh && e != plane) {

                e.rotation.x += controls.rotationSpeed;
                e.rotation.y += controls.rotationSpeed;
                e.rotation.z += controls.rotationSpeed;
            }
        });

        // render using requestAnimationFrame
        requestAnimationFrame(render);
        renderer.render(scene, camera);
    }
}
  • screne.fog = new THREE.For(0xffffff, 0.015, 100),第二个参数是near(近处)属性,第三个是far(远处)属性。 雾的浓度线性增长。
  • screne.fog = new THREE.For(0xffffff, 0.01) 只设置颜色和浓度,浓度随距离指数增长。

场景overrideMaterial属性

通过scene.overrideMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });来强制设置场景中对象的材质,极端情况可以做性能优化。

show code

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function init() {

    var stats = initStats();

    // create a scene, that will hold all our elements such as objects, cameras and lights.
    var scene = new THREE.Scene();
    scene.overrideMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });

    // create a camera, which defines where we're looking at.
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

    // create a render and set the size
    var renderer = new THREE.WebGLRenderer();

    renderer.setClearColor(new THREE.Color(0x000000));
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;

    // create the ground plane
    var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
    var planeMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.receiveShadow = true;

    // rotate and position the plane
    plane.rotation.x = -0.5 * Math.PI;
    plane.position.x = 0;
    plane.position.y = 0;
    plane.position.z = 0;

    // add the plane to the scene
    scene.add(plane);

    // position and point the camera to the center of the scene
    camera.position.x = -30;
    camera.position.y = 40;
    camera.position.z = 30;
    camera.lookAt(scene.position);

    // add subtle ambient lighting
    var ambientLight = new THREE.AmbientLight(0x0c0c0c);
    scene.add(ambientLight);

    // add spotlight for the shadows
    var spotLight = new THREE.SpotLight(0xffffff, 1, 150, 120);
    spotLight.position.set(-40, 60, -10);
    spotLight.castShadow = true;
    scene.add(spotLight);

    // add the output of the renderer to the html element
    document.getElementById("webgl-output").appendChild(renderer.domElement);

    // call the render function
    var step = 0;

    var controls = new function () {
        this.rotationSpeed = 0.02;
        this.numberOfObjects = scene.children.length;

        this.removeCube = function () {
            var allChildren = scene.children;
            var lastObject = allChildren[allChildren.length - 1];
            if (lastObject instanceof THREE.Mesh) {
                scene.remove(lastObject);
                this.numberOfObjects = scene.children.length;
            }
        };

        this.addCube = function () {

            var cubeSize = Math.ceil((Math.random() * 3));
            var cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
            var cubeMaterial = new THREE.MeshLambertMaterial({
                color: Math.random() * 0xffffff
            });
            var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
            cube.castShadow = true;

            // position the cube randomly in the scene
            cube.position.x = -30 + Math.round((Math.random() * planeGeometry.parameters.width));
            cube.position.y = Math.round((Math.random() * 5));
            cube.position.z = -20 + Math.round((Math.random() * planeGeometry.parameters.height));

            // add the cube to the scene
            scene.add(cube);
            this.numberOfObjects = scene.children.length;
        };

        this.outputObjects = function () {
            console.log(scene.children);
        }
    };

    var gui = new dat.GUI();
    gui.add(controls, 'rotationSpeed', 0, 0.5);
    gui.add(controls, 'addCube');
    gui.add(controls, 'removeCube');
    gui.add(controls, 'outputObjects');
    gui.add(controls, 'numberOfObjects').listen();

    var trackballControls = initTrackballControls(camera, renderer);
    var clock = new THREE.Clock();

    render();

    function render() {

        trackballControls.update(clock.getDelta());
        stats.update();

        // rotate the cubes around its axes
        scene.traverse(function (e) {
            if (e instanceof THREE.Mesh && e != plane) {

                e.rotation.x += controls.rotationSpeed;
                e.rotation.y += controls.rotationSpeed;
                e.rotation.z += controls.rotationSpeed;
            }
        });

        // render using requestAnimationFrame
        requestAnimationFrame(render);
        renderer.render(scene, camera);
    }
}

几何体和网格(mesh)

创建对象的经典步骤,形状,材质,mesh。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
var planeMaterial = new THREE.MeshLambertMaterial({
		color: 0xffffff
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);

threejs中可用几何体

show code

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function init() {

    var stats = initStats();

    // create a scene, that will hold all our elements such as objects, cameras and lights.
    var scene = new THREE.Scene();

    // create a camera, which defines where we're looking at.
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

    // create a render and set the size
    var renderer = new THREE.WebGLRenderer();

    renderer.setClearColor(new THREE.Color(0x000000));
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;

    // create the ground plane
    var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
    var planeMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.receiveShadow = true;

    // rotate and position the plane
    plane.rotation.x = -0.5 * Math.PI;
    plane.position.x = 0;
    plane.position.y = 0;
    plane.position.z = 0;

    // add the plane to the scene
    scene.add(plane);

    // position and point the camera to the center of the scene
    camera.position.x = -50;
    camera.position.y = 30;
    camera.position.z = 20;
    camera.lookAt(new THREE.Vector3(-10, 0, 0));

    // add subtle ambient lighting
    var ambientLight = new THREE.AmbientLight(0x555555);
    scene.add(ambientLight);

    // add spotlight for the shadows
    var spotLight = new THREE.SpotLight(0xffffff, 1.2, 150, Math.PI / 4, 0, 2);
    spotLight.shadow.mapSize.height = 1024;
    spotLight.shadow.mapSize.width = 1024;
    spotLight.position.set(-40, 30, 30);
    spotLight.castShadow = true;
    scene.add(spotLight);

    // add geometries
    addGeometries(scene);

    // add the output of the renderer to the html element
    document.getElementById("webgl-output").appendChild(renderer.domElement);

    // call the render function
    var step = 0;


    function addGeometries(scene) {
        var geoms = [];

        geoms.push(new THREE.CylinderGeometry(1, 4, 4));

        // basic cube
        geoms.push(new THREE.BoxGeometry(2, 2, 2));

        // basic spherer
        geoms.push(new THREE.SphereGeometry(2));

        geoms.push(new THREE.IcosahedronGeometry(4));

        // create a convex shape (a shape without dents)
        // using a couple of points
        // for instance a cube
        var points = [
            new THREE.Vector3(2, 2, 2),
            new THREE.Vector3(2, 2, -2),
            new THREE.Vector3(-2, 2, -2),
            new THREE.Vector3(-2, 2, 2),
            new THREE.Vector3(2, -2, 2),
            new THREE.Vector3(2, -2, -2),
            new THREE.Vector3(-2, -2, -2),
            new THREE.Vector3(-2, -2, 2)
        ];
        geoms.push(new THREE.ConvexGeometry(points));

        // create a lathgeometry
        //http://en.wikipedia.org/wiki/Lathe_(graphics)
        var pts = []; //points array - the path profile points will be stored here
        var detail = .1; //half-circle detail - how many angle increments will be used to generate points
        var radius = 3; //radius for half_sphere
        for (var angle = 0.0; angle < Math.PI; angle += detail) //loop from 0.0 radians to PI (0 - 180 degrees)
            pts.push(new THREE.Vector3(Math.cos(angle) * radius, 0, Math.sin(angle) * radius)); //angle/radius to x,z
        geoms.push(new THREE.LatheGeometry(pts, 12));

        // create a OctahedronGeometry
        geoms.push(new THREE.OctahedronGeometry(3));

        // create a geometry based on a function
        geoms.push(new THREE.ParametricGeometry(THREE.ParametricGeometries.mobius3d, 20, 10));

        //
        geoms.push(new THREE.TetrahedronGeometry(3));

        geoms.push(new THREE.TorusGeometry(3, 1, 10, 10));

        geoms.push(new THREE.TorusKnotGeometry(3, 0.5, 50, 20));

        var j = 0;
        for (var i = 0; i < geoms.length; i++) {
            var cubeMaterial = new THREE.MeshLambertMaterial({
                wireframe: true,
                color: Math.random() * 0xffffff
            });

            var materials = [

                new THREE.MeshLambertMaterial({
                    color: Math.random() * 0xffffff
                }),
                new THREE.MeshBasicMaterial({
                    color: 0x000000,
                    wireframe: true
                })

            ];

            var mesh = THREE.SceneUtils.createMultiMaterialObject(geoms[i], materials);
            mesh.traverse(function (e) {
                e.castShadow = true
            });

            //var mesh = new THREE.Mesh(geoms[i],materials[i]);
            //mesh.castShadow=true;
            mesh.position.x = -24 + ((i % 4) * 12);
            mesh.position.y = 4;
            mesh.position.z = -8 + (j * 12);

            if ((i + 1) % 4 == 0) j++;
            scene.add(mesh);
        }

    }

    
    var trackballControls = initTrackballControls(camera, renderer);
    var clock = new THREE.Clock();

    render();

    function render() {
        trackballControls.update(clock.getDelta());
        stats.update();

        // render using requestAnimationFrame
        requestAnimationFrame(render);
        renderer.render(scene, camera);
    }
}

创建几何体

  • 顶点和面就组合成了几何体
  • three.js也建议使用三角形定义一个面
  • 注意创建面的顶点数据
    • 顺时针——面向摄像机的面
    • 逆时针——背向摄像机的面

show code

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function init() {

  var stats = initStats();

  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  // create a camera, which defines where we're looking at.
  var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

  // create a render and set the size
  var renderer = new THREE.WebGLRenderer();

  renderer.setClearColor(new THREE.Color(0x000000));
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.shadowMap.enabled = true;

  // create the ground plane
  var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
  var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
  var plane = new THREE.Mesh(planeGeometry, planeMaterial);
  plane.receiveShadow = true;

  // rotate and position the plane
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 0;
  plane.position.y = 0;
  plane.position.z = 0;

  // add the plane to the scene
  scene.add(plane);

  // position and point the camera to the center of the scene
  camera.position.x = -20;
  camera.position.y = 25;
  camera.position.z = 20;
  camera.lookAt(new THREE.Vector3(5, 0, 0));

  // add subtle ambient lighting
  var ambientLight = new THREE.AmbientLight(0x494949);
  scene.add(ambientLight);

  // add the output of the renderer to the html element
  document.getElementById("webgl-output").appendChild(renderer.domElement);

  // call the render function
  var step = 0;


  var vertices = [
      new THREE.Vector3(1, 3, 1),
      new THREE.Vector3(1, 3, -1),
      new THREE.Vector3(1, -1, 1),
      new THREE.Vector3(1, -1, -1),
      new THREE.Vector3(-1, 3, -1),
      new THREE.Vector3(-1, 3, 1),
      new THREE.Vector3(-1, -1, -1),
      new THREE.Vector3(-1, -1, 1)
  ];

  var faces = [
      new THREE.Face3(0, 2, 1),
      new THREE.Face3(2, 3, 1),
      new THREE.Face3(4, 6, 5),
      new THREE.Face3(6, 7, 5),
      new THREE.Face3(4, 5, 1),
      new THREE.Face3(5, 0, 1),
      new THREE.Face3(7, 6, 2),
      new THREE.Face3(6, 3, 2),
      new THREE.Face3(5, 7, 0),
      new THREE.Face3(7, 2, 0),
      new THREE.Face3(1, 3, 4),
      new THREE.Face3(3, 6, 4),
  ];

  var geom = new THREE.Geometry();
  geom.vertices = vertices;
  geom.faces = faces;
  geom.computeFaceNormals();

  var materials = [
    new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true}),
    new THREE.MeshLambertMaterial({opacity: 0.6, color: 0x44ff44, transparent: true})
  ];

  var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, materials);
  mesh.castShadow = true;
  mesh.children.forEach(function (e) {
      e.castShadow = true
  });

  scene.add(mesh);

  // add spotlight for the shadows
  var spotLight = new THREE.SpotLight(0xffffff, 1, 180, Math.PI/4);
  spotLight.shadow.mapSize.height = 2048;
  spotLight.shadow.mapSize.width = 2048;
  spotLight.position.set(-40, 30, 30);
  spotLight.castShadow = true;
  spotLight.lookAt(mesh);
  scene.add(spotLight);

  function addControl(x, y, z) {
      var controls = new function () {
          this.x = x;
          this.y = y;
          this.z = z;
      };

      return controls;
  }

  var controlPoints = [];
  controlPoints.push(addControl(3, 5, 3));
  controlPoints.push(addControl(3, 5, 0));
  controlPoints.push(addControl(3, 0, 3));
  controlPoints.push(addControl(3, 0, 0));
  controlPoints.push(addControl(0, 5, 0));
  controlPoints.push(addControl(0, 5, 3));
  controlPoints.push(addControl(0, 0, 0));
  controlPoints.push(addControl(0, 0, 3));

  var gui = new dat.GUI();
  gui.add(new function () {
      this.clone = function () {

          var clonedGeometry = mesh.children[0].geometry.clone();
          var materials = [
              new THREE.MeshLambertMaterial({opacity: 0.8, color: 0xff44ff, transparent: true}),
              new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true})
          ];

          var mesh2 = THREE.SceneUtils.createMultiMaterialObject(clonedGeometry, materials);
          mesh2.children.forEach(function (e) {
              e.castShadow = true
          });

          mesh2.translateX(5);
          mesh2.translateZ(5);
          mesh2.name = "clone";
          scene.remove(scene.getChildByName("clone"));
          scene.add(mesh2);


      }
  }, 'clone');

  for (var i = 0; i < 8; i++) {

      f1 = gui.addFolder('Vertices ' + (i + 1));
      f1.add(controlPoints[i], 'x', -10, 10);
      f1.add(controlPoints[i], 'y', -10, 10);
      f1.add(controlPoints[i], 'z', -10, 10);

  }

  var trackballControls = initTrackballControls(camera, renderer);
  var clock = new THREE.Clock();

  render();

  function render() {
      trackballControls.update(clock.getDelta());
      stats.update();

      var vertices = [];
      for (var i = 0; i < 8; i++) {
          vertices.push(new THREE.Vector3(controlPoints[i].x, controlPoints[i].y, controlPoints[i].z));
      }

      mesh.children.forEach(function (e) {
          e.geometry.vertices = vertices;
          e.geometry.verticesNeedUpdate = true;
          e.geometry.computeFaceNormals();
          delete e.geometry.__directGeometry
      });

      // render using requestAnimationFrame
      requestAnimationFrame(render);
      renderer.render(scene, camera);
  }
}

mesh网格对象的属性和方法

网格 = 形状 + 材质

mesh网格对象的属性和方法:

方法/属性

position

相对于父对象的位置。父对象通常是THREE.Scene或者THREE.Object3D对象

rotation

设置每个轴的旋转弧度,可以分别设置rotateX(),rotateY(),rotateZ()

scale

通过x,y,z轴缩放对象

translateX(amount)

沿x轴将对象平移amound 距离

translateY(amount)

沿y轴将对象平移amound 距离

translateZ(amount)

沿z轴将对象平移amound 距离

visible

为false时,mesh对象将不会被渲染到场景中

show code

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function init() {

  var stats = initStats();

  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  // create a camera, which defines where we're looking at.
  var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

  // create a render and set the size
  var renderer = new THREE.WebGLRenderer();

  renderer.setClearColor(new THREE.Color(0x000000));
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.shadowMap.enabled = true;

  // create the ground plane
  var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
  var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
  var plane = new THREE.Mesh(planeGeometry, planeMaterial);
  plane.receiveShadow = true;

  // rotate and position the plane
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 0;
  plane.position.y = 0;
  plane.position.z = 0;

  // add the plane to the scene
  scene.add(plane);

  // position and point the camera to the center of the scene
  camera.position.x = -30;
  camera.position.y = 40;
  camera.position.z = 30;
  camera.lookAt(scene.position);

  // add subtle ambient lighting
  var ambientLight = new THREE.AmbientLight(0x3c3c3c);
  scene.add(ambientLight);

  // add spotlight for the shadows
  // add spotlight for the shadows
  var spotLight = new THREE.SpotLight(0xffffff, 1, 180, Math.PI/4);
  spotLight.shadow.mapSize.height = 2048;
  spotLight.shadow.mapSize.width = 2048;
  spotLight.position.set(-40, 30, 30);
  spotLight.castShadow = true;
  scene.add(spotLight);

  // add the output of the renderer to the html element
  document.getElementById("webgl-output").appendChild(renderer.domElement);

  // call the render function
  var step = 0;

  var controls = new function () {
      this.scaleX = 1;
      this.scaleY = 1;
      this.scaleZ = 1;

      this.positionX = 0;
      this.positionY = 4;
      this.positionZ = 0;

      this.rotationX = 0;
      this.rotationY = 0;
      this.rotationZ = 0;
      this.scale = 1;

      this.translateX = 0;
      this.translateY = 0;
      this.translateZ = 0;

      this.visible = true;

      this.translate = function () {

          cube.translateX(controls.translateX);
          cube.translateY(controls.translateY);
          cube.translateZ(controls.translateZ);

          controls.positionX = cube.position.x;
          controls.positionY = cube.position.y;
          controls.positionZ = cube.position.z;
      }
  };


  var material = new THREE.MeshLambertMaterial({color: 0x44ff44});
  var geom = new THREE.BoxGeometry(5, 8, 3);

  // var materials = [
  //   new THREE.MeshLambertMaterial({opacity: 0.8, color: 0x44ff44, transparent: true}),
  //   new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true})
  // ];

  // var cube = THREE.SceneUtils.createMultiMaterialObject(geom, materials);

  var cube = new THREE.Mesh(geom, material);
  cube.position.y = 4;
  cube.castShadow = true;
  scene.add(cube);


  var gui = new dat.GUI();

  guiScale = gui.addFolder('scale');
  guiScale.add(controls, 'scaleX', 0, 5);
  guiScale.add(controls, 'scaleY', 0, 5);
  guiScale.add(controls, 'scaleZ', 0, 5);

  guiPosition = gui.addFolder('position');
  var contX = guiPosition.add(controls, 'positionX', -10, 10);
  var contY = guiPosition.add(controls, 'positionY', -4, 20);
  var contZ = guiPosition.add(controls, 'positionZ', -10, 10);

  contX.listen();
  contX.onChange(function (value) {
      cube.position.x = controls.positionX;
      // cube.children[1].position.x = controls.positionX;
  });

  contY.listen();
  contY.onChange(function (value) {
      cube.position.y = controls.positionY;
  });

  contZ.listen();
  contZ.onChange(function (value) {
      cube.position.z = controls.positionZ;
  });


  guiRotation = gui.addFolder('rotation');
  guiRotation.add(controls, 'rotationX', -4, 4);
  guiRotation.add(controls, 'rotationY', -4, 4);
  guiRotation.add(controls, 'rotationZ', -4, 4);

  guiTranslate = gui.addFolder('translate');

  guiTranslate.add(controls, 'translateX', -10, 10);
  guiTranslate.add(controls, 'translateY', -10, 10);
  guiTranslate.add(controls, 'translateZ', -10, 10);
  guiTranslate.add(controls, 'translate');

  gui.add(controls, 'visible');

  var trackballControls = initTrackballControls(camera, renderer);
  var clock = new THREE.Clock();

  render();

  function render() {
      trackballControls.update(clock.getDelta());
      stats.update();
      cube.visible = controls.visible;

      cube.rotation.x = controls.rotationX;
      cube.rotation.y = controls.rotationY;
      cube.rotation.z = controls.rotationZ;

      cube.scale.set(controls.scaleX, controls.scaleY, controls.scaleZ);
      requestAnimationFrame(render);
      renderer.render(scene, camera);
  }
}

选择合适的摄像机

正交投影摄像机和透视投影摄像机

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function init() {

  var stats = initStats();

  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  // create a camera, which defines where we're looking at.
  var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.x = 120;
  camera.position.y = 60;
  camera.position.z = 180;

  // create a render and set the size
  var renderer = new THREE.WebGLRenderer();

  renderer.setClearColor(new THREE.Color(0x000000));
  renderer.setSize(window.innerWidth, window.innerHeight);

  // create the ground plane
  var planeGeometry = new THREE.PlaneGeometry(180, 180);
  var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
  var plane = new THREE.Mesh(planeGeometry, planeMaterial);


  // rotate and position the plane
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 0;
  plane.position.y = 0;
  plane.position.z = 0;

  // add the plane to the scene
  scene.add(plane);

  var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);

  for (var j = 0; j < (planeGeometry.parameters.height / 5); j++) {
      for (var i = 0; i < planeGeometry.parameters.width / 5; i++) {
          var rnd = Math.random() * 0.75 + 0.25;
          var cubeMaterial = new THREE.MeshLambertMaterial();
          cubeMaterial.color = new THREE.Color(rnd, 0, 0);
          var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

          cube.position.z = -((planeGeometry.parameters.height) / 2) + 2 + (j * 5);
          cube.position.x = -((planeGeometry.parameters.width) / 2) + 2 + (i * 5);
          cube.position.y = 2;

          scene.add(cube);
      }
  }


  var directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
  directionalLight.position.set(-20, 40, 60);
  scene.add(directionalLight);


  // add subtle ambient lighting
  var ambientLight = new THREE.AmbientLight(0x292929);
  scene.add(ambientLight);

  // add the output of the renderer to the html element
  document.getElementById("webgl-output").appendChild(renderer.domElement);

  // call the render function
  var step = 0;

  var trackballControls
  var controls = new function () {
      this.perspective = "Perspective";
      this.switchCamera = function () {
          if (camera instanceof THREE.PerspectiveCamera) {
              camera = new THREE.OrthographicCamera(window.innerWidth / -16, window.innerWidth / 16, window.innerHeight / 16, window.innerHeight / -16, -200, 500);
              camera.position.x = 120;
              camera.position.y = 60;
              camera.position.z = 180;
              camera.lookAt(scene.position);

              trackballControls = initTrackballControls(camera, renderer);
              this.perspective = "Orthographic";
          } else {
              camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
              camera.position.x = 120;
              camera.position.y = 60;
              camera.position.z = 180;

              

              camera.lookAt(scene.position);
              trackballControls = initTrackballControls(camera, renderer);
              this.perspective = "Perspective";
          }
      };
  };

  var gui = new dat.GUI();
  gui.add(controls, 'switchCamera');
  gui.add(controls, 'perspective').listen();

  // make sure that for the first time, the
  // camera is looking at the scene
  camera.lookAt(scene.position);

  trackballControls = initTrackballControls(camera, renderer);
  var clock = new THREE.Clock();

  render();

  function render() {
      trackballControls.update(clock.getDelta());
      stats.update();

      // render using requestAnimationFrame
      requestAnimationFrame(render);
      renderer.render(scene, camera);
  }
}
  • 正交投影摄像机(THREE.PerspectiveCamera):所有的立方体被渲染出来的尺寸都是一样(对象相对于摄像机的距离怼渲染的结果是没有影响的)
  • 透视投影摄像机(THREE.OrthographicCamera):透视效果
透视投影摄像机(THREE.PerspectiveCamera)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PerspectiveCamera( fov, aspect, near, far )

参数

含义

推荐默认值

fov

fov表示视场,所谓视场就是能够看到的角度范围,人的眼睛大约能够看到180度的视场,视角大小设置要根据具体应用,一般游戏会设置60~90度

45

aspect(长宽比)

aspect表示渲染窗口的长宽比,如果一个网页上只有一个全屏的canvas画布且画布上只有一个窗口,那么aspect的值就是网页窗口客户区的宽高比

window.innerWidth/window.innerHeight

near(近面距离)

near属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。

0.1

far(远面距离)

far属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到

1000

zoom(变焦)

zoom 属性可以放大和缩小场景。小于1场景缩小,大于1场景放大,负数,场景会上下颠倒

1

正交投影摄像机(THREE.PerspectiveCamera)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
OrthographicCamera( left, right, top, bottom, near, far )

参数

含义

推荐默认值

left

渲染空间的左边界

right

渲染空间的右边界

top

渲染空间的上边界

bottom

渲染空间的下边界

near

near属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。

0.1

far

far属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到

1000

zoom(变焦)

zoom 属性可以放大和缩小场景。小于1场景缩小,大于1场景放大,负数,场景会上下颠倒

1

设置摄像机聚焦

默认摄像机指向场景的中心position(0,0,0),我们可以随意更改。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
camera.lookAt(new THTREE.Vector3(x,y,z));

或者还可以设置跟随某个对象camera.lookAt(mesh.position);

如下是两种摄像机下,改变摄像机聚焦点的效果。

show code

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function init() {

  var stats = initStats();

  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  // create a camera, which defines where we're looking at.
  var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.x = 120;
  camera.position.y = 60;
  camera.position.z = 180;

  // create a render and set the size
  var renderer = new THREE.WebGLRenderer();

  renderer.setClearColor(new THREE.Color(0x000000));
  renderer.setSize(window.innerWidth, window.innerHeight);

  // create the ground plane
  var planeGeometry = new THREE.PlaneGeometry(180, 180);
  var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
  var plane = new THREE.Mesh(planeGeometry, planeMaterial);


  // rotate and position the plane
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 0;
  plane.position.y = 0;
  plane.position.z = 0;

  // add the plane to the scene
  scene.add(plane);

  var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
  for (var j = 0; j < (planeGeometry.parameters.height / 5); j++) {
      for (var i = 0; i < planeGeometry.parameters.width / 5; i++) {
          var rnd = Math.random() * 0.75 + 0.25;
          var cubeMaterial = new THREE.MeshLambertMaterial();
          cubeMaterial.color = new THREE.Color(rnd, 0, 0);
          var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

          cube.position.z = -((planeGeometry.parameters.height) / 2) + 2 + (j * 5);
          cube.position.x = -((planeGeometry.parameters.width) / 2) + 2 + (i * 5);
          cube.position.y = 2;

          scene.add(cube);
      }
  }

  var lookAtGeom = new THREE.SphereGeometry(2);
  var lookAtMesh = new THREE.Mesh(lookAtGeom, new THREE.MeshLambertMaterial({color: 0x00ff00}));
  scene.add(lookAtMesh);


  var directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
  directionalLight.position.set(-20, 40, 60);
  scene.add(directionalLight);


  // add subtle ambient lighting
  var ambientLight = new THREE.AmbientLight(0x292929);
  scene.add(ambientLight);

  // add the output of the renderer to the html element
  document.getElementById("webgl-output").appendChild(renderer.domElement);

  // call the render function
  var step = 0;

  var controls = new function () {
      this.perspective = "Perspective";
      this.switchCamera = function () {
          if (camera instanceof THREE.PerspectiveCamera) {
              camera = new THREE.OrthographicCamera(window.innerWidth / -16, window.innerWidth / 16, window.innerHeight / 16, window.innerHeight / -16, -200, 500);
              camera.position.x = 120;
              camera.position.y = 60;
              camera.position.z = 180;

              camera.lookAt(scene.position);
              this.perspective = "Orthographic";
          } else {
              camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
              camera.position.x = 120;
              camera.position.y = 60;
              camera.position.z = 180;

              camera.lookAt(scene.position);
              this.perspective = "Perspective";
          }
      };
  };

  var gui = new dat.GUI();
  gui.add(controls, 'switchCamera');
  gui.add(controls, 'perspective').listen();

  // make sure that for the first time, the
  // camera is looking at the scene
  //   camera.lookAt(scene.position);
  render();


  var step = 0;

  function render() {

      stats.update();
      // render using requestAnimationFrame
      step += 0.02;
      if (camera instanceof THREE.Camera) {
          var x = 10 + ( 100 * (Math.sin(step)));
          camera.lookAt(new THREE.Vector3(x, 10, 0));
          lookAtMesh.position.copy(new THREE.Vector3(x, 10, 0));
      }

//        .position.x = 20+( 10*(Math.cos(step)));
      requestAnimationFrame(render);
      renderer.render(scene, camera);
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
学习Three.js
window resize 需要设置camera的aspect 属性,设置renderer的尺寸
小刀c
2024/04/03
3550
vtk.js、three.js在浏览器展示3d图形
对于unstructured grid非格式化网格图形vtk数据,是没有办法在浏览器上展示的。用paraview对vtk进行extract surface后再另存为vtk可以转成polydata类型的vtk,可以在three.js上显示,但不能在vtk.js里显示。
hotqin888
2022/03/10
2.9K0
【愚公系列】2023年08月 Three.js专题-粒子特效案例
粒子特效是一种视觉效果,可以模拟出许多粒子在空间中的运动和变化,形成各种美丽的图案和动态效果。常见的粒子特效包括烟雾、火焰、水流、星空、气泡等,可以在电影、电视、游戏等领域中得到广泛应用。实现粒子特效,需要使用计算机图形学技术,如粒子系统、计算流体力学等。
愚公搬代码
2025/05/28
1700
【愚公系列】2023年08月 Three.js专题-粒子特效案例
造个海洋球池来学习物理引擎【Three.js系列】
github地址:https://github.com/hua1995116/Fly-Three.js
秋风的笔记
2022/08/30
2.1K0
造个海洋球池来学习物理引擎【Three.js系列】
使用Three.Js制作3D相册
ThreeJS是一个用JavaScript写的开源3D图形库,它有个简单但是功能强大的3D渲染引擎,可以在网页浏览器里快速创建和展示3D图形。ThreeJS是一个功能强大、使用简单的3D图形库,提供了一个强大的3D渲染工具,大大降低了创建3D应用程序的难度。
查拉图斯特拉说
2024/04/26
7660
使用Three.Js制作3D相册
Three.js中光源
官方文档:https://threejs.org/docs/index.html#api/zh/lights/SpotLight
小刀c
2024/04/03
2790
Three.js中光源
3d弹弹球(加强版)
上篇文章带读者完成了一个3d弹弹球,本文我们来继续看看这个3d弹弹球的一个增强版,即给弹弹球添加上光线和阴影。
江南一点雨
2019/03/07
6090
Three.js 这样写就有阴影效果啦
在学习 Three.js 时,很多知识点其实记住几个重要的步骤就能实现相应的效果。
德育处主任
2022/09/23
2.8K0
Three.js 这样写就有阴影效果啦
【愚公系列】2023年08月 Three.js专题-光源
光源是能够发出光的物体或设备,它能够发出光线,使我们看到周围的环境和物体。常见的光源包括太阳、灯泡、蜡烛、火把、手电筒等。根据发光方式不同,光源可以分为自发光源和非自发光源。自发光源是指能够自行发出光线的物体,如太阳等;而非自发光源是指需要外部能量刺激才能发出光线的物体,如灯泡、荧光棒等。
愚公搬代码
2025/05/28
1130
【愚公系列】2023年08月 Three.js专题-光源
元宇宙基础案例 | 大帅老猿threejs特训
「元宇宙」这个概念在近来十分火热,但本质来上说,元宇宙这个词更多的是一个商业上的概念,在这个概念里面融入集成了很多现有的技术。具体可能包括:
IT从业者张某某
2023/10/16
8290
元宇宙基础案例 | 大帅老猿threejs特训
ThreeJs 基础学习
如果你要实现一个机器人在跑步,那么机器人的头、四肢、躯干等都是要整体移动的,group可以将一系列的mesh模型组成一个整体,这样就可以实现整体移动了。
心安事随
2024/07/29
4240
Three.js 之 Import Model 导入模型
Three.js 提供了很多原始模型,但如果我们需要更复杂的模型,最好使用 3D 软件建模,然后导入到场景中。本节我们就来学学如何导入一个做好的 3D 模型。
阿珍
2022/08/10
6.9K0
【愚公系列】2022年09月 微信小程序-three.js绘制球体
Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。
愚公搬代码
2022/09/28
1.2K0
【愚公系列】2022年09月 微信小程序-three.js绘制球体
【愚公系列】2023年08月 Three.js专题-材质
材质是指制造物品所使用的原料或物质的种类,常见的材质包括金属、塑料、木材、玻璃、石头等。材质的选择取决于所制造物品的用途、设计和预算等因素。不同的材质有不同的特点和优缺点,如金属通常较为坚固,但较重且易锈蚀;塑料轻便且不易损坏,但耐久性较差。材质也会影响制造物品的外观和质感,如木材可以赋予物品自然美感,而玻璃则可以营造现代感。
愚公搬代码
2025/05/28
1110
【愚公系列】2023年08月 Three.js专题-材质
threejs中实现物体阴影
在Three.js中实现阴影需要几个步骤,包括设置渲染器、光源以及物体的材质等。以下是一个基本的实现阴影的步骤:
用户8703799
2024/08/20
2170
第3章 让场景动起来
这一节课,我们要让场景动起来,不禁想到了郭富城的一首歌《动起来》。心中有很多感慨,觉得时间过得太快,自己还没有多大的成功。以淡淡的感伤开始这节课的讲解。
webvrmodel模型网
2023/01/03
1.2K0
如何实现一个3d场景中的阴影效果(threejs)?
跟OpenGL不同,在threejs中实现一个阴影效果很简单,只需要简单的几个设置。
程序你好
2021/07/23
3K0
如何实现一个3d场景中的阴影效果(threejs)?
three.js中的矩阵变换(模型视图投影变换)
我在《WebGL简易教程(五):图形变换(模型、视图、投影变换)》这篇博文里详细讲解了OpenGL\WebGL关于绘制场景的图形变换过程,并推导了相应的模型变换矩阵、视图变换矩阵以及投影变换矩阵。这里我就通过three.js这个图形引擎,验证一下其推导是否正确,顺便学习下three.js是如何进行图形变换的。
charlee44
2020/05/08
6.3K0
Three.js教程(5):光源
Three.js的作用就是做3D效果,一说到3D就绕不过一个话题,那就是阴影。而要出现阴影的效果,那么就要涉及光源。本章介绍Three.js中光源相关的知识。
kai666666
2020/10/17
2.9K0
Three.js教程(3):场景
场景(Scene)相当于是一个容器,可以在它上面添加光线,物体等,最后Three.js把它和相机一起渲染到DOM中。
kai666666
2020/10/17
4.2K0
相关推荐
学习Three.js
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档