Sun.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*global define*/
  2. define([
  3. '../Core/BoundingRectangle',
  4. '../Core/BoundingSphere',
  5. '../Core/Cartesian2',
  6. '../Core/Cartesian3',
  7. '../Core/Cartesian4',
  8. '../Core/Color',
  9. '../Core/ComponentDatatype',
  10. '../Core/defined',
  11. '../Core/defineProperties',
  12. '../Core/destroyObject',
  13. '../Core/IndexDatatype',
  14. '../Core/Math',
  15. '../Core/Matrix4',
  16. '../Core/PixelFormat',
  17. '../Core/PrimitiveType',
  18. '../Renderer/BufferUsage',
  19. '../Renderer/ClearCommand',
  20. '../Renderer/DrawCommand',
  21. '../Shaders/SunFS',
  22. '../Shaders/SunTextureFS',
  23. '../Shaders/SunVS',
  24. './BlendingState',
  25. './SceneMode',
  26. './SceneTransforms'
  27. ], function(
  28. BoundingRectangle,
  29. BoundingSphere,
  30. Cartesian2,
  31. Cartesian3,
  32. Cartesian4,
  33. Color,
  34. ComponentDatatype,
  35. defined,
  36. defineProperties,
  37. destroyObject,
  38. IndexDatatype,
  39. CesiumMath,
  40. Matrix4,
  41. PixelFormat,
  42. PrimitiveType,
  43. BufferUsage,
  44. ClearCommand,
  45. DrawCommand,
  46. SunFS,
  47. SunTextureFS,
  48. SunVS,
  49. BlendingState,
  50. SceneMode,
  51. SceneTransforms) {
  52. "use strict";
  53. /**
  54. * Draws a sun billboard.
  55. * <p>This is only supported in 3D and Columbus view.</p>
  56. *
  57. * @alias Sun
  58. * @constructor
  59. *
  60. * @see Scene#sun
  61. *
  62. * @example
  63. * scene.sun = new Cesium.Sun();
  64. */
  65. var Sun = function() {
  66. /**
  67. * Determines if the sun will be shown.
  68. *
  69. * @type {Boolean}
  70. * @default true
  71. */
  72. this.show = true;
  73. this._command = new DrawCommand({
  74. primitiveType : PrimitiveType.TRIANGLES,
  75. boundingVolume : new BoundingSphere(),
  76. owner : this
  77. });
  78. this._boundingVolume = new BoundingSphere();
  79. this._boundingVolume2D = new BoundingSphere();
  80. this._texture = undefined;
  81. this._drawingBufferWidth = undefined;
  82. this._drawingBufferHeight = undefined;
  83. this._radiusTS = undefined;
  84. this._size = undefined;
  85. this.glowFactor = 1.0;
  86. this._glowFactorDirty = false;
  87. var that = this;
  88. this._uniformMap = {
  89. u_texture : function() {
  90. return that._texture;
  91. },
  92. u_size : function() {
  93. return that._size;
  94. }
  95. };
  96. };
  97. defineProperties(Sun.prototype, {
  98. /**
  99. * Gets or sets a number that controls how "bright" the Sun's lens flare appears
  100. * to be. Zero shows just the Sun's disc without any flare.
  101. * Use larger values for a more pronounced flare around the Sun.
  102. *
  103. * @memberof Sun.prototype
  104. * @type {Number}
  105. * @default 1.0
  106. */
  107. glowFactor : {
  108. get : function () { return this._glowFactor; },
  109. set : function (glowFactor) {
  110. glowFactor = Math.max(glowFactor, 0.0);
  111. this._glowFactor = glowFactor;
  112. this._glowFactorDirty = true;
  113. }
  114. }
  115. });
  116. var scratchPositionWC = new Cartesian2();
  117. var scratchLimbWC = new Cartesian2();
  118. var scratchPositionEC = new Cartesian4();
  119. var scratchCartesian4 = new Cartesian4();
  120. /**
  121. * @private
  122. */
  123. Sun.prototype.update = function(scene) {
  124. var frameState = scene.frameState;
  125. var context = scene.context;
  126. if (!this.show) {
  127. return undefined;
  128. }
  129. var mode = frameState.mode;
  130. if (mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) {
  131. return undefined;
  132. }
  133. if (!frameState.passes.render) {
  134. return undefined;
  135. }
  136. var drawingBufferWidth = scene.drawingBufferWidth;
  137. var drawingBufferHeight = scene.drawingBufferHeight;
  138. if (!defined(this._texture) ||
  139. drawingBufferWidth !== this._drawingBufferWidth ||
  140. drawingBufferHeight !== this._drawingBufferHeight ||
  141. this._glowFactorDirty) {
  142. this._texture = this._texture && this._texture.destroy();
  143. this._drawingBufferWidth = drawingBufferWidth;
  144. this._drawingBufferHeight = drawingBufferHeight;
  145. this._glowFactorDirty = false;
  146. var size = Math.max(drawingBufferWidth, drawingBufferHeight);
  147. size = Math.pow(2.0, Math.ceil(Math.log(size) / Math.log(2.0)) - 2.0);
  148. this._texture = context.createTexture2D({
  149. width : size,
  150. height : size,
  151. pixelFormat : PixelFormat.RGBA
  152. });
  153. var fbo = context.createFramebuffer({
  154. colorTextures : [this._texture]
  155. });
  156. fbo.destroyAttachments = false;
  157. var clearCommand = new ClearCommand({
  158. color : new Color(0.0, 0.0, 0.0, 0.0),
  159. framebuffer : fbo
  160. });
  161. var rs = context.createRenderState({
  162. viewport : new BoundingRectangle(0.0, 0.0, size, size)
  163. });
  164. this._glowLengthTS = this._glowFactor * 5.0;
  165. this._radiusTS = (1.0 / (1.0 + 2.0 * this._glowLengthTS)) * 0.5;
  166. var that = this;
  167. var uniformMap = {
  168. u_glowLengthTS : function() {
  169. return that._glowLengthTS;
  170. },
  171. u_radiusTS : function() {
  172. return that._radiusTS;
  173. }
  174. };
  175. var drawCommand = context.createViewportQuadCommand(SunTextureFS, {
  176. renderState : rs,
  177. uniformMap : uniformMap,
  178. framebuffer : fbo,
  179. owner : this
  180. });
  181. clearCommand.execute(context);
  182. drawCommand.execute(context);
  183. drawCommand.shaderProgram.destroy();
  184. fbo.destroy();
  185. }
  186. var command = this._command;
  187. if (!defined(command.vertexArray)) {
  188. var attributeLocations = {
  189. direction : 0
  190. };
  191. var directions = new Uint8Array(4 * 2);
  192. directions[0] = 0;
  193. directions[1] = 0;
  194. directions[2] = 255;
  195. directions[3] = 0.0;
  196. directions[4] = 255;
  197. directions[5] = 255;
  198. directions[6] = 0.0;
  199. directions[7] = 255;
  200. var vertexBuffer = context.createVertexBuffer(directions, BufferUsage.STATIC_DRAW);
  201. var attributes = [{
  202. index : attributeLocations.direction,
  203. vertexBuffer : vertexBuffer,
  204. componentsPerAttribute : 2,
  205. normalize : true,
  206. componentDatatype : ComponentDatatype.UNSIGNED_BYTE
  207. }];
  208. // Workaround Internet Explorer 11.0.8 lack of TRIANGLE_FAN
  209. var indexBuffer = context.createIndexBuffer(new Uint16Array([0, 1, 2, 0, 2, 3]), BufferUsage.STATIC_DRAW, IndexDatatype.UNSIGNED_SHORT);
  210. command.vertexArray = context.createVertexArray(attributes, indexBuffer);
  211. command.shaderProgram = context.createShaderProgram(SunVS, SunFS, attributeLocations);
  212. command.renderState = context.createRenderState({
  213. blending : BlendingState.ALPHA_BLEND
  214. });
  215. command.uniformMap = this._uniformMap;
  216. }
  217. var sunPosition = context.uniformState.sunPositionWC;
  218. var sunPositionCV = context.uniformState.sunPositionColumbusView;
  219. var boundingVolume = this._boundingVolume;
  220. var boundingVolume2D = this._boundingVolume2D;
  221. Cartesian3.clone(sunPosition, boundingVolume.center);
  222. boundingVolume2D.center.x = sunPositionCV.z;
  223. boundingVolume2D.center.y = sunPositionCV.x;
  224. boundingVolume2D.center.z = sunPositionCV.y;
  225. boundingVolume.radius = CesiumMath.SOLAR_RADIUS + CesiumMath.SOLAR_RADIUS * this._glowLengthTS;
  226. boundingVolume2D.radius = boundingVolume.radius;
  227. if (mode === SceneMode.SCENE3D) {
  228. BoundingSphere.clone(boundingVolume, command.boundingVolume);
  229. } else if (mode === SceneMode.COLUMBUS_VIEW) {
  230. BoundingSphere.clone(boundingVolume2D, command.boundingVolume);
  231. }
  232. var position = SceneTransforms.computeActualWgs84Position(frameState, sunPosition, scratchCartesian4);
  233. var dist = Cartesian3.magnitude(Cartesian3.subtract(position, scene.camera.position, scratchCartesian4));
  234. var projMatrix = context.uniformState.projection;
  235. var positionEC = scratchPositionEC;
  236. positionEC.x = 0;
  237. positionEC.y = 0;
  238. positionEC.z = -dist;
  239. positionEC.w = 1;
  240. var positionCC = Matrix4.multiplyByVector(projMatrix, positionEC, scratchCartesian4);
  241. var positionWC = SceneTransforms.clipToDrawingBufferCoordinates(scene, positionCC, scratchPositionWC);
  242. positionEC.x = CesiumMath.SOLAR_RADIUS;
  243. var limbCC = Matrix4.multiplyByVector(projMatrix, positionEC, scratchCartesian4);
  244. var limbWC = SceneTransforms.clipToDrawingBufferCoordinates(scene, limbCC, scratchLimbWC);
  245. this._size = Math.ceil(Cartesian2.magnitude(Cartesian2.subtract(limbWC, positionWC, scratchCartesian4)));
  246. this._size = 2.0 * this._size * (1.0 + 2.0 * this._glowLengthTS);
  247. return command;
  248. };
  249. /**
  250. * Returns true if this object was destroyed; otherwise, false.
  251. * <br /><br />
  252. * If this object was destroyed, it should not be used; calling any function other than
  253. * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
  254. *
  255. * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
  256. *
  257. * @see Sun#destroy
  258. */
  259. Sun.prototype.isDestroyed = function() {
  260. return false;
  261. };
  262. /**
  263. * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
  264. * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
  265. * <br /><br />
  266. * Once an object is destroyed, it should not be used; calling any function other than
  267. * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
  268. * assign the return value (<code>undefined</code>) to the object as done in the example.
  269. *
  270. * @returns {undefined}
  271. *
  272. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
  273. *
  274. * @see Sun#isDestroyed
  275. *
  276. * @example
  277. * sun = sun && sun.destroy();
  278. */
  279. Sun.prototype.destroy = function() {
  280. var command = this._command;
  281. command.vertexArray = command.vertexArray && command.vertexArray.destroy();
  282. command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy();
  283. this._texture = this._texture && this._texture.destroy();
  284. return destroyObject(this);
  285. };
  286. return Sun;
  287. });