Home Reference Source

src/materials/DepthMaskMaterial.js

  1. import {
  2. AlwaysDepth,
  3. BasicDepthPacking,
  4. EqualDepth,
  5. GreaterDepth,
  6. GreaterEqualDepth,
  7. LessDepth,
  8. LessEqualDepth,
  9. NeverDepth,
  10. NoBlending,
  11. NotEqualDepth,
  12. PerspectiveCamera,
  13. ShaderMaterial,
  14. Uniform,
  15. Vector2
  16. } from "three";
  17.  
  18. import { DepthTestStrategy } from "../enums/DepthTestStrategy.js";
  19.  
  20. import fragmentShader from "./glsl/depth-mask.frag";
  21. import vertexShader from "./glsl/common.vert";
  22.  
  23. /**
  24. * A depth mask shader material.
  25. *
  26. * This material masks a color buffer by comparing two depth textures.
  27. */
  28.  
  29. export class DepthMaskMaterial extends ShaderMaterial {
  30.  
  31. /**
  32. * Constructs a new depth mask material.
  33. */
  34.  
  35. constructor() {
  36.  
  37. super({
  38. name: "DepthMaskMaterial",
  39. defines: {
  40. DEPTH_EPSILON: "0.0001",
  41. DEPTH_PACKING_0: "0",
  42. DEPTH_PACKING_1: "0",
  43. DEPTH_TEST_STRATEGY: DepthTestStrategy.KEEP_MAX_DEPTH
  44. },
  45. uniforms: {
  46. inputBuffer: new Uniform(null),
  47. depthBuffer0: new Uniform(null),
  48. depthBuffer1: new Uniform(null),
  49. cameraNearFar: new Uniform(new Vector2(1, 1))
  50. },
  51. blending: NoBlending,
  52. toneMapped: false,
  53. depthWrite: false,
  54. depthTest: false,
  55. fragmentShader,
  56. vertexShader
  57. });
  58.  
  59. this.depthMode = LessDepth;
  60.  
  61. }
  62.  
  63. /**
  64. * The primary depth buffer.
  65. *
  66. * @type {Texture}
  67. */
  68.  
  69. set depthBuffer0(value) {
  70.  
  71. this.uniforms.depthBuffer0.value = value;
  72.  
  73. }
  74.  
  75. /**
  76. * The primary depth packing strategy.
  77. *
  78. * @type {DepthPackingStrategies}
  79. */
  80.  
  81. set depthPacking0(value) {
  82.  
  83. this.defines.DEPTH_PACKING_0 = value.toFixed(0);
  84. this.needsUpdate = true;
  85.  
  86. }
  87.  
  88. /**
  89. * Sets the base depth buffer.
  90. *
  91. * @deprecated Use depthBuffer0 and depthPacking0 instead.
  92. * @param {Texture} buffer - The depth texture.
  93. * @param {DepthPackingStrategies} [depthPacking=BasicDepthPacking] - The depth packing strategy.
  94. */
  95.  
  96. setDepthBuffer0(buffer, depthPacking = BasicDepthPacking) {
  97.  
  98. this.depthBuffer0 = buffer;
  99. this.depthPacking0 = depthPacking;
  100.  
  101. }
  102.  
  103. /**
  104. * The secondary depth buffer.
  105. *
  106. * @type {Texture}
  107. */
  108.  
  109. set depthBuffer1(value) {
  110.  
  111. this.uniforms.depthBuffer1.value = value;
  112.  
  113. }
  114.  
  115. /**
  116. * The secondary depth packing strategy.
  117. *
  118. * @type {DepthPackingStrategies}
  119. */
  120.  
  121. set depthPacking1(value) {
  122.  
  123. this.defines.DEPTH_PACKING_1 = value.toFixed(0);
  124. this.needsUpdate = true;
  125.  
  126. }
  127.  
  128. /**
  129. * Sets the depth buffer that will be compared with the base depth buffer.
  130. *
  131. * @deprecated Use depthBuffer1 and depthPacking1 instead.
  132. * @param {Texture} buffer - The depth texture.
  133. * @param {DepthPackingStrategies} [depthPacking=BasicDepthPacking] - The depth packing strategy.
  134. */
  135.  
  136. setDepthBuffer1(buffer, depthPacking = BasicDepthPacking) {
  137.  
  138. this.depthBuffer1 = buffer;
  139. this.depthPacking1 = depthPacking;
  140.  
  141. }
  142.  
  143. /**
  144. * The strategy for handling maximum depth.
  145. *
  146. * @type {DepthTestStrategy}
  147. */
  148.  
  149. get maxDepthStrategy() {
  150.  
  151. return Number(this.defines.DEPTH_TEST_STRATEGY);
  152.  
  153. }
  154.  
  155. set maxDepthStrategy(value) {
  156.  
  157. this.defines.DEPTH_TEST_STRATEGY = value.toFixed(0);
  158. this.needsUpdate = true;
  159.  
  160. }
  161.  
  162. /**
  163. * Indicates whether maximum depth values should be preserved.
  164. *
  165. * @type {Boolean}
  166. * @deprecated Use maxDepthStrategy instead.
  167. */
  168.  
  169. get keepFar() {
  170.  
  171. return this.maxDepthStrategy;
  172.  
  173. }
  174.  
  175. set keepFar(value) {
  176.  
  177. this.maxDepthStrategy = value ? DepthTestStrategy.KEEP_MAX_DEPTH : DepthTestStrategy.DISCARD_MAX_DEPTH;
  178.  
  179. }
  180.  
  181. /**
  182. * Returns the strategy for dealing with maximum depth values.
  183. *
  184. * @deprecated Use maxDepthStrategy instead.
  185. * @return {DepthTestStrategy} The strategy.
  186. */
  187.  
  188. getMaxDepthStrategy() {
  189.  
  190. return this.maxDepthStrategy;
  191.  
  192. }
  193.  
  194. /**
  195. * Sets the strategy for dealing with maximum depth values.
  196. *
  197. * @deprecated Use maxDepthStrategy instead.
  198. * @param {DepthTestStrategy} value - The strategy.
  199. */
  200.  
  201. setMaxDepthStrategy(value) {
  202.  
  203. this.maxDepthStrategy = value;
  204.  
  205. }
  206.  
  207. /**
  208. * A small error threshold that is used for `EqualDepth` and `NotEqualDepth` tests. Default is `1e-4`.
  209. *
  210. * @type {Number}
  211. */
  212.  
  213. get epsilon() {
  214.  
  215. return Number(this.defines.DEPTH_EPSILON);
  216.  
  217. }
  218.  
  219. set epsilon(value) {
  220.  
  221. this.defines.DEPTH_EPSILON = value.toFixed(16);
  222. this.needsUpdate = true;
  223.  
  224. }
  225.  
  226. /**
  227. * Returns the current error threshold for depth comparisons.
  228. *
  229. * @deprecated Use epsilon instead.
  230. * @return {Number} The error threshold.
  231. */
  232.  
  233. getEpsilon() {
  234.  
  235. return this.epsilon;
  236.  
  237. }
  238.  
  239. /**
  240. * Sets the depth comparison error threshold.
  241. *
  242. * @deprecated Use epsilon instead.
  243. * @param {Number} value - The new error threshold.
  244. */
  245.  
  246. setEpsilon(value) {
  247.  
  248. this.epsilon = value;
  249.  
  250. }
  251.  
  252. /**
  253. * The depth mode.
  254. *
  255. * @see https://threejs.org/docs/#api/en/constants/Materials
  256. * @type {DepthModes}
  257. */
  258.  
  259. get depthMode() {
  260.  
  261. return Number(this.defines.DEPTH_MODE);
  262.  
  263. }
  264.  
  265. set depthMode(value) {
  266.  
  267. // If the depth test fails, the texel will be discarded.
  268. let depthTest;
  269.  
  270. switch(value) {
  271.  
  272. case NeverDepth:
  273. depthTest = "false";
  274. break;
  275.  
  276. case AlwaysDepth:
  277. depthTest = "true";
  278. break;
  279.  
  280. case EqualDepth:
  281. depthTest = "abs(d1 - d0) <= DEPTH_EPSILON";
  282. break;
  283.  
  284. case NotEqualDepth:
  285. depthTest = "abs(d1 - d0) > DEPTH_EPSILON";
  286. break;
  287.  
  288. case LessDepth:
  289. depthTest = "d0 > d1";
  290. break;
  291.  
  292. case LessEqualDepth:
  293. depthTest = "d0 >= d1";
  294. break;
  295.  
  296. case GreaterEqualDepth:
  297. depthTest = "d0 <= d1";
  298. break;
  299.  
  300. case GreaterDepth:
  301. default:
  302. depthTest = "d0 < d1";
  303. break;
  304.  
  305. }
  306.  
  307. this.defines.DEPTH_MODE = value.toFixed(0);
  308. this.defines["depthTest(d0, d1)"] = depthTest;
  309. this.needsUpdate = true;
  310.  
  311. }
  312.  
  313. /**
  314. * Returns the current depth mode.
  315. *
  316. * @deprecated Use depthMode instead.
  317. * @return {DepthModes} The depth mode. Default is `LessDepth`.
  318. */
  319.  
  320. getDepthMode() {
  321.  
  322. return this.depthMode;
  323.  
  324. }
  325.  
  326. /**
  327. * Sets the depth mode.
  328. *
  329. * @deprecated Use depthMode instead.
  330. * @param {DepthModes} mode - The depth mode.
  331. */
  332.  
  333. setDepthMode(mode) {
  334.  
  335. this.depthMode = mode;
  336.  
  337. }
  338.  
  339. /**
  340. * Copies the settings of the given camera.
  341. *
  342. * @deprecated Use copyCameraSettings instead.
  343. * @param {Camera} camera - A camera.
  344. */
  345.  
  346. adoptCameraSettings(camera) {
  347.  
  348. this.copyCameraSettings(camera);
  349.  
  350. }
  351.  
  352. /**
  353. * Copies the settings of the given camera.
  354. *
  355. * @param {Camera} camera - A camera.
  356. */
  357.  
  358. copyCameraSettings(camera) {
  359.  
  360. if(camera) {
  361.  
  362. this.uniforms.cameraNearFar.value.set(camera.near, camera.far);
  363.  
  364. if(camera instanceof PerspectiveCamera) {
  365.  
  366. this.defines.PERSPECTIVE_CAMERA = "1";
  367.  
  368. } else {
  369.  
  370. delete this.defines.PERSPECTIVE_CAMERA;
  371.  
  372. }
  373.  
  374. this.needsUpdate = true;
  375.  
  376. }
  377.  
  378. }
  379.  
  380. }