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>
相关推荐
weixin_382395239 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__9 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.9 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~10 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华11 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子13 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅13 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni14 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学15 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端