• 作者:老汪软件技巧
  • 发表时间:2024-08-25 07:02
  • 浏览量:

three 附件文档总结之后,写出如下附件介绍,主要包括,功能函数类 DataUtils,切割多边形三角剖分算法实现类 Earcut, 图片功能函数类 ImageUtils, 环境贴图类 PMREMGenerator,形状实用的函数类 ShapeUtils

先介绍下 DataUtils 这个类有两个方法,并且这个类不是构造函数先介绍下什么是单精度浮点数,什么时半精度浮点数

代码示例

const DataUtils = THREE.DataUtils //获取指向
// 半精度转单精度
const halfFloatValue = 0x3c00;
const floatValue = DataUtils.fromHalfFloat(halfFloatValue);
console.log(floatValue); //
// 单精度转半精度
const value = 1.5;
const halfFloat = THREE.DataUtils.toHalfFloat(value);
console.log(halfFloat); // 16 位整数

Earcut 这个类只有一个方法

使用示例


    // 外部多边形顶点
    const vertices = [
    0, 0,   // 顶点 1
    4, 0,   // 顶点 2
    4, 4,   // 顶点 3
    0, 4,   // 顶点 4
    // 孔的顶点
    1, 1,   // 孔的顶点 1
    3, 1,   // 孔的顶点 2
    3, 3,   // 孔的顶点 3
    1, 3    // 孔的顶点 4
    ];
    // 孔的起始位置索引
    const holeIndices = [4]; // 孔的顶点从索引 4 开始
    // 使用 Earcut 进行三角剖分
    const indices = Earcut.triangulate(vertices, holeIndices, 2); // 2 表示二维顶点

_类的构造函数可以有几个参数_类的构造函数

ImageUtils 图片工具类 只有一个方法基本使用示例

    THREE.ImageUtils.getDataURL(renderer.domElement)

PMREMGenerator 贴图环境纹理这个对象有六个方法代码示例



<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from 'three';
import { PMREMGenerator } from 'three/src/extras/PMREMGenerator.js';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
import hdrImg from "@public/hdr/bgImage.hdr"
import pngImg from "@public/banner2.jpg"
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const parkingLot = ref();
onMounted(() => {
    const DOMEl = parkingLot.value;
    // 获取 DOMEl 的宽度和高度,以设置渲染器的大小。
    const width = DOMEl.clientWidth;
    const height = DOMEl.clientHeight;
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize( width, height );
    DOMEl.appendChild( renderer.domElement );
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 2000 );
    camera.position.set( 0, 300, 800 );
    camera.lookAt( 0, 0, 0 );
    // 创建 PMREM 生成器
    const pmremGenerator = new PMREMGenerator(renderer);
    
    // 使用 RGBELoader 加载 HDR 环境图
    new RGBELoader().load(hdrImg, (hdrTexture) => {
        console.log(hdrTexture,"hdrTexture");
        // 从 HDR 图像生成 PMREM 贴图
        const pmremTexture = pmremGenerator.fromEquirectangular(hdrTexture).texture;
        scene.background = pmremTexture;   // 作为背景图像
        scene.environment = pmremTexture;  // 作为全局环境贴图
        
        scene.add(new THREE.Mesh(new THREE.SphereGeometry(10, 32, 32), new THREE.MeshBasicMaterial({ map: hdrTexture })));
        const pmremTextureImg = pmremGenerator.fromScene(scene, 0).texture;
        
        // 创建立方体
        const geometry = new THREE.BoxGeometry(100,100,100);
        // 使用 PMREM 纹理创建材质
        const material = new THREE.MeshStandardMaterial({
            envMap: pmremTextureImg,
            roughness: 0.1,
            metalness: 0.9
        });
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);
        // 假设你已经加载了六个图像作为立方体贴图的面
        const loader = new THREE.CubeTextureLoader();
        const cubemap = loader.load([
            pngImg, pngImg,
            pngImg, pngImg,
            pngImg, pngImg
        ]);
        // 从立方体贴图生成 PMREM 贴图
        const pmremTexture2 = pmremGenerator.fromCubemap(cubemap).texture;
        // 使用 PMREM 纹理创建材质
        const material2 = new THREE.MeshStandardMaterial({
            envMap: pmremTexture2,
            roughness: 0.1,// 光滑度,0 完全光滑  1 表面非常粗粗
            metalness: 0.9 // 反射属性是否类似于金属 0 非类似 1 完全
        });
        // 创建立方体
        const geometry2 = new THREE.BoxGeometry(256,256,256);
        const cube2 = new THREE.Mesh(geometry2, material2);
        cube2.position.z = 200
        scene.add(cube2);
        // 清理生成器以释放内存
        hdrTexture.dispose();
        pmremTexture.dispose();
        pmremGenerator.dispose();
        // 创建 OrbitControls
        const controls = new OrbitControls(camera, renderer.domElement);
        // 创建地板
        const floorGeometry = new THREE.PlaneGeometry(400, 400); // 宽度和高度为 10 的地板
        const floorMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 }); // 灰色材质
        const floor = new THREE.Mesh(floorGeometry, floorMaterial);
        floor.rotation.x = -Math.PI / 2; // 将平面旋转到水平位置
        scene.add(floor);
        
        // 创建光源
        const light = new THREE.DirectionalLight(0x0000ff, 10);
        light.position.set(10, 10, 10);
        light.castShadow = true;
        scene.add(light);
        // 渲染循环
        function animate() {
            requestAnimationFrame(animate);
            controls.update();  // 更新控制器
            renderer.render(scene, camera);
        }
        animate();
    });
});
script>
<style lang="scss" scoped="scoped">
    #parkingLot {
        width: 940px;
        height: 940px;
        border: 1px solid #ccc;
        margin: 30px auto;
    }
style>

ShapeUtils 这个类有三个方法

使用示例



<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from 'three';
const parkingLot = ref();
const renderer = new THREE.WebGLRenderer();
onMounted(() => {
    const DOMEl = parkingLot.value;
    // 获取 DOMEl 的宽度和高度,以设置渲染器的大小。
    const width = DOMEl.clientWidth;
    const height = DOMEl.clientHeight;
    renderer.setSize( width, height );
    DOMEl.appendChild( renderer.domElement );
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 2000 );
    camera.position.set( 0, 300, 800 );
    camera.lookAt( 0, 0, 0 );
    
    // 创建多边形形状
    const shape = new THREE.Shape();
    shape.moveTo(0, 0);
    shape.lineTo(100, 0);
    shape.lineTo(100, 100);
    shape.lineTo(0, 100);
    shape.lineTo(0, 0);
    // 将形状转换为几何体
    const geometry = new THREE.ShapeGeometry(shape);
    // 创建材质
    const material = new THREE.MeshBasicMaterial({ color: 0xff0000, side: THREE.DoubleSide });
    // 创建网格
    const mesh = new THREE.Mesh(geometry, material);
    // 将网格添加到场景中
    scene.add(mesh);
    const ShapeUtils = THREE.ShapeUtils;
        // 计算形状的面积
    const area = ShapeUtils.area(shape.getPoints());
    // 使用 ShapeUtils.isClockWise 判断顶点顺序
    const isClockWise = ShapeUtils.isClockWise(shape.getPoints());
    console.log('Area:', area, isClockWise);
    
    // 创建光源
    const light = new THREE.DirectionalLight(0x0000ff, 10);
    light.position.set(10, 10, 10);
    light.castShadow = true;
    scene.add(light);
    renderer.render(scene, camera);
});
onUnmounted(() => {
    if(renderer){
        renderer.dispose()
    }
})
script>
<style lang="scss" scoped="scoped">
    #parkingLot {
        width: 940px;
        height: 940px;
        border: 1px solid #ccc;
        margin: 30px auto;
    }
style>