Home Reference Source

src/materials/MaskMaterial.js

import { NoBlending, ShaderMaterial, Uniform, UnsignedByteType } from "three";
import { ColorChannel } from "../enums/ColorChannel.js";
import { MaskFunction } from "../enums/MaskFunction.js";

import fragmentShader from "./glsl/mask.frag";
import vertexShader from "./glsl/common.vert";

/**
 * A mask shader material.
 *
 * This material applies a mask texture to a buffer.
 */

export class MaskMaterial extends ShaderMaterial {

	/**
	 * Constructs a new mask material.
	 *
	 * @param {Texture} [maskTexture] - The mask texture.
	 */

	constructor(maskTexture = null) {

		super({
			name: "MaskMaterial",
			uniforms: {
				maskTexture: new Uniform(maskTexture),
				inputBuffer: new Uniform(null),
				strength: new Uniform(1.0)
			},
			blending: NoBlending,
			toneMapped: false,
			depthWrite: false,
			depthTest: false,
			fragmentShader,
			vertexShader
		});

		this.colorChannel = ColorChannel.RED;
		this.maskFunction = MaskFunction.DISCARD;

	}

	/**
	 * The input buffer.
	 *
	 * @type {Texture}
	 */

	set inputBuffer(value) {

		this.uniforms.inputBuffer.value = value;

	}

	/**
	 * Sets the input buffer.
	 *
	 * @deprecated Use inputBuffer instead.
	 * @param {Texture} value - The input buffer.
	 */

	setInputBuffer(value) {

		this.uniforms.inputBuffer.value = value;

	}

	/**
	 * The mask texture.
	 *
	 * @type {Texture}
	 */

	set maskTexture(value) {

		this.uniforms.maskTexture.value = value;
		delete this.defines.MASK_PRECISION_HIGH;

		if(value.type !== UnsignedByteType) {

			this.defines.MASK_PRECISION_HIGH = "1";

		}

		this.needsUpdate = true;

	}

	/**
	 * Sets the mask texture.
	 *
	 * @deprecated Use maskTexture instead.
	 * @param {Texture} value - The texture.
	 */

	setMaskTexture(value) {

		this.maskTexture = value;

	}

	/**
	 * Sets the color channel to use for masking. Default is `ColorChannel.RED`.
	 *
	 * @type {ColorChannel}
	 */

	set colorChannel(value) {

		this.defines.COLOR_CHANNEL = value.toFixed(0);
		this.needsUpdate = true;

	}

	/**
	 * Sets the color channel to use for masking. Default is `ColorChannel.RED`.
	 *
	 * @deprecated Use colorChannel instead.
	 * @param {ColorChannel} value - The channel.
	 */

	setColorChannel(value) {

		this.colorChannel = value;

	}

	/**
	 * The masking technique. Default is `MaskFunction.DISCARD`.
	 *
	 * @type {MaskFunction}
	 */

	set maskFunction(value) {

		this.defines.MASK_FUNCTION = value.toFixed(0);
		this.needsUpdate = true;

	}

	/**
	 * Sets the masking technique. Default is `MaskFunction.DISCARD`.
	 *
	 * @deprecated Use maskFunction instead.
	 * @param {MaskFunction} value - The function.
	 */

	setMaskFunction(value) {

		this.maskFunction = value;

	}

	/**
	 * Indicates whether the masking is inverted.
	 *
	 * @type {Boolean}
	 */

	get inverted() {

		return (this.defines.INVERTED !== undefined);

	}

	set inverted(value) {

		if(this.inverted && !value) {

			delete this.defines.INVERTED;

		} else if(value) {

			this.defines.INVERTED = "1";

		}

		this.needsUpdate = true;

	}

	/**
	 * Indicates whether the masking is inverted.
	 *
	 * @deprecated Use inverted instead.
	 * @return {Boolean} Whether the masking is inverted.
	 */

	isInverted() {

		return this.inverted;

	}

	/**
	 * Determines whether the masking should be inverted.
	 *
	 * @deprecated Use inverted instead.
	 * @param {Boolean} value - Whether the masking should be inverted.
	 */

	setInverted(value) {

		this.inverted = value;

	}

	/**
	 * The current mask strength.
	 *
	 * Individual mask values will be clamped to [0.0, 1.0]. Has no effect when the mask function is set to `DISCARD`.
	 *
	 * @type {Number}
	 */

	get strength() {

		return this.uniforms.strength.value;

	}

	set strength(value) {

		this.uniforms.strength.value = value;

	}

	/**
	 * Returns the current mask strength.
	 *
	 * @deprecated Use strength instead.
	 * @return {Number} The mask strength.
	 */

	getStrength() {

		return this.strength;

	}

	/**
	 * Sets the mask strength.
	 *
	 * Has no effect when the mask function is set to `DISCARD`.
	 *
	 * @deprecated Use strength instead.
	 * @param {Number} value - The mask strength.
	 */

	setStrength(value) {

		this.strength = value;

	}

}