SunPostProcess.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. import BoundingRectangle from '../Core/BoundingRectangle.js';
  2. import Cartesian2 from '../Core/Cartesian2.js';
  3. import Cartesian4 from '../Core/Cartesian4.js';
  4. import defined from '../Core/defined.js';
  5. import destroyObject from '../Core/destroyObject.js';
  6. import CesiumMath from '../Core/Math.js';
  7. import Matrix4 from '../Core/Matrix4.js';
  8. import Transforms from '../Core/Transforms.js';
  9. import AdditiveBlend from '../Shaders/PostProcessStages/AdditiveBlend.js';
  10. import BrightPass from '../Shaders/PostProcessStages/BrightPass.js';
  11. import GaussianBlur1D from '../Shaders/PostProcessStages/GaussianBlur1D.js';
  12. import PassThrough from '../Shaders/PostProcessStages/PassThrough.js';
  13. import PostProcessStage from './PostProcessStage.js';
  14. import PostProcessStageComposite from './PostProcessStageComposite.js';
  15. import PostProcessStageSampleMode from './PostProcessStageSampleMode.js';
  16. import PostProcessStageTextureCache from './PostProcessStageTextureCache.js';
  17. import SceneFramebuffer from './SceneFramebuffer.js';
  18. function SunPostProcess() {
  19. this._sceneFramebuffer = new SceneFramebuffer();
  20. var scale = 0.125;
  21. var stages = new Array(6);
  22. stages[0] = new PostProcessStage({
  23. fragmentShader : PassThrough,
  24. textureScale : scale,
  25. forcePowerOfTwo : true,
  26. sampleMode : PostProcessStageSampleMode.LINEAR
  27. });
  28. var brightPass = stages[1] = new PostProcessStage({
  29. fragmentShader : BrightPass,
  30. uniforms : {
  31. avgLuminance : 0.5, // A guess at the average luminance across the entire scene
  32. threshold : 0.25,
  33. offset : 0.1
  34. },
  35. textureScale : scale,
  36. forcePowerOfTwo : true
  37. });
  38. var that = this;
  39. this._delta = 1.0;
  40. this._sigma = 2.0;
  41. this._blurStep = new Cartesian2();
  42. stages[2] = new PostProcessStage({
  43. fragmentShader : GaussianBlur1D,
  44. uniforms : {
  45. step : function() {
  46. that._blurStep.x = that._blurStep.y = 1.0 / brightPass.outputTexture.width;
  47. return that._blurStep;
  48. },
  49. delta : function() {
  50. return that._delta;
  51. },
  52. sigma : function() {
  53. return that._sigma;
  54. },
  55. direction : 0.0
  56. },
  57. textureScale : scale,
  58. forcePowerOfTwo : true
  59. });
  60. stages[3] = new PostProcessStage({
  61. fragmentShader : GaussianBlur1D,
  62. uniforms : {
  63. step : function() {
  64. that._blurStep.x = that._blurStep.y = 1.0 / brightPass.outputTexture.width;
  65. return that._blurStep;
  66. },
  67. delta : function() {
  68. return that._delta;
  69. },
  70. sigma : function() {
  71. return that._sigma;
  72. },
  73. direction : 1.0
  74. },
  75. textureScale : scale,
  76. forcePowerOfTwo : true
  77. });
  78. stages[4] = new PostProcessStage({
  79. fragmentShader : PassThrough,
  80. sampleMode : PostProcessStageSampleMode.LINEAR
  81. });
  82. this._uCenter = new Cartesian2();
  83. this._uRadius = undefined;
  84. stages[5] = new PostProcessStage({
  85. fragmentShader : AdditiveBlend,
  86. uniforms : {
  87. center : function() {
  88. return that._uCenter;
  89. },
  90. radius : function() {
  91. return that._uRadius;
  92. },
  93. colorTexture2 : function() {
  94. return that._sceneFramebuffer.getFramebuffer().getColorTexture(0);
  95. }
  96. }
  97. });
  98. this._stages = new PostProcessStageComposite({
  99. stages : stages
  100. });
  101. var textureCache = new PostProcessStageTextureCache(this);
  102. var length = stages.length;
  103. for (var i = 0; i < length; ++i) {
  104. stages[i]._textureCache = textureCache;
  105. }
  106. this._textureCache = textureCache;
  107. this.length = stages.length;
  108. }
  109. SunPostProcess.prototype.get = function(index) {
  110. return this._stages.get(index);
  111. };
  112. SunPostProcess.prototype.getStageByName = function(name) {
  113. var length = this._stages.length;
  114. for (var i = 0; i < length; ++i) {
  115. var stage = this._stages.get(i);
  116. if (stage.name === name) {
  117. return stage;
  118. }
  119. }
  120. return undefined;
  121. };
  122. var sunPositionECScratch = new Cartesian4();
  123. var sunPositionWCScratch = new Cartesian2();
  124. var sizeScratch = new Cartesian2();
  125. var postProcessMatrix4Scratch= new Matrix4();
  126. function updateSunPosition(postProcess, context, viewport) {
  127. var us = context.uniformState;
  128. var sunPosition = us.sunPositionWC;
  129. var viewMatrix = us.view;
  130. var viewProjectionMatrix = us.viewProjection;
  131. var projectionMatrix = us.projection;
  132. // create up sampled render state
  133. var viewportTransformation = Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, postProcessMatrix4Scratch);
  134. var sunPositionEC = Matrix4.multiplyByPoint(viewMatrix, sunPosition, sunPositionECScratch);
  135. var sunPositionWC = Transforms.pointToGLWindowCoordinates(viewProjectionMatrix, viewportTransformation, sunPosition, sunPositionWCScratch);
  136. sunPositionEC.x += CesiumMath.SOLAR_RADIUS;
  137. var limbWC = Transforms.pointToGLWindowCoordinates(projectionMatrix, viewportTransformation, sunPositionEC, sunPositionEC);
  138. var sunSize = Cartesian2.magnitude(Cartesian2.subtract(limbWC, sunPositionWC, limbWC)) * 30.0 * 2.0;
  139. var size = sizeScratch;
  140. size.x = sunSize;
  141. size.y = sunSize;
  142. postProcess._uCenter = Cartesian2.clone(sunPositionWC, postProcess._uCenter);
  143. postProcess._uRadius = Math.max(size.x, size.y) * 0.15;
  144. var width = context.drawingBufferWidth;
  145. var height = context.drawingBufferHeight;
  146. var stages = postProcess._stages;
  147. var firstStage = stages.get(0);
  148. var downSampleWidth = firstStage.outputTexture.width;
  149. var downSampleHeight = firstStage.outputTexture.height;
  150. var downSampleViewport = new BoundingRectangle();
  151. downSampleViewport.width = downSampleWidth;
  152. downSampleViewport.height = downSampleHeight;
  153. // create down sampled render state
  154. viewportTransformation = Matrix4.computeViewportTransformation(downSampleViewport, 0.0, 1.0, postProcessMatrix4Scratch);
  155. sunPositionWC = Transforms.pointToGLWindowCoordinates(viewProjectionMatrix, viewportTransformation, sunPosition, sunPositionWCScratch);
  156. size.x *= downSampleWidth / width;
  157. size.y *= downSampleHeight / height;
  158. var scissorRectangle = firstStage.scissorRectangle;
  159. scissorRectangle.x = Math.max(sunPositionWC.x - size.x * 0.5, 0.0);
  160. scissorRectangle.y = Math.max(sunPositionWC.y - size.y * 0.5, 0.0);
  161. scissorRectangle.width = Math.min(size.x, width);
  162. scissorRectangle.height = Math.min(size.y, height);
  163. for (var i = 1; i < 4; ++i) {
  164. BoundingRectangle.clone(scissorRectangle, stages.get(i).scissorRectangle);
  165. }
  166. }
  167. SunPostProcess.prototype.clear = function(context, passState, clearColor) {
  168. this._sceneFramebuffer.clear(context, passState, clearColor);
  169. this._textureCache.clear(context);
  170. };
  171. SunPostProcess.prototype.update = function(passState) {
  172. var context = passState.context;
  173. var viewport = passState.viewport;
  174. var sceneFramebuffer = this._sceneFramebuffer;
  175. sceneFramebuffer.update(context, viewport);
  176. var framebuffer = sceneFramebuffer.getFramebuffer();
  177. this._textureCache.update(context);
  178. this._stages.update(context, false);
  179. updateSunPosition(this, context, viewport);
  180. return framebuffer;
  181. };
  182. SunPostProcess.prototype.execute = function(context) {
  183. var colorTexture = this._sceneFramebuffer.getFramebuffer().getColorTexture(0);
  184. var stages = this._stages;
  185. var length = stages.length;
  186. stages.get(0).execute(context, colorTexture);
  187. for (var i = 1; i < length; ++i) {
  188. stages.get(i).execute(context, stages.get(i - 1).outputTexture);
  189. }
  190. };
  191. SunPostProcess.prototype.copy = function(context, framebuffer) {
  192. if (!defined(this._copyColorCommand)) {
  193. var that = this;
  194. this._copyColorCommand = context.createViewportQuadCommand(PassThrough, {
  195. uniformMap : {
  196. colorTexture : function() {
  197. return that._stages.get(that._stages.length - 1).outputTexture;
  198. }
  199. },
  200. owner : this
  201. });
  202. }
  203. this._copyColorCommand.framebuffer = framebuffer;
  204. this._copyColorCommand.execute(context);
  205. };
  206. SunPostProcess.prototype.isDestroyed = function() {
  207. return false;
  208. };
  209. SunPostProcess.prototype.destroy = function() {
  210. this._textureCache.destroy();
  211. this._stages.destroy();
  212. return destroyObject(this);
  213. };
  214. export default SunPostProcess;