BABYLON.Effect.ShadersStore["guiTextureImageFragmentShader"] = ` precision highp float; // Samplers varying vec2 vUV; uniform sampler2D textureSampler; uniform sampler2D customTextureSampler; // Parameters uniform vec2 bottomLeft, topRight; uniform float width, height; uniform vec4 backgroundColor; vec3 mask = normalize(vec3(0.2, 0.4, 0.8)); float insideBox(vec2 v) { vec2 s = step(bottomLeft, v) - step(topRight, v); return s.x * s.y; } void main(void) { float x = (vUV.x - bottomLeft.x) / width; float y = (vUV.y - topRight.y) / height; vec4 orgPixel = texture2D(textureSampler, vUV); if(dot(normalize(orgPixel.xyz * insideBox(vUV)), mask) > 0.99){ vec4 pixel = texture2D(customTextureSampler, vec2(x, y)); gl_FragColor = pixel + backgroundColor * (1.0 - pixel.w); } else { gl_FragColor = orgPixel; } } `; class TextureImage extends BABYLON.GUI.Control { private static CTX: CanvasRenderingContext2D; private _scene: BABYLON.Scene; private postProcess: BABYLON.PostProcess; public readonly mask = '#3366CC'; private uniformsDirty = false; private onBeforeRenderObserver: BABYLON.Observer; constructor(public texture: BABYLON.BaseTexture) { super(); this.onBeforeDrawObservable.addOnce(() => { this._scene = this.host.getScene(); this.addPostProcess(); this.onBeforeRenderObserver = this._scene.onBeforeRenderObservable.add(() => { if (this.uniformsDirty) { this.applyUniforms(); } }); this.onDirtyObservable.add(() => { this.uniformsDirty = true; }); }); } public _draw(context: CanvasRenderingContext2D) { context.fillStyle = this.mask; context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height); } private addPostProcess() { this.postProcess = new BABYLON.PostProcess("guiTexturePostProcess", "guiTextureImage", ["screenSize", "bottomLeft", "topRight", "width", "height", "backgroundColor"], ["customTextureSampler"], 1.0, this._scene.activeCamera); this.postProcess.onApply = (effect) => { this.applyUniforms(); }; } private applyUniforms() { let effect = this.postProcess.getEffect(); if (effect) { let size = this.host.getSize(); let width = size.width; let height = size.height; effect.setTexture('customTextureSampler', this.texture); effect.setFloat2('bottomLeft', this._currentMeasure.left / width, 1 - (this._currentMeasure.top + this._currentMeasure.height) / height); effect.setFloat2('topRight', (this._currentMeasure.left + this._currentMeasure.width) / width, 1 - this._currentMeasure.top / height); effect.setFloat('width', this.widthInPixels / width); effect.setFloat('height', this.heightInPixels / height); effect.setVector4('backgroundColor', TextureImage.ColorFromString(this.color)); } } private static GetContext() { if (!TextureImage.CTX) { let canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = 1; TextureImage.CTX = canvas.getContext('2d'); } return TextureImage.CTX; } private static ColorFromString(str: string) { let ctx = TextureImage.GetContext(); ctx.fillStyle = str; ctx.fillRect(0, 0, 1, 1); let pixel = ctx.getImageData(0, 0, 1, 1).data; return new BABYLON.Vector4(pixel[0], pixel[1], pixel[2], pixel[3]).scale(1 / 255); } dispose() { this._scene.onBeforeRenderObservable.remove(this.onBeforeRenderObserver); super.dispose(); } } (BABYLON.GUI).TextureImage = TextureImage;