如何

为物料库创建物料


本教程将指导您完成为材料库创建材料的过程

搭建环境

首先,您需要在/ materialsLibrary / src文件夹中为着色器创建一个文件夹。我们称它为diffuseEmissive。然后,您需要创建文件:

  • babylon.diffuseEmissiveMaterial.ts(只需从babylon.simpleMaterial.ts复制/粘贴)
  • diffuseEmissive.vertex.fx(只需从simple.vertex.fx复制/粘贴)
  • diffuseEmissive.fragment.fx(只需从simple.fragment.fx复制/粘贴)

然后在tools / gulp中更新config.json文件,并在该文件的“ materialsLibrary / libraries”部分中添加一个条目:

  "libraries": [
    ...
      {
        "output": "babylon.triPlanarMaterial.min.js",
        "entry": "./legacy/legacy-triPlanar.ts",
        "preventLoadLibrary": true
      }
      ...
  ]

要构建所有资料并生成dist文件夹,只需从tools / gulp文件夹运行:

gulp materialsLibrary

更新着色器

因为我们使用了简单的材料作为源,所以我们已经拥有了完整的babylon.js材料所需的一切。简单的材料已经支持漫反射纹理。

为了增加对发射纹理的支持,让我们将此代码添加到diffuseEmissive.vertex.fx文件的标题中:

#ifdef EMISSIVE 
varying vec2 vEmissiveUV; 
uniform mat4 emissiveMatrix; 
uniform vec2 vEmissiveInfos; 
#endif

然后在主要功能中添加以下代码:

#ifdef EMISSIVE
    if (vEmissiveInfos.x == 0.)
    {
        vEmissiveUV = vec2(emissiveMatrix * vec4(uv, 1.0, 0.0));
    }
    else
    {
        vEmissiveUV = vec2(emissiveMatrix * vec4(uv2, 1.0, 0.0));
    }
#endif

此代码将生成正确的UV以从发射纹理读取。请注意,我们使用#ifdef来获取babylon.js智能着色器的利润。

然后,您必须更新片段着色器。首先将此代码添加到标题中:

#ifdef EMISSIVE
varying vec2 vEmissiveUV;
uniform sampler2D emissiveSampler;
uniform vec2 vEmissiveInfos;
#endif

然后在主函数的末尾(恰好在最后一行(gl_FragColor = ...)之前)添加以下代码:

#ifdef EMISSIVE
    color.rgb += texture2D(emissiveSampler, vEmissiveUV) * vEmissiveInfos.y;
#endif

更新资料

首先,重命名出现的所有SimpleMaterialDefines到DiffuseEmissiveMaterialDefines和SimpleMaterial到DiffuseEmissiveMaterial。

然后将此属性添加到SimpleMaterialDefines类:

public EMISSIVE = false;

将此属性添加到DiffuseEmissiveMaterial类中:

public emissiveTexture: BaseTexture;

然后转到isReady函数并在代码if (scene.textureEnabled)块中添加以下代码:

if (this.emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
    if (!this.emissiveTexture.isReady()) {
        return false;
    } else {
        needUVs = true;
        this._defines.EMISSIVE = true;
    }
}

下一个要更新的功能是bind。在//Textures注释后添加以下代码:

if (this.emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
    this._effect.setTexture("emissiveSampler", this.emissiveTexture);

    this._effect.setFloat2("vEmissiveInfos", this.emissiveTexture.coordinatesIndex, this.emissiveTexture.level);
    this._effect.setMatrix("emissiveMatrix", this.emissiveTexture.getTextureMatrix());
}

您可能还需要将此代码添加到clone函数:

if (this.emissiveTexture && this.emissiveTexture.clone) {
    newMaterial.emissiveTexture = this.emissiveTexture.clone();
}

为了完整起见,您还必须完成序列化和解析功能(仅在要将材料保存/加载到.babylon文件中时才需要)。请注意,序列化功能需要将完整的材料名称输出到serializationObject,如下所示:

serializationObject.customType = "BABYLON.SimplelMaterial";

材料就大功告成!现在该进行测试了。

更新测试页

要测试您的材料,请打开/materialsLibrary/index.html页面。参考是自动添加的。

然后在第120行添加材料:

var diffuseEmissive = new BABYLON.DiffuseEmissiveMaterial("diffuseEmissive", scene); 
diffuseEmissive.diffuseTexture = new BABYLON.Texture("textures/amiga.jpg", scene); 
diffuseEmissive.diffuseTexture.uScale = 5; 
diffuseEmissive.diffuseTexture.vScale = 5; 

diffuseEmissive.emissiveTexture = new BABYLON.Texture("textures/amiga.jpg", scene); 
diffuseEmissive.emissiveTexture.uScale = 10; 
diffuseEmissive.emissiveTexture.vScale = 10;

最后更新UI控件:

gui.add(options, 'material', ['standard', 'simple', 'diffuseEmissive']).onFinishChange(function () {
    switch (options.material) {
        case "diffuseEmissive":
            currentMaterial = diffuseEmissive;
            break;
        case "simple":
            currentMaterial = simple;
            break;
        default:
            currentMaterial = std;
            break;
        }

        currentMesh.material = currentMaterial;
    });

启动测试服务器

要启动服务器,可以从tools / gulp文件夹开始:

gulp webserver

Using 将材料与Babylon.js文件加载器一起使用

Babylon.js文件格式支持使用自定义材料。您必须提供serialize()和Parse()功能与旁边一个getClassName()功能。为了让装载者知道您的材料,您还需要使用您的材料将以下行添加到代码中:

Tools.RegisteredExternalClasses["MyMaterial"] = MyMaterial;

此代码会将您的类添加到受支持的外部类的列表中,以便加载器在加载引用了您的资料的.babylon文件时可以实例化该类。