PickDepth.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import Cartesian4 from "../Core/Cartesian4.js";
  2. import defined from "../Core/defined.js";
  3. import destroyObject from "../Core/destroyObject.js";
  4. import FramebufferManager from "../Renderer/FramebufferManager.js";
  5. import RenderState from "../Renderer/RenderState.js";
  6. /**
  7. * @private
  8. */
  9. function PickDepth() {
  10. this._framebuffer = new FramebufferManager();
  11. this._textureToCopy = undefined;
  12. this._copyDepthCommand = undefined;
  13. }
  14. Object.defineProperties(PickDepth.prototype, {
  15. framebuffer: {
  16. get: function () {
  17. return this._framebuffer.framebuffer;
  18. },
  19. },
  20. });
  21. function updateFramebuffers(pickDepth, context, depthTexture) {
  22. const width = depthTexture.width;
  23. const height = depthTexture.height;
  24. pickDepth._framebuffer.update(context, width, height);
  25. }
  26. function updateCopyCommands(pickDepth, context, depthTexture) {
  27. if (!defined(pickDepth._copyDepthCommand)) {
  28. const fs =
  29. "uniform highp sampler2D u_texture;\n" +
  30. "in vec2 v_textureCoordinates;\n" +
  31. "void main()\n" +
  32. "{\n" +
  33. " out_FragColor = czm_packDepth(texture(u_texture, v_textureCoordinates).r);\n" +
  34. "}\n";
  35. pickDepth._copyDepthCommand = context.createViewportQuadCommand(fs, {
  36. renderState: RenderState.fromCache(),
  37. uniformMap: {
  38. u_texture: function () {
  39. return pickDepth._textureToCopy;
  40. },
  41. },
  42. owner: pickDepth,
  43. });
  44. }
  45. pickDepth._textureToCopy = depthTexture;
  46. pickDepth._copyDepthCommand.framebuffer = pickDepth.framebuffer;
  47. }
  48. PickDepth.prototype.update = function (context, depthTexture) {
  49. updateFramebuffers(this, context, depthTexture);
  50. updateCopyCommands(this, context, depthTexture);
  51. };
  52. const scratchPackedDepth = new Cartesian4();
  53. const packedDepthScale = new Cartesian4(
  54. 1.0,
  55. 1.0 / 255.0,
  56. 1.0 / 65025.0,
  57. 1.0 / 16581375.0
  58. );
  59. PickDepth.prototype.getDepth = function (context, x, y) {
  60. // If this function is called before the framebuffer is created, the depth is undefined.
  61. if (!defined(this.framebuffer)) {
  62. return undefined;
  63. }
  64. const pixels = context.readPixels({
  65. x: x,
  66. y: y,
  67. width: 1,
  68. height: 1,
  69. framebuffer: this.framebuffer,
  70. });
  71. const packedDepth = Cartesian4.unpack(pixels, 0, scratchPackedDepth);
  72. Cartesian4.divideByScalar(packedDepth, 255.0, packedDepth);
  73. return Cartesian4.dot(packedDepth, packedDepthScale);
  74. };
  75. PickDepth.prototype.executeCopyDepth = function (context, passState) {
  76. this._copyDepthCommand.execute(context, passState);
  77. };
  78. PickDepth.prototype.isDestroyed = function () {
  79. return false;
  80. };
  81. PickDepth.prototype.destroy = function () {
  82. this._framebuffer.destroy();
  83. if (defined(this._copyDepthCommand)) {
  84. this._copyDepthCommand.shaderProgram =
  85. defined(this._copyDepthCommand.shaderProgram) &&
  86. this._copyDepthCommand.shaderProgram.destroy();
  87. }
  88. return destroyObject(this);
  89. };
  90. export default PickDepth;