Home Reference Source

src/effects/ColorDepthEffect.js

import { Uniform } from "three";
import { Effect } from "./Effect.js";

import fragmentShader from "./glsl/color-depth.frag";

/**
 * A color depth effect.
 *
 * Simulates a hardware limitation to create a retro feel. The real color depth remains unchanged.
 */

export class ColorDepthEffect extends Effect {

	/**
	 * Constructs a new color depth effect.
	 *
	 * @param {Object} [options] - The options.
	 * @param {BlendFunction} [options.blendFunction] - The blend function of this effect.
	 * @param {Number} [options.bits=16] - The color bit depth.
	 */

	constructor({ blendFunction, bits = 16 } = {}) {

		super("ColorDepthEffect", fragmentShader, {
			blendFunction,
			uniforms: new Map([
				["factor", new Uniform(1.0)]
			])
		});

		/**
		 * The current amount of bits.
		 *
		 * @type {Number}
		 * @private
		 */

		this.bits = 0;
		this.bitDepth = bits;

	}

	/**
	 * The virtual amount of color bits.
	 *
	 * Each color channel effectively uses a fourth of the total amount of bits. Alpha remains unaffected.
	 *
	 * @type {Number}
	 */

	get bitDepth() {

		return this.bits;

	}

	set bitDepth(value) {

		this.bits = value;
		this.uniforms.get("factor").value = Math.pow(2.0, value / 3.0);

	}

	/**
	 * Returns the current color bit depth.
	 *
	 * @return {Number} The bit depth.
	 */

	getBitDepth() {

		return this.bitDepth;

	}

	/**
	 * Sets the virtual amount of color bits.
	 *
	 * @param {Number} value - The bit depth.
	 */

	setBitDepth(value) {

		this.bitDepth = value;

	}

}