天天看點

Babylon.js 第21章 材質映射到網格+貼花

目錄

 一、 表面網格

二、正面與背面的網格

三、對不同網格使用多材料

四、網格貼花

 貼花示例:

 一、 表面網格

let col=6
    let row=4
    let faceUV=new Array(6)
    
    for(let i=0;i<6;i++){
        faceUV[i]=new BABYLON.Vector4(i/col,0,(i+1)/col,1/4)
    }
    /*
    *面上的圖像反轉
    faceUV[0]=new BABYLON.Vector4(0,0,1/2,1/4)
    let temp=faceUV[0].x
    faceUV[0].x=faceUV[0].z
    faceUV[0].z=temp
    let temp1=faceUV[0].y
    faceUV[0].y=faceUV[0].w
    faceUV[0].w=temp1
    */

    let faceColor=new Array(6)
    //應用顔色
    faceColor[0]=new BABYLON.Color4(1,1,0,0)
    faceColor[4]=new BABYLON.Color4(0,0,1,0)
    let box=BABYLON.MeshBuilder.CreateBox(
        'box',
        {width:10,height:5,depth:5,faceUV:faceUV,
        wrap:true,topBaseAt:0,faceColors:faceColor},
        scene
    )
    box.material=sphereMaterial
    sphere.material=sphereMaterial
           

必須使用MeshBuilder才能自定義面上的網格圖像。當然faceUV的Vector4有四個參數(x,y,z,w),其實際意思很簡單,就是圖像的比例,x,y,左下角開始的一個坐标,z,w,右上角的一個坐标,隻是其取值是圖像的比例,介于0到1之間。(0,0,0.5,1),意識就是截取圖像左半部分的圖像。依此類推。

option對象參數:

  • wrap - 布爾值(預設 = false),當為 true 時,所有垂直邊 (0, 1, 2, 3) 将在正确的垂直方向上應用圖像紋理,兩個水準邊 (4, 5) 将應用圖像紋理,以便當框圍繞 x 軸旋轉以使這些邊垂直時,應用的圖像紋理将以其原始方向應用;
  • topBaseAt - 整數,0, 1, 2, 3,(預設 = 1),框頂部圖像的底部(底部)緊挨着給定數字的一側;
  • bottomBaseAt- 整數,0, 1, 2, 3,(預設 = 0),框底部圖像的底部(底)緊挨着給定數字的一側。

faceColor也是對應面上應用顔色。

圓柱體的面:圓柱體具有三個表面,頂部、底部和連接配接它們的管子。對于面選項,面 0 是底部,面 1 是管,面 2 是頂部。

擠壓多邊形具有頂部、底部和擠壓邊三個表面,面 0 是頂部,面 1 是擠壓邊,面 2 是底部。

可以将紋理圖集與所有多面體一起使用,但是如果不仔細考慮紋理圖集的性質,結果可能看起來有點随機。 

二、正面與背面的網格

frontUVs 和 backUVs 都具有 Vector4(u0, v0, u1, v1) 的形式,其中 0<= u0, v0, u1, v1 <= 1 和 (u0, v0) 是左下角坐标, (u1, v1) 是頂部坐标圖像剪切矩形的右坐标。

要拆分上面的圖像,您可以形成兩個變量

let f=new BABYLON.Vector4(0,0,0.5,1)
    let b=new BABYLON.Vector4(0.5,0,1,1)
    let plane=BABYLON.MeshBuilder.CreatePlane(
        'p',
        {
            height:10,
            width:10,
            sideOrientation:BABYLON.Mesh.DOUBLESIDE,
            frontUVS:f,
            backUVs:b
        },
        scene
    )
    let planeMat=new BABYLON.StandardMaterial('mat',scene)
    planeMat.diffuseTexture=new BABYLON.Texture('../img/test.jpg',scene)
    plane.material=planeMat
           
Babylon.js 第21章 材質映射到網格+貼花

三、對不同網格使用多材料

let mat0=new BABYLON.StandardMaterial('mat0',scene)
    mat0.diffuseColor=new BABYLON.Color3(1,0,1)
    mat0.bumpTexture=new BABYLON.Texture('../img/4.png',scene)
    let mat1=new BABYLON.StandardMaterial('mat1',scene)
    mat1.diffuseColor=new BABYLON.Color3(0,0,1)
    let mat2=new BABYLON.StandardMaterial('mat2',scene)
    mat2.emissiveColor=new BABYLON.Color3(1,0,0)

    let multimat=new BABYLON.MultiMaterial('mutl',scene)
    multimat.subMaterials.push(mat0)
    multimat.subMaterials.push(mat1)
    multimat.subMaterials.push(mat2)
    sphere.material=multimat
    sphere.subMeshes=[]
    //擷取定點數
    let verticesCount=sphere.getTotalVertices()
    new BABYLON.SubMesh(0,0,verticesCount,0,3000,sphere)
    new BABYLON.SubMesh(1,0,verticesCount,3000,6000,sphere)
    new BABYLON.SubMesh(2,0,verticesCount,6000,7870,sphere)
           

在這種情況下,您将有 3 個部分:

  • 一個從索引 0 開始到索引 900
  • 一個從索引 900 到索引 1800
  • 一個從索引 1800 開始到索引 3880

子網格定義為:

  • 要使用的材質的索引(該索引用于在多材質的subMaterials集合中找到正确的材質)
  • 第一個頂點的索引和使用的頂點數(例如,為了優化碰撞)
  • 要使用的第一個索引的索引和索引計數
  • 父網格

是以,使用上面的代碼,您可以在球體頂部使用第一種材料,在中間部分使用第二種材料,在球體底部使用最後一種材料。

四、合并網格

let mat0=new BABYLON.StandardMaterial('mat0',scene)
    mat0.diffuseColor=new BABYLON.Color3(1,0,1)
    mat0.bumpTexture=new BABYLON.Texture('../img/4.png',scene)
    let mat1=new BABYLON.StandardMaterial('mat1',scene)
    mat1.diffuseColor=new BABYLON.Color3(0,0,1)
    let mat2=new BABYLON.StandardMaterial('mat2',scene)
    mat2.emissiveColor=new BABYLON.Color3(1,0,0)
    sphere.material=mat2
    let box=new BABYLON.MeshBuilder.CreateBox('box',
        {width:3,height:15,depth:2},scene)
    box.position.z=-2
    
    box.material=mat1
    let mesh=BABYLON.Mesh.MergeMeshes(
        [sphere,box],
        sphere,
        true,
        undefined,
        false,
        true
        /*
        *将最終參數multiMultiMaterial設定為 true 時,
        *将自動建立包含所有合并網格的子網格的子網格數組。
        *每個 subMesh 的材質也包含在生成的網格的新 multiMaterial 中。
        */
        )
           

 将最後一個參數multiMultiMaterial設定為 true 時,将自動建立包含所有合并網格的子網格的子網格數組。每個 subMesh 的材質也包含在生成的網格的新 multiMaterial 中。此功能忽略參數 ( 

subdivideWithSubMeshes

)。

将倒數第二個參數 ( 

subdivideWithSubMeshes

) 設定為 true,但最後一個參數 ( 

multiMultiMaterial

) 保留為 false 時,将自動建立 subMeshes 數組,其中每個合并網格都作為新網格的子網格。您必須将正确的子網格索引配置設定給正确的材料索引。

mergedMesh

通過按此數組順序 [mesh1, mesh2] 合并網格來形成時,multiMaterials subMaterials 數組包含順序為 [mat1, mat2] 的材料,那麼對于 subMesh from

mesh2

具有

mat2

您需要設定的材料

Babylon.js 第21章 材質映射到網格+貼花

四、網格貼花

這些通常用于在網格上添加細節(子彈孔、局部細節等),貼花是從前一個網格的子集生成的網格,具有小的偏移量,以便出現在其頂部。

var decal = BABYLON.MeshBuilder.CreateDecal("decal", mesh,
    {position: myPos}, scene);
           
屬性 預設值
position (Vector3)貼花的位置(世界坐标) (0, 0, 0)
normal (Vector3) 貼花應用到的網格的法線(世界坐标) Vector3.Up
size (Vector3) 貼花的 x、y、z 尺寸 (1, 1, 1)
angle (數字)旋轉貼花的角度

 貼花示例:

let mat=new BABYLON.StandardMaterial('mat',scene)
    mat.diffuseTexture=new BABYLON.Texture('../img/太陽.png',scene)
    mat.diffuseTexture.hasAlpha=true
    mat.zOffset=-2
    
    let onPointerDown=evt=>{
        if(evt.button!==0){
            return
        }
        let pickInfo=scene.pick(scene.pointerX,
            scene.pointerY,mesh=>{return mesh===ground})
        if(pickInfo.hit){
            let decalSize=new BABYLON.Vector3(1,1,1)
            let opt={
                position:pickInfo.pickedPoint,
                normal:pickInfo.getNormal(true),
                size:decalSize
            }
            let decal=BABYLON.MeshBuilder.CreateDecal('decal',ground,opt,scene)
            decal.material=mat
        }
        
    }
    let canva=engine.getRenderingCanvas()
    canva.addEventListener('p',onPointerDown,false)
    scene.onDispose=()=>{
        canva.removeEventListener('p',onPointerDown)
    }
    canvas.addEventListener("pointerdown", onPointerDown, false);
    scene.onDispose = function () {
        canvas.removeEventListener("pointerdown", onPointerDown);
    }
           
Babylon.js 第21章 材質映射到網格+貼花

繼續閱讀