playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
257 lines (256 loc) • 6.83 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
import { FUNC_ALWAYS, STENCILOP_KEEP } from "./constants.js";
import { StringIds } from "../../core/string-ids.js";
const stringIds = new StringIds();
const _StencilParameters = class _StencilParameters {
/**
* Create a new StencilParameters instance.
*
* @param {object} [options] - Options object to configure the stencil parameters.
*/
constructor(options = {}) {
/**
* @type {number}
* @private
*/
__publicField(this, "_func");
/**
* @type {number}
* @private
*/
__publicField(this, "_ref");
/**
* @type {number}
* @private
*/
__publicField(this, "_fail");
/**
* @type {number}
* @private
*/
__publicField(this, "_zfail");
/**
* @type {number}
* @private
*/
__publicField(this, "_zpass");
/**
* @type {number}
* @private
*/
__publicField(this, "_readMask");
/**
* @type {number}
* @private
*/
__publicField(this, "_writeMask");
/** @private */
__publicField(this, "_dirty", true);
/**
* @type {number}
* @private
*/
__publicField(this, "_key");
this._func = options.func ?? FUNC_ALWAYS;
this._ref = options.ref ?? 0;
this._readMask = options.readMask ?? 255;
this._writeMask = options.writeMask ?? 255;
this._fail = options.fail ?? STENCILOP_KEEP;
this._zfail = options.zfail ?? STENCILOP_KEEP;
this._zpass = options.zpass ?? STENCILOP_KEEP;
this._evalKey();
}
/**
* Sets the comparison function that decides if the pixel should be written, based on the
* current stencil buffer value, reference value, and mask value. Can be:
*
* - {@link FUNC_NEVER}: never pass
* - {@link FUNC_LESS}: pass if (ref & mask) < (stencil & mask)
* - {@link FUNC_EQUAL}: pass if (ref & mask) == (stencil & mask)
* - {@link FUNC_LESSEQUAL}: pass if (ref & mask) <= (stencil & mask)
* - {@link FUNC_GREATER}: pass if (ref & mask) > (stencil & mask)
* - {@link FUNC_NOTEQUAL}: pass if (ref & mask) != (stencil & mask)
* - {@link FUNC_GREATEREQUAL}: pass if (ref & mask) >= (stencil & mask)
* - {@link FUNC_ALWAYS}: always pass
*
* @type {number}
*/
set func(value) {
this._func = value;
this._dirty = true;
}
/**
* Sets the comparison function that decides if the pixel should be written.
*
* @type {number}
*/
get func() {
return this._func;
}
/**
* Sets the stencil test reference value used in comparisons.
*
* @type {number}
*/
set ref(value) {
this._ref = value;
this._dirty = true;
}
/**
* Gets the stencil test reference value used in comparisons.
*
* @type {number}
*/
get ref() {
return this._ref;
}
/**
* Sets the operation to perform if stencil test is failed. Can be:
*
* - {@link STENCILOP_KEEP}: don't change the stencil buffer value
* - {@link STENCILOP_ZERO}: set value to zero
* - {@link STENCILOP_REPLACE}: replace value with the reference value.
* - {@link STENCILOP_INCREMENT}: increment the value
* - {@link STENCILOP_INCREMENTWRAP}: increment the value, but wrap it to zero when it's larger
* than a maximum representable value
* - {@link STENCILOP_DECREMENT}: decrement the value
* - {@link STENCILOP_DECREMENTWRAP}: decrement the value, but wrap it to a maximum
* representable value, if the current value is 0
* - {@link STENCILOP_INVERT}: invert the value bitwise
*
* @type {number}
*/
set fail(value) {
this._fail = value;
this._dirty = true;
}
/**
* Gets the operation to perform if stencil test is failed.
*
* @type {number}
*/
get fail() {
return this._fail;
}
/**
* Sets the operation to perform if depth test is failed. Accepts the same values as `fail`.
*
* @type {number}
*/
set zfail(value) {
this._zfail = value;
this._dirty = true;
}
/**
* Gets the operation to perform if depth test is failed.
*
* @type {number}
*/
get zfail() {
return this._zfail;
}
/**
* Sets the operation to perform if both stencil and depth test are passed. Accepts the same
* values as `fail`.
*
* @type {number}
*/
set zpass(value) {
this._zpass = value;
this._dirty = true;
}
/**
* Gets the operation to perform if both stencil and depth test are passed.
*
* @type {number}
*/
get zpass() {
return this._zpass;
}
/**
* Sets the mask applied to stencil buffer value and reference value before comparison.
*
* @type {number}
*/
set readMask(value) {
this._readMask = value;
this._dirty = true;
}
/**
* Gets the mask applied to stencil buffer value and reference value before comparison.
*
* @type {number}
*/
get readMask() {
return this._readMask;
}
/**
* Sets the bit mask applied to the stencil value when written.
*
* @type {number}
*/
set writeMask(value) {
this._writeMask = value;
this._dirty = true;
}
/**
* Gets the bit mask applied to the stencil value when written.
*
* @type {number}
*/
get writeMask() {
return this._writeMask;
}
_evalKey() {
const { _func, _ref, _fail, _zfail, _zpass, _readMask, _writeMask } = this;
const key = `${_func},${_ref},${_fail},${_zfail},${_zpass},${_readMask},${_writeMask}`;
this._key = stringIds.get(key);
this._dirty = false;
}
get key() {
if (this._dirty) {
this._evalKey();
}
return this._key;
}
/**
* Copies the contents of a source stencil parameters to this stencil parameters.
*
* @param {StencilParameters} rhs - A stencil parameters to copy from.
* @returns {StencilParameters} Self for chaining.
*/
copy(rhs) {
this._func = rhs._func;
this._ref = rhs._ref;
this._readMask = rhs._readMask;
this._writeMask = rhs._writeMask;
this._fail = rhs._fail;
this._zfail = rhs._zfail;
this._zpass = rhs._zpass;
this._dirty = rhs._dirty;
this._key = rhs._key;
return this;
}
/**
* Clone the stencil parameters.
*
* @returns {StencilParameters} A cloned StencilParameters object.
*/
clone() {
const clone = new this.constructor();
return clone.copy(this);
}
};
/**
* A default stencil state.
*
* @type {StencilParameters}
* @readonly
*/
__publicField(_StencilParameters, "DEFAULT", Object.freeze(new _StencilParameters()));
let StencilParameters = _StencilParameters;
export {
StencilParameters
};