threejs小案例——贴图翻转

发布于:2025-05-19 ⋅ 阅读:(21) ⋅ 点赞:(0)

简要说明:

该小案例,主要做的是对长方体6个面进行贴图,以及贴图的方向进行调整;

贴图图片:

1、不加旋转的贴图效果:

整体效果

代码运行的整体效果;

完整代码(可运行):

// 引入threejs
import * as THREE from "three";
// 引入轨道控制器扩展库
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

const scene = new THREE.Scene();
// 定义变量
const width = 1167;   // 画布大小
const height = 737;
const bigBox = {
    len: 822,
    W: 482,
    H: 86,
};
const smallBox = {
    len: 150,
    W: 50,
    H: 80,
};
// 外面大盒子
const geometry = new THREE.BoxGeometry(bigBox.len, bigBox.H, bigBox.W); // 形状
const meterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 材质
meterial.transparent = true;
meterial.opacity = 0.5;

const mesh = new THREE.Mesh(geometry, meterial);
scene.add(mesh);
// 线框
borderLine(geometry, mesh)


// 里面小盒子
const smallGeometry = new THREE.BoxGeometry(
    smallBox.W,
    smallBox.H,
    smallBox.len
);

const textureLoader = new THREE.TextureLoader()

let smallMaterial = []
// 顺序不可乱:右左、上下、前后
let arr = ['../../src/direction_image/right.jpg', '../../src/direction_image/left.jpg', '../../src/direction_image/top.jpg',
    '../../src/direction_image/bottom.jpg', '../../src/direction_image/front.jpg', '../../src/direction_image/back.jpg']

// 加载所有纹理并创建材质
Promise.all(arr.map(url => {
    return new Promise((resolve, reject) => {
        const texture = textureLoader.load(url, () => resolve(texture), error => reject(error));
    });
})).then((textures) => {
    // 对顶部和底部纹理进行特殊处理
    // const topTexture = textures[2]; // 顶部纹理
    // topTexture.rotation = Math.PI; // 旋转180度
    // topTexture.center.set(0.5, 0.5); // 设置旋转中心

    smallMaterial = textures.map((texture, index) => {
        // if (index === 2) {
        //     return new THREE.MeshBasicMaterial({
        //         map: texture,
        //         side: THREE.DoubleSide
        //     });
        // }
        return new THREE.MeshBasicMaterial({ map: texture });
    })

    const smallMesh = new THREE.Mesh(smallGeometry, smallMaterial);
    smallMesh.position.set(0, -(bigBox.H - smallBox.H - 2) / 2, 0)
    scene.add(smallMesh);
    borderLine(smallGeometry, smallMaterial)

    // 显示坐标轴
    const axesHelper = new THREE.AxesHelper(500);
    scene.add(axesHelper);

    const camera = new THREE.PerspectiveCamera(30, width / height, 0.1, 2000);
    // 创建渲染器对象
    const renderer = new THREE.WebGLRenderer();
    // 相机
    CameraFn(renderer,camera)

    // 设置相机空间轨道控制器
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.addEventListener("change", function () {
        renderer.render(scene, camera);
    });
})


function CameraFn(renderer,camera){
    camera.position.set(-1000, 800, 800); // 设置相机位置
    camera.lookAt(0, 10, 0);

    renderer.setSize(width, height);
    renderer.render(scene, camera);
    document.body.appendChild(renderer.domElement);
}

// 各部件外框线
function borderLine(BoxGeometry, Mesh, color = 0xffffff) {
    let edgesGeometry = new THREE.EdgesGeometry(BoxGeometry)
    let edgesMaterial = new THREE.LineBasicMaterial({
        color: color,
        linewidth: 2
    })
    let line = new THREE.LineSegments(edgesGeometry, edgesMaterial)
    scene.add(line)
}

2、对贴图添加旋转

需求:要求左图和有图,图片上的箭头均指向后方;

目前的左图、右图如下所示:

目前的效果(不加旋转):

修改后的(添加旋转):

修改的核心代码:

完整代码(可运行):

// 引入threejs
import * as THREE from "three";
// 引入轨道控制器扩展库
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

const scene = new THREE.Scene();
// 定义变量
const width = 1167;   // 画布大小
const height = 737;
const bigBox = {
    len: 822,
    W: 482,
    H: 86,
};
const smallBox = {
    len: 150,
    W: 50,
    H: 80,
};
// 外面大盒子
const geometry = new THREE.BoxGeometry(bigBox.len, bigBox.H, bigBox.W); // 形状
const meterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 材质
meterial.transparent = true;
meterial.opacity = 0.5;

const mesh = new THREE.Mesh(geometry, meterial);
scene.add(mesh);
// 线框
borderLine(geometry, mesh)


// 里面小盒子
const smallGeometry = new THREE.BoxGeometry(
    smallBox.W,
    smallBox.H,
    smallBox.len
);

const textureLoader = new THREE.TextureLoader()

let smallMaterial = []
// 顺序不可乱:右左、上下、前后
let arr = ['../../src/direction_image/right.jpg', '../../src/direction_image/left.jpg', '../../src/direction_image/top.jpg',
    '../../src/direction_image/bottom.jpg', '../../src/direction_image/front.jpg', '../../src/direction_image/back.jpg']

// 加载所有纹理并创建材质
Promise.all(arr.map(url => {
    return new Promise((resolve, reject) => {
        const texture = textureLoader.load(url, () => resolve(texture), error => reject(error));
    });
})).then((textures) => {
    // 对顶部和底部纹理进行特殊处理
    const topTexture = textures[0]; // 顶部纹理
    topTexture.rotation = Math.PI; // 旋转180度
    topTexture.center.set(0.5, 0.5); // 设置旋转中心

    smallMaterial = textures.map((texture, index) => {
        if (index === 0) {
            return new THREE.MeshBasicMaterial({
                map: texture,
                side: THREE.DoubleSide
            });
        }   
        return new THREE.MeshBasicMaterial({ map: texture });
    })

    const smallMesh = new THREE.Mesh(smallGeometry, smallMaterial);
    smallMesh.position.set(0, -(bigBox.H - smallBox.H - 2) / 2, 0)
    scene.add(smallMesh);
    borderLine(smallGeometry, smallMaterial)

    // 显示坐标轴
    const axesHelper = new THREE.AxesHelper(500);
    scene.add(axesHelper);

    const camera = new THREE.PerspectiveCamera(30, width / height, 0.1, 2000);
    // 创建渲染器对象
    const renderer = new THREE.WebGLRenderer();
    // 相机
    CameraFn(renderer,camera)

    // 设置相机空间轨道控制器
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.addEventListener("change", function () {
        renderer.render(scene, camera);
    });
})


function CameraFn(renderer,camera){
    camera.position.set(-1000, 800, 800); // 设置相机位置
    camera.lookAt(0, 10, 0);

    renderer.setSize(width, height);
    renderer.render(scene, camera);
    document.body.appendChild(renderer.domElement);
}

// 各部件外框线
function borderLine(BoxGeometry, Mesh, color = 0xffffff) {
    let edgesGeometry = new THREE.EdgesGeometry(BoxGeometry)
    let edgesMaterial = new THREE.LineBasicMaterial({
        color: color,
        linewidth: 2
    })
    let line = new THREE.LineSegments(edgesGeometry, edgesMaterial)
    scene.add(line)
}

 


网站公告

今日签到

点亮在社区的每一天
去签到