SkyBoxOnGround.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //以下代码复制自Cesium源码的SkyBox,然后做了一点点修改。
  2. //SkyBoxOnGround.js
  3. (function () {
  4. const Cesium = window.Cesium;
  5. const BoxGeometry = Cesium.BoxGeometry;
  6. const Cartesian3 = Cesium.Cartesian3;
  7. const defaultValue = Cesium.defaultValue;
  8. const defined = Cesium.defined;
  9. const destroyObject = Cesium.destroyObject;
  10. const DeveloperError = Cesium.DeveloperError;
  11. const GeometryPipeline = Cesium.GeometryPipeline;
  12. const Matrix3 = Cesium.Matrix3;
  13. const Matrix4 = Cesium.Matrix4;
  14. const Transforms = Cesium.Transforms;
  15. const VertexFormat = Cesium.VertexFormat;
  16. const BufferUsage = Cesium.BufferUsage;
  17. const CubeMap = Cesium.CubeMap;
  18. const DrawCommand = Cesium.DrawCommand;
  19. const loadCubeMap = Cesium.loadCubeMap;
  20. const RenderState = Cesium.RenderState;
  21. const VertexArray = Cesium.VertexArray;
  22. const BlendingState = Cesium.BlendingState;
  23. const SceneMode = Cesium.SceneMode;
  24. const ShaderProgram = Cesium.ShaderProgram;
  25. const ShaderSource = Cesium.ShaderSource;
  26. //片元着色器,直接从源码复制
  27. const SkyBoxFS = "uniform samplerCube u_cubeMap;\n\
  28. varying vec3 v_texCoord;\n\
  29. void main()\n\
  30. {\n\
  31. vec4 color = textureCube(u_cubeMap, normalize(v_texCoord));\n\
  32. gl_FragColor = vec4(czm_gammaCorrect(color).rgb, czm_morphTime);\n\
  33. }\n\
  34. ";
  35. //顶点着色器有修改,主要是乘了一个旋转矩阵
  36. const SkyBoxVS = "attribute vec3 position;\n\
  37. varying vec3 v_texCoord;\n\
  38. uniform mat3 u_rotateMatrix;\n\
  39. void main()\n\
  40. {\n\
  41. vec3 p = czm_viewRotation * u_rotateMatrix * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));\n\
  42. gl_Position = czm_projection * vec4(p, 1.0);\n\
  43. v_texCoord = position.xyz;\n\
  44. }\n\
  45. ";
  46. /**
  47. * 为了兼容高版本的Cesium,因为新版cesium中getRotation被移除
  48. */
  49. if (!Cesium.defined(Cesium.Matrix4.getRotation)) {
  50. Cesium.Matrix4.getRotation = Cesium.Matrix4.getMatrix3
  51. }
  52. function SkyBoxOnGround(options) {
  53. /**
  54. * 近景天空盒
  55. * @type Object
  56. * @default undefined
  57. */
  58. this.sources = options.sources;
  59. this._sources = undefined;
  60. /**
  61. * Determines if the sky box will be shown.
  62. *
  63. * @type {Boolean}
  64. * @default true
  65. */
  66. this.show = defaultValue(options.show, true);
  67. this._command = new DrawCommand({
  68. modelMatrix: Matrix4.clone(Matrix4.IDENTITY),
  69. owner: this
  70. });
  71. this._cubeMap = undefined;
  72. this._attributeLocations = undefined;
  73. this._useHdr = undefined;
  74. }
  75. const skyboxMatrix3 = new Matrix3();
  76. SkyBoxOnGround.prototype.update = function (frameState, useHdr) {
  77. const that = this;
  78. if (!this.show) {
  79. return undefined;
  80. }
  81. if ((frameState.mode !== SceneMode.SCENE3D) &&
  82. (frameState.mode !== SceneMode.MORPHING)) {
  83. return undefined;
  84. }
  85. if (!frameState.passes.render) {
  86. return undefined;
  87. }
  88. const context = frameState.context;
  89. if (this._sources !== this.sources) {
  90. this._sources = this.sources;
  91. const sources = this.sources;
  92. if ((!defined(sources.positiveX)) ||
  93. (!defined(sources.negativeX)) ||
  94. (!defined(sources.positiveY)) ||
  95. (!defined(sources.negativeY)) ||
  96. (!defined(sources.positiveZ)) ||
  97. (!defined(sources.negativeZ))) {
  98. throw new DeveloperError('this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties.');
  99. }
  100. if ((typeof sources.positiveX !== typeof sources.negativeX) ||
  101. (typeof sources.positiveX !== typeof sources.positiveY) ||
  102. (typeof sources.positiveX !== typeof sources.negativeY) ||
  103. (typeof sources.positiveX !== typeof sources.positiveZ) ||
  104. (typeof sources.positiveX !== typeof sources.negativeZ)) {
  105. throw new DeveloperError('this.sources properties must all be the same type.');
  106. }
  107. if (typeof sources.positiveX === 'string') {
  108. // Given urls for cube-map images. Load them.
  109. loadCubeMap(context, this._sources).then(function (cubeMap) {
  110. that._cubeMap = that._cubeMap && that._cubeMap.destroy();
  111. that._cubeMap = cubeMap;
  112. });
  113. } else {
  114. this._cubeMap = this._cubeMap && this._cubeMap.destroy();
  115. this._cubeMap = new CubeMap({
  116. context: context,
  117. source: sources
  118. });
  119. }
  120. }
  121. const command = this._command;
  122. command.modelMatrix = Transforms.eastNorthUpToFixedFrame(frameState.camera._positionWC);
  123. if (!defined(command.vertexArray)) {
  124. command.uniformMap = {
  125. u_cubeMap: function () {
  126. return that._cubeMap;
  127. },
  128. u_rotateMatrix: function () {
  129. return Matrix4.getRotation(command.modelMatrix, skyboxMatrix3);
  130. },
  131. };
  132. const geometry = BoxGeometry.createGeometry(BoxGeometry.fromDimensions({
  133. dimensions: new Cartesian3(2.0, 2.0, 2.0),
  134. vertexFormat: VertexFormat.POSITION_ONLY
  135. }));
  136. const attributeLocations = this._attributeLocations = GeometryPipeline.createAttributeLocations(geometry);
  137. command.vertexArray = VertexArray.fromGeometry({
  138. context: context,
  139. geometry: geometry,
  140. attributeLocations: attributeLocations,
  141. bufferUsage: BufferUsage._DRAW
  142. });
  143. command.renderState = RenderState.fromCache({
  144. blending: BlendingState.ALPHA_BLEND
  145. });
  146. }
  147. if (!defined(command.shaderProgram) || this._useHdr !== useHdr) {
  148. const fs = new ShaderSource({
  149. defines: [useHdr ? 'HDR' : ''],
  150. sources: [SkyBoxFS]
  151. });
  152. command.shaderProgram = ShaderProgram.fromCache({
  153. context: context,
  154. vertexShaderSource: SkyBoxVS,
  155. fragmentShaderSource: fs,
  156. attributeLocations: this._attributeLocations
  157. });
  158. this._useHdr = useHdr;
  159. }
  160. if (!defined(this._cubeMap)) {
  161. return undefined;
  162. }
  163. return command;
  164. };
  165. SkyBoxOnGround.prototype.isDestroyed = function () {
  166. return false
  167. };
  168. SkyBoxOnGround.prototype.destroy = function () {
  169. const command = this._command;
  170. command.vertexArray = command.vertexArray && command.vertexArray.destroy();
  171. command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy();
  172. this._cubeMap = this._cubeMap && this._cubeMap.destroy();
  173. return destroyObject(this);
  174. }
  175. window.Cesium.GroundSkyBox= SkyBoxOnGround
  176. })();