Threejs的学习-入门

突然想学学webGL,所以做个记录。

Threejs,一个 基于WebGL 的 JavaScript 3D库 ,封装了WebGL,提供了一系列简单的API便于处理WebGL。

相关概念

场景:scene, 所有物体的容器

相机:camera,设置观察场景的角度和位置

渲染器:renderer, 负责将场景渲染到画布上

使用步骤

本质是使用Three的一系列API创建对象,然后相互组合。

1、下载并引入three.js文件

2、创建场景scene对象

3、创建相机camera对象,并根据参数进行设置

4、创建渲染器renderer对象,渲染器使用js添加到页面中

5、创建物体对象,并把物体对象添加到场景中

6、调用渲染器对象的render函数开始渲染,如果需要不断刷新则需要创建一个函数,并在函数中执行requestAnimationFrame函数,该函数由threejs提供,用于把页面再渲染一次

详细步骤

代码效果是创建一个不断旋转的正方体

1、引入three.js文件

html 复制代码
<script src="js/three.js"></script>

2、创建场景scene对象

javascript 复制代码
// 场景 所有物体的容器
var scene = new THREE.Scene();

3、创建相机camera对象,并根据参数进行设置

javascript 复制代码
// 相机 决定了场景中那个角度的景色会显示出来
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 5;

PerspectiveCamera 是threejs提供的 透视相机 , 用于3D场景渲染的相机类型,它模拟了人眼观察世界的方式 , 远处的物体看起来比近处的物体小,且遵循透视缩短规律。

构造函数参数:

  • fov (Field of View,视野):定义相机视锥体的垂直角度,以弧度为单位。通常设置为如75度这样的值。
  • aspect (宽高比):视锥体的宽高比,通常是渲染窗口的宽除以高。如果不指定,Three.js会在渲染时自动调整。
  • near:近裁剪面距离相机的距离。任何比这个距离近的物体都不会被渲染。
  • far:远裁剪面距离相机的距离。任何比这个距离远的物体都不会被渲染。

属性:

  • position:相机的位置,一个THREE.Vector3对象。
  • rotation:相机的旋转角度,一个包含xyz属性的对象,每个属性都是一个THREE.Euler对象。
  • up:相机的上方向向量,一个THREE.Vector3对象,默认为(0, 1, 0),即Y轴向上。

Vector3 三维向量 , 接受三个参数来定义对象的 x、y 和 z ,分别对应 x、y 和 z轴上的值

4、创建渲染器renderer对象,渲染器使用js添加到页面中

javascript 复制代码
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

5、创建物体对象,并把物体对象添加到场景中

javascript 复制代码
var geometry = new THREE.CubeGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial({color:0x00ff00});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);

CubeGeometry 几何立方体 ,较新版本BoxGeometry替换

构造函数参数:

  • width(宽度):x方向上的长度。
  • height(高度):y方向上的长度。
  • depth(深度):z方向上的长度。
  • widthSegments(宽度分段):沿x轴的方向,将面分成多少份。默认值是1。
  • heightSegments(高度分段):沿y轴的方向,将面分成多少份。默认值是1。
  • depthSegments(深度分段):沿z轴的方向,将面分成多少份。默认值是1。

MeshBasicMaterial 基本材质类型(可以理解为皮肤) ,不考虑光源(想象一个手电筒照在物体上,物体根据光照展示不同效果,这就是光源,实际用起来也是js对象)的影响, 适合用于不需要光照效果的场景 。

构造函数是一个 包含材质属性的对象。

属性:

  • color:材质的颜色,默认为白色(0xffffff)。可以是一个整数,表示十六进制颜色值。
  • map:基础颜色贴图,可以用来替代材质的颜色。可以是一个 THREE.Texture 对象。
  • alphaMap:透明度贴图,可以用来定义材质的透明度。可以是一个 THREE.Texture 对象。
  • emissive:自发光颜色,默认为黑色(0x000000)。即使在没有光源的情况下,也会显示这个颜色。
  • emissiveMap:自发光贴图,可以用来定义自发光的颜色。可以是一个 THREE.Texture 对象。
  • opacity:材质的全局透明度,默认为 1(不透明)。
  • transparent:是否开启透明模式,默认为 false。如果设置为 true,则需要设置 opacity 或者使用 alphaMap
  • side:指定材质在哪一面渲染,可以是 THREE.FrontSide(正面)、THREE.BackSide(背面)或 THREE.DoubleSide(双面)。
  • wireframe:是否启用线框模式,默认为 false
  • visible:是否渲染该材质,默认为 true
  • depthTest:是否进行深度测试,默认为 true
  • depthWrite:是否写入深度缓冲区,默认为 true
  • blending:混合模式,默认为 THREE.NormalBlending。可以设置为 THREE.AdditiveBlendingTHREE.SubtractiveBlending 等。
  • vertexColors:是否启用顶点颜色,默认为 THREE.NoColors。可以设置为 THREE.VertexBasicColorsTHREE.VertexColorsTHREE.FaceColors
  • flatShading:是否使用平滑着色,默认为 false。如果设置为 true,则每个面片都将使用平均法线。

Mesh 三维网格对象 ,用于结合了一个几何体和一个或多个材质,并可以被添加到场景中进行渲染

6、调用渲染器对象的render函数开始渲染,如果需要不断刷新则需要创建一个函数,并在函数中执行requestAnimationFrame函数,该函数由threejs提供,用于把页面再渲染一次

javascript 复制代码
function render() {
    // requestAnimationFrame 执行一次参数中的函数,把页面再次渲染一次
    requestAnimationFrame(render);
    cube.rotation.x += 0.1;
    cube.rotation.y += 0.1;
    // 渲染器渲染
    /**
     render( scene, camera, renderTarget, forceClear )
         scene:前面定义的场景
         camera:前面定义的相机
         renderTarget:渲染的目标,默认是渲染到前面定义的render变量中
         forceClear:每次绘制之前都将画布的内容给清除,即使自动清除标志autoClear为false,也会清除
     */
    renderer.render(scene, camera);
}

完整代码

如果代码报错,应该是Three版本问题

html 复制代码
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="js/three.js"></script>
</head>
<body>

  <script>
    /* 画一个不断旋转的立体正方体 */

    // 场景 所有物体的容器
    var scene = new THREE.Scene();
    // 相机 决定了场景中那个角度的景色会显示出来
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
    camera.position.z = 5;
    // 渲染器 使用相机将场景渲染到网页
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    // 物体添加到场景中
    // CubeGeometry 定义一个几何体
    var geometry = new THREE.CubeGeometry(1,1,1);
    var material = new THREE.MeshBasicMaterial({color:0x00ff00});
    var cube = new THREE.Mesh(geometry, material);
    scene.add(cube);
    function render() {
      // requestAnimationFrame 执行一次参数中的函数,把页面再次渲染一次
      requestAnimationFrame(render);
      cube.rotation.x += 0.1;
      cube.rotation.y += 0.1;
      // 渲染器渲染
      /**
             render( scene, camera, renderTarget, forceClear )
                 scene:前面定义的场景
                 camera:前面定义的相机
                 renderTarget:渲染的目标,默认是渲染到前面定义的render变量中
                 forceClear:每次绘制之前都将画布的内容给清除,即使自动清除标志autoClear为false,也会清除
             */
      renderer.render(scene, camera);
    }
    render();
  </script>

</body>
相关推荐
乘风gg1 小时前
还在养虾吗?虾王已诞生:微信龙虾 ClawBot
前端·ai编程·claude
小小小小宇1 小时前
LLM 长期记忆构建
前端
lichenyang4531 小时前
从 Express 老项目到 NestJS + Docker:一次车辆管理系统的渐进式重构
前端
Momo__2 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富3 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇3 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇3 小时前
React中的forwardRef
前端·react.js·面试
槑有老呆3 小时前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马3 小时前
Verilog开发常见问题汇总解析
前端
子兮曰3 小时前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端