Three.js入门④

  最近学习Three.js,此贴供学习记录之用。
  学习视频:Three.js教程。讲解很详细,也有配套的笔记,但不包含前端基础知识的讲解,如果是纯小白的朋友,可以找这位up之前的教程学习一下。

文章目录

  • 一、常用几何体介绍
    • 立体几何
      • 1、长方体
      • 2、圆柱体
      • 3、球体
      • 4、圆锥体
    • 平面图形
      • 5、矩形平面
      • 6、圆平面
  • 二、高光网格材质MeshPhongMaterial
  • 三、模型渲染优化
    • 渲染器抗锯齿属性设置
    • 设置设备像素比
  • 完整.js文件

  • .html文件
DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>0619_2title>

        <style>
            body{
                overflow: hidden;
                margin: 0;
            }
        style>
    head>
    <body>
        <script type="importmap">
            {
                "imports": {
                    "three": "./three.js/build/three.module.js",
                    "three/addons/": "./three.js/examples/jsm/"
                }
            }
        script>

        <script src="0619_2.js" type="module">script>
    body>
html>

一、常用几何体介绍

  • 几何体均为多个三角形拼接而成

立体几何

1、长方体

构造参数:
width: X轴上面的宽度 默认值为1
height: Y轴上面的高度 默认值为1
depth: Z轴上面的深度 默认值为1
widthSegments: (可选)宽度的分段数 默认值是1
heightSegments: (可选)高度的分段数 默认值是1
depthSegments: (可选)深度的分段数 默认值是1

Three.js入门④_第1张图片

2、圆柱体

构造参数:
radiusTop: 圆柱的顶部半径 默认值是1
radiusBottom: 圆柱的底部半径 默认值是1
height: 圆柱的高度 默认值是1
radialSegments: 圆柱侧面周围的分段数 默认为32
heightSegments: 圆柱侧面沿着其高度的分段数 默认值为1
openEnded: 一个Boolean值,指明该圆锥的底面是开放的还是封顶的 默认值为false,即其底面默认是封顶的
thetaStart: 第一个分段的起始角度 默认为0
thetaLength: 圆柱底面圆扇区的中心角,通常被称为“θ”(西塔) 默认值是2*Pi,这使其成为一个完整的圆柱

Three.js入门④_第2张图片

3、球体

构造参数:
radius: 球体半径 默认为1
widthSegments: 水平分段数(沿着经线分段) 最小值为3(三棱锥),默认值为32
heightSegments: 垂直分段数(沿着纬线分段) 最小值为2,默认值为16
phiStart: 指定水平(经线)起始角度 默认值为0
phiLength: 指定水平(经线)扫描角度的大小 默认值为 Math.PI * 2
thetaStart: 指定垂直(纬线)起始角度 默认值为0
thetaLength: 指定垂直(纬线)扫描角度大小 默认值为 Math.PI

Three.js入门④_第3张图片

4、圆锥体

构造参数:
radius: 圆锥底部的半径 默认值为1
height: 圆锥的高度 默认值为1
radialSegments: 圆锥侧面周围的分段数 最小为3(三棱锥),默认为32
heightSegments: 圆锥侧面沿着其高度的分段数 默认值为1
openEnded: 一个Boolean值,指明该圆锥的底面是开放的还是封顶的 默认值为false,即其底面默认是封顶的
thetaStart: 第一个分段的起始角度 默认为0
thetaLength: 圆锥底面圆扇区的中心角,通常被称为“θ”(西塔) 默认值是2*Pi,这使其成为一个完整的圆锥

Three.js入门④_第4张图片

平面图形

  • 平面图形默认单面显示
    显示设置:
const material = new THREE.MeshPhongMaterial({
	side: THREE.FrontSide,	// 默认单面显示
	side: THREE.DoubleSide,	// 双面显示
});

// 也可以选择写在外面
// material.side = THREE.DoubleSide;
  • 单面和双面显示的背面
    Three.js入门④_第5张图片

5、矩形平面

构造参数:
width: 平面沿x轴宽度 默认为1
height: 平面沿y轴宽度 默认为1
widthSegments: 平面的宽度分段数 默认值是1
heightSegments: 平面的高度分段数 默认值是1

Three.js入门④_第6张图片

6、圆平面

构造参数:
radius: 圆形半径 默认为1
segments: 分段(三角形)数量 最少为3,默认为32
thetaStart: 第一个分段的起始角度 默认为0
thetaLength: 圆形扇区的中心角,通常被称为“θ” 默认值是2*Pi,这使其成为一个完整的圆

Three.js入门④_第7张图片

  • 几何体烤串

Three.js入门④_第8张图片

二、高光网格材质MeshPhongMaterial

   高光网格材质MeshPhongMaterial和漫反射网格材质MeshLambertMaterial一样会受到光照的影响。
   但MeshPhongMaterial能够实现镜面反射,实现高光反射效果。

  • 高光网格材质属性

shininess: 高光亮度属性 默认30
specular: 高光颜色属性 默认0x111111

// 高光网格材质   模拟镜面反射,产生一个高光效果
const material = new THREE.MeshPhongMaterial({
    color: 0xff0f00,
    // shininess高光部分亮度   默认30
    shininess: 20,
    // 高光部分颜色
    specular: 0xfff000,
});
  • 效果图
    Three.js入门④_第9张图片

三、模型渲染优化

渲染器抗锯齿属性设置

const renderer = new THREE.WebGLRender({
	// 在参数中设置抗锯齿属性   使模型渲染效果更好,边缘更平滑
    antialias: true,    // 或在之外通过对象属性设置 renderer.antialias = true;
});
  • 抗锯齿属性设置前后
    Three.js入门④_第10张图片

设置设备像素比

  • 查看设备像素比window.devicePixelRatio
// 在控制台查看设备像素比
console.log('查看当前屏幕设备像素比:', window.devicePixelRatio);
  • 设置设备像素比
    若硬件设备设备像素比刚好是1,那么是否执行.setPixelRatio()不会有明显差异,像素比较高设备差异较明显。但这条一般开发时都会写上以期达到更好的渲染效果。
// 设置设备像素比   获取屏幕对应的设备像素比告诉threejs,减少渲染模糊问题
renderer.setPixelRatio(window.devicePixelRatio);

完整.js文件

import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const scene = new THREE.Scene();

const axesHelper = new THREE.AxesHelper(300, 300, 300);
scene.add(axesHelper);

// BoxGeometry() 长方体
/* 构造参数:
    width: X轴上面的宽度   默认值为1
    height: Y轴上面的高度   默认值为1
    depth: Z轴上面的深度   默认值为1
    widthSegments: (可选)宽度的分段数   默认值是1
    heightSegments: (可选)高度的分段数   默认值是1
    depthSegments: (可选)深度的分段数   默认值是1
*/
const box = new THREE.BoxGeometry(30, 20, 10);
// CylinderGeometry() 圆柱体
/* 构造参数:
    radiusTop: 圆柱的顶部半径   默认值是1
    radiusBottom: 圆柱的底部半径   默认值是1
    height: 圆柱的高度   默认值是1
    radialSegments: 圆柱侧面周围的分段数   默认为32
    heightSegments: 圆柱侧面沿着其高度的分段数   默认值为1
    openEnded: 一个Boolean值,指明该圆锥的底面是开放的还是封顶的   默认值为false,即其底面默认是封顶的
    thetaStart: 第一个分段的起始角度   默认为0
    thetaLength: 圆柱底面圆扇区的中心角,通常被称为“θ”(西塔)   默认值是2*Pi,这使其成为一个完整的圆柱
*/
const cylinder = new THREE.CylinderGeometry(15, 15, 30);
// SphereGeometry() 球体
/* 构造参数:
    radius: 球体半径   默认为1
    widthSegments: 水平分段数(沿着经线分段)   最小值为3(三棱锥),默认值为32
    heightSegments: 垂直分段数(沿着纬线分段)   最小值为2,默认值为16
    phiStart: 指定水平(经线)起始角度   默认值为0
    phiLength: 指定水平(经线)扫描角度的大小   默认值为 Math.PI * 2
    thetaStart: 指定垂直(纬线)起始角度   默认值为0
    thetaLength: 指定垂直(纬线)扫描角度大小   默认值为 Math.PI
*/
const sphere = new THREE.SphereGeometry(25);
// ConeGeometry() 圆锥   由数个三角形构成
/* 构造参数:
    radius: 圆锥底部的半径   默认值为1
    height: 圆锥的高度   默认值为1
    radialSegments: 圆锥侧面周围的分段数   最小为3(三棱锥),默认为32
    heightSegments: 圆锥侧面沿着其高度的分段数   默认值为1
    openEnded: 一个Boolean值,指明该圆锥的底面是开放的还是封顶的   默认值为false,即其底面默认是封顶的
    thetaStart: 第一个分段的起始角度   默认为0
    thetaLength: 圆锥底面圆扇区的中心角,通常被称为“θ”(西塔)   默认值是2*Pi,这使其成为一个完整的圆锥
 */
const cone = new THREE.ConeGeometry(15, 20, 30);
// PlaneGeometry() 矩形平面 由数个三角形构成
/* 构造参数:
    width: 平面沿x轴宽度   默认为1
    height: 平面沿y轴宽度   默认为1
    widthSegments: 平面的宽度分段数   默认值是1
    heightSegments: 平面的高度分段数   默认值是1
*/
const plane = new THREE.PlaneGeometry(40, 30);
// CircleGeometry() 圆平面  由数个三角形构成
/* 构造参数:
    radius: 圆形半径   默认为1
    segments: 分段(三角形)数量   最少为3,默认为32
    thetaStart: 第一个分段的起始角度   默认为0
    thetaLength: 圆形扇区的中心角,通常被称为“θ”   默认值是2*Pi,这使其成为一个完整的圆
*/
const circle = new THREE.CircleGeometry(35);

// 高光网格材质   模拟镜面反射,产生一个高光效果
const material = new THREE.MeshPhongMaterial({
    color: 0xff0f00,
    // shininess高光部分亮度   默认30
    shininess: 20,
    // 高光部分颜色
    specular: 0xfff000,
    // 对于平面图形,默认单面可见
    side: THREE.FrontSide,
    // 平面图形双面可见
    side: THREE.DoubleSide,
});

// 平面图形双面可见
// material.side = THREE.DoubleSide;

const mesh1 = new THREE.Mesh(box, material);
mesh1.position.set(0, 0, 20);
scene.add(mesh1);

const mesh2 = new THREE.Mesh(cylinder, material);
mesh2.position.set(0, 0, 50);
scene.add(mesh2);

const mesh3 = new THREE.Mesh(sphere, material);
mesh3.position.set(0, 0, 100);
scene.add(mesh3);

const mesh4 = new THREE.Mesh(cone, material);
mesh4.position.set(0, 0, 140);
scene.add(mesh4);

const mesh5 = new THREE.Mesh(plane, material);
mesh5.position.set(0, 0, 0);
scene.add(mesh5);

const mesh6 = new THREE.Mesh(circle, material);
mesh6.position.set(0, 0, 165);
scene.add(mesh6);

const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(100, 200, 200);
scene.add(pointLight);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);

const width = window.innerWidth;
const height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(35, width/height, 0.1, 3000);
camera.position.set(350, 350, 350);
camera.lookAt(0, 0, 0);

const renderer = new THREE.WebGLRenderer({
    // 在参数中设置抗锯齿属性   使模型渲染效果更好,边缘更平滑
    antialias: true,    // 或在之外通过对象属性设置 renderer.antialias = true;
});
renderer.setSize(width, height);
renderer.render(scene, camera);
// 背景颜色设置   颜色,透明度
renderer.setClearColor(0x444444, 1);

document.body.appendChild(renderer.domElement);

// 旋转预览
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', function () {
    renderer.render(scene, camera);
})

// 窗口动态调节
window.onresize = function (){
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
}

// 查看设备像素比
console.log('查看当前屏幕设备像素比:', window.devicePixelRatio);
// 设置设备像素比   获取屏幕对应的设备像素比告诉threejs,以免渲染模糊问题
/* 若硬件设备设备像素比刚好是1,那么是否执行.setPixelRatio()不会有明显差异
    像素比较高设备差异较明显 */
renderer.setPixelRatio(window.devicePixelRatio);

你可能感兴趣的:(javascript,前端,html,笔记)