babylonjs note 05 build a village (07) Face Materials

141 阅读1分钟

In the faceUV array faces are numbered 0 for back, 1 front, 2 right, 3 left, 4 top and 5 bottom.

cubehouse.png

上图的左下角 被定义为 (0, 0) , 右上角被定义为 (1, 1) , 无论图片的形状看起来像什么,整幅图的左下角都被定义 ,为 (0, 0) , 右上角被定义为 (1, 1), 在 UV 面贴图是这样理解的。

2023-11-29_14-15.png

const faceUV = [];
faceUV[0] = new BABYLON.Vector4(0.5, 0.0, 0.75, 1.0); //rear face
faceUV[1] = new BABYLON.Vector4(0.0, 0.0, 0.25, 1.0); //front face
faceUV[2] = new BABYLON.Vector4(0.25, 0, 0.5, 1.0); //right side
faceUV[3] = new BABYLON.Vector4(0.75, 0, 1.0, 1.0); //left side

如果对某个面设置了 UV 则使用贴图对应部分映射,否则用整幅图映射

const box = BABYLON.MeshBuilder.CreateBox("box", {faceUV: faceUV, wrap: true});

完整实例代码:

import { ArcRotateCamera, Color3, HemisphericLight, MeshBuilder, Scene, Texture, StandardMaterial, Vector3, Vector4 } from "@babylonjs/core";
import { createApp } from "../utils";

const app = createApp((canvas, engine) => {
    const scene = new Scene(engine);

    /**** Set camera and light *****/
    const camera = new ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 15, Vector3.Zero(), scene);
    camera.attachControl(canvas, true);

    const light = new HemisphericLight('light', new Vector3(1, 1, 0), scene);

    // customize your scene here

    /**** Materials *****/
    // color
    const groundMat = new StandardMaterial('groundMat', scene);
    groundMat.diffuseColor = new Color3(0, 1, 0);

    // texture

    const roofMat = new StandardMaterial('roofMat', scene);
    roofMat.diffuseTexture = new Texture('assets/texture/ex01/roof.jpg', scene)

    const boxMat = new StandardMaterial('boxMat', scene);
    boxMat.diffuseTexture = new Texture('assets/texture/ex01/cubehouse.png', scene);

    //options parameter to set different images on each side
    const faceUV = [];
    faceUV[0] = new Vector4(0.5, 0, 0.75, 1);  //rear face
    faceUV[1] = new Vector4(0, 0, 0.25, 1); //front face
    faceUV[2] = new Vector4(0.25, 0, 0.5, 1); //right side
    faceUV[3] = new Vector4(0.75, 0, 1, 1); //left side
    // top 4 and bottom 5 not seen so not set

    const ground = MeshBuilder.CreateGround("ground", { width: 10, height: 10 }, scene);
    ground.material = groundMat;

    /**** World Objects *****/
    const box = MeshBuilder.CreateBox("box", { width: 1, height: 1, depth: 1, faceUV, wrap: true }, scene);
    box.material = boxMat;
    box.position.y = 0.5;

    const roof = MeshBuilder.CreateCylinder("roof", { height: 1.2, diameter: 1.3, tessellation: 3 }, scene);
    roof.material = roofMat;

    roof.scaling.x = 0.75;
    roof.rotation.z = Math.PI / 2;
    roof.position.y = 1.22;

    return scene;
})

app.run();