如何

为过程纹理库创建过程纹理


本教程将指导您完成为过程纹理库创建过程纹理的过程

搭建环境

首先,您需要在/ proceduralTexturesLibrary / src文件夹中为着色器创建一个文件夹。我们称它为cloudBis。

然后,您需要创建文件:

  • 巴比伦。cloudBis ProceduralTexture.ts(只需从babylon.woodProceduralTexture.ts复制/粘贴)
  • loudBis ProceduralTexture.fragment.fx(只需从woodProceduralTexture.fragment.fx复制/粘贴)

要将新的过程纹理集成到构建过程中,必须编辑tools / gulp文件夹中的config.json文件,并在该文件的“ proceduralTextureLibrary / libraries”部分中添加一个条目:

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

要构建所有过程纹理并生成dist文件夹,只需从tools / gulp文件夹运行:

gulp proceduralTextureLibrary

更新着色器

打开cloudBisProceduralTexture.fragment.fx文件。着色器由3部分组成:

  • 变量和制服的定义
precision highp float;

varying vec2 vUV;

uniform vec4 skyColor;
uniform vec4 cloudColor;
  • 您需要的所有功能(此处为rand,noise和fbm)
float rand(vec2 n) {
    return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
}

float noise(vec2 n) {
    const vec2 d = vec2(0.0, 1.0);
    vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
    return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
}

float fbm(vec2 n) {
    float total = 0.0, amplitude = 1.0;
    for (int i = 0; i < 4; i++) {
        total += noise(n) * amplitude;
        n += n;
        amplitude *= 0.5;
    }
    return total;
}
  • 的主要功能是一个叫得到的像素颜色
void main() {
    vec2 p = vUV * 12.0;
    vec4 c = mix(skyColor, cloudColor, fbm(p));
    gl_FragColor = c;
}

编写程序纹理

程序纹理是.ts文件。它包含一个必须从ProceduralTexture类继承的类。

为了确保您拥有intelliSense并确保编译阶段运行良好,您必须在babylon.cloudBisProceduralTexture.ts文件的顶部添加一个引用:

/// <reference path="../css/../dist/preview release/babylon.d.ts"/>

程序纹理的魔术的主要部分发生在着色器文件中。将输出文件主要是在这里给它的调用者制服设定值,并把它传递给着色器本身的能力。按照惯例,我们创建一个名为功能updateShaderUniforms()将来自construtor,并在每制定者为每个属性被调用。

这是CloudBisProceduralTexture的示例

如您所见,setXXX函数用于将特定值发送到着色器。

使用超级函数在构造函数中按其名称调用着色器。

module BABYLON {
    export class CloudBisProceduralTexture extends ProceduralTexture {
        private _skyColor = new Color4(0.15, 0.68, 1.0, 1.0);
        private _cloudColor = new Color4(1, 1, 1, 1.0);

        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
            super(name, size, "cloudProceduralTexture", scene, fallbackTexture, generateMipMaps);
            this.updateShaderUniforms();
            this.refreshRate = 0;
        }

        public updateShaderUniforms() {
            this.setColor4("skyColor", this._skyColor);
            this.setColor4("cloudColor", this._cloudColor);
        }

        public get skyColor(): Color4 {
            return this._skyColor;
        }

        public set skyColor(value: Color4) {
            this._skyColor = value;
            this.updateShaderUniforms();
        }

        public get cloudColor(): Color4 {
            return this._cloudColor;
        }

        public set cloudColor(value: Color4) {
            this._cloudColor = value;
            this.updateShaderUniforms();
        }
    }
}

更新测试页

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

然后添加程序纹理管线192:

var cloudBis = new BABYLON.CloudBisProceduralTexture("cloudPTBis", 256, scene);

最后更新UI控件:

    gui.add(options, 'texture', ['default', 'fire', 'wood', 'cloud', 'grass', 'road', 'brick', 'marble', 'starfield', 'cloudBis']).onFinishChange(function () {
                    resetPTOptions();
                    switch (options.texture) {
                        case "fire":
                            currentTexture = firePT;
                            addPToptions(firePT, ['time', 'alphaThreshold', 'speed', ]);
                            break;
                        case "wood":
                            currentTexture = woodPT;
                            addPToptions(woodPT, ['ampScale', 'woodColor']);
                            break;
                        case "cloud":
                            currentTexture = cloudPT;
                            addPToptions(cloudPT, ['skyColor', 'cloudColor']);
                            break;
                        case "grass":
                            currentTexture = grassPT;
                            addPToptions(grassPT, ['groundColor']);
                            break;
                        case "road":
                            currentTexture = roadPT;
                            addPToptions(roadPT, ['roadColor']);
                            break;
                        case "brick":
                            currentTexture = brickPT;
                            addPToptions(brickPT, ['numberOfBricksHeight', 'numberOfBricksWidth', 'brickColor', 'jointColor']);
                            break;
                        case "marble":
                            currentTexture = marblePT;
                            addPToptions(marblePT, ['numberOfTilesHeight', 'numberOfTilesWidth', 'amplitude', 'jointColor']);
                            break;
                        case "starfield":
                            currentTexture = starfieldPT;
                            addPToptions(starfieldPT, ['saturation', 'distfading', 'darkmatter', 'alpha', 'time', 'beta', 'zoom', 'formuparam', 'stepsize', 'tile', 'brightness']);
                            break;
                        case "cloudBis":
                            currentTexture = cloudBis;
                            break;
                        case "none":
                        default:
                            currentTexture = diffuseTexture;
                            break;
                    }

                    std.diffuseTexture = currentTexture;
                    window.enableTexture(options.texture);
                });

(可选)启用图形界面。

如果过程纹理包含允许开发人员对其进行自定义的属性,则可以启用界面以在示例中实时更改它们。

为此,您只需要在您的情况下添加对addPToptions帮助器函数的调用

您的代码将如下所示:

case "cloudBis":
currentTexture = cloudBis;
addPToptions(cloudBis, ['skyColor', 'cloudColor']);
break;

第一个参数是纹理对象,第二个参数是一个数组,其中包含要在示例中使其可编辑的属性的列表。

启动测试服务器

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

gulp webserver