EllipsoidSurfaceAppearance.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*global define*/
  2. define([
  3. '../Core/defaultValue',
  4. '../Core/defined',
  5. '../Core/defineProperties',
  6. '../Core/VertexFormat',
  7. '../Shaders/Appearances/EllipsoidSurfaceAppearanceFS',
  8. '../Shaders/Appearances/EllipsoidSurfaceAppearanceVS',
  9. './Appearance',
  10. './Material'
  11. ], function(
  12. defaultValue,
  13. defined,
  14. defineProperties,
  15. VertexFormat,
  16. EllipsoidSurfaceAppearanceFS,
  17. EllipsoidSurfaceAppearanceVS,
  18. Appearance,
  19. Material) {
  20. "use strict";
  21. /**
  22. * An appearance for geometry on the surface of the ellipsoid like {@link PolygonGeometry}
  23. * and {@link RectangleGeometry}, which supports all materials like {@link MaterialAppearance}
  24. * with {@link MaterialAppearance.MaterialSupport.ALL}. However, this appearance requires
  25. * fewer vertex attributes since the fragment shader can procedurally compute <code>normal</code>,
  26. * <code>binormal</code>, and <code>tangent</code>.
  27. *
  28. * @alias EllipsoidSurfaceAppearance
  29. * @constructor
  30. *
  31. * @param {Object} [options] Object with the following properties:
  32. * @param {Boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account.
  33. * @param {Boolean} [options.faceForward=options.aboveGround] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}.
  34. * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link EllipsoidSurfaceAppearance#renderState} has alpha blending enabled.
  35. * @param {Boolean} [options.aboveGround=false] When <code>true</code>, the geometry is expected to be on the ellipsoid's surface - not at a constant height above it - so {@link EllipsoidSurfaceAppearance#renderState} has backface culling enabled.
  36. * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color.
  37. * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader.
  38. * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader.
  39. * @param {RenderState} [options.renderState] Optional render state to override the default render state.
  40. *
  41. * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}
  42. *
  43. * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Ellipsoid%20Surface.html|Cesium Sandcastle Ellipsoid Surface Appearance Demo}
  44. *
  45. * @example
  46. * var primitive = new Cesium.Primitive({
  47. * geometryInstances : new Cesium.GeometryInstance({
  48. * geometry : new Cesium.PolygonGeometry({
  49. * vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
  50. * // ...
  51. * })
  52. * }),
  53. * appearance : new Cesium.EllipsoidSurfaceAppearance({
  54. * material : Cesium.Material.fromType('Stripe')
  55. * })
  56. * });
  57. */
  58. var EllipsoidSurfaceAppearance = function(options) {
  59. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  60. var translucent = defaultValue(options.translucent, true);
  61. var aboveGround = defaultValue(options.aboveGround, false);
  62. /**
  63. * The material used to determine the fragment color. Unlike other {@link EllipsoidSurfaceAppearance}
  64. * properties, this is not read-only, so an appearance's material can change on the fly.
  65. *
  66. * @type Material
  67. *
  68. * @default {@link Material.ColorType}
  69. *
  70. * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}
  71. */
  72. this.material = (defined(options.material)) ? options.material : Material.fromType(Material.ColorType);
  73. /**
  74. * When <code>true</code>, the geometry is expected to appear translucent.
  75. *
  76. * @type {Boolean}
  77. *
  78. * @default true
  79. */
  80. this.translucent = defaultValue(options.translucent, true);
  81. this._vertexShaderSource = defaultValue(options.vertexShaderSource, EllipsoidSurfaceAppearanceVS);
  82. this._fragmentShaderSource = defaultValue(options.fragmentShaderSource, EllipsoidSurfaceAppearanceFS);
  83. this._renderState = Appearance.getDefaultRenderState(translucent, !aboveGround, options.renderState);
  84. this._closed = false;
  85. // Non-derived members
  86. this._flat = defaultValue(options.flat, false);
  87. this._faceForward = defaultValue(options.faceForward, aboveGround);
  88. this._aboveGround = aboveGround;
  89. };
  90. defineProperties(EllipsoidSurfaceAppearance.prototype, {
  91. /**
  92. * The GLSL source code for the vertex shader.
  93. *
  94. * @memberof EllipsoidSurfaceAppearance.prototype
  95. *
  96. * @type {String}
  97. * @readonly
  98. */
  99. vertexShaderSource : {
  100. get : function() {
  101. return this._vertexShaderSource;
  102. }
  103. },
  104. /**
  105. * The GLSL source code for the fragment shader. The full fragment shader
  106. * source is built procedurally taking into account {@link EllipsoidSurfaceAppearance#material},
  107. * {@link EllipsoidSurfaceAppearance#flat}, and {@link EllipsoidSurfaceAppearance#faceForward}.
  108. * Use {@link EllipsoidSurfaceAppearance#getFragmentShaderSource} to get the full source.
  109. *
  110. * @memberof EllipsoidSurfaceAppearance.prototype
  111. *
  112. * @type {String}
  113. * @readonly
  114. */
  115. fragmentShaderSource : {
  116. get : function() {
  117. return this._fragmentShaderSource;
  118. }
  119. },
  120. /**
  121. * The WebGL fixed-function state to use when rendering the geometry.
  122. * <p>
  123. * The render state can be explicitly defined when constructing a {@link EllipsoidSurfaceAppearance}
  124. * instance, or it is set implicitly via {@link EllipsoidSurfaceAppearance#translucent}
  125. * and {@link EllipsoidSurfaceAppearance#aboveGround}.
  126. * </p>
  127. *
  128. * @memberof EllipsoidSurfaceAppearance.prototype
  129. *
  130. * @type {Object}
  131. * @readonly
  132. */
  133. renderState : {
  134. get : function() {
  135. return this._renderState;
  136. }
  137. },
  138. /**
  139. * When <code>true</code>, the geometry is expected to be closed so
  140. * {@link EllipsoidSurfaceAppearance#renderState} has backface culling enabled.
  141. * If the viewer enters the geometry, it will not be visible.
  142. *
  143. * @memberof EllipsoidSurfaceAppearance.prototype
  144. *
  145. * @type {Boolean}
  146. * @readonly
  147. *
  148. * @default false
  149. */
  150. closed : {
  151. get : function() {
  152. return this._closed;
  153. }
  154. },
  155. /**
  156. * The {@link VertexFormat} that this appearance instance is compatible with.
  157. * A geometry can have more vertex attributes and still be compatible - at a
  158. * potential performance cost - but it can't have less.
  159. *
  160. * @memberof EllipsoidSurfaceAppearance.prototype
  161. *
  162. * @type VertexFormat
  163. * @readonly
  164. *
  165. * @default {@link EllipsoidSurfaceAppearance.VERTEX_FORMAT}
  166. */
  167. vertexFormat : {
  168. get : function() {
  169. return EllipsoidSurfaceAppearance.VERTEX_FORMAT;
  170. }
  171. },
  172. /**
  173. * When <code>true</code>, flat shading is used in the fragment shader,
  174. * which means lighting is not taking into account.
  175. *
  176. * @memberof EllipsoidSurfaceAppearance.prototype
  177. *
  178. * @type {Boolean}
  179. * @readonly
  180. *
  181. * @default false
  182. */
  183. flat : {
  184. get : function() {
  185. return this._flat;
  186. }
  187. },
  188. /**
  189. * When <code>true</code>, the fragment shader flips the surface normal
  190. * as needed to ensure that the normal faces the viewer to avoid
  191. * dark spots. This is useful when both sides of a geometry should be
  192. * shaded like {@link WallGeometry}.
  193. *
  194. * @memberof EllipsoidSurfaceAppearance.prototype
  195. *
  196. * @type {Boolean}
  197. * @readonly
  198. *
  199. * @default true
  200. */
  201. faceForward : {
  202. get : function() {
  203. return this._faceForward;
  204. }
  205. },
  206. /**
  207. * When <code>true</code>, the geometry is expected to be on the ellipsoid's
  208. * surface - not at a constant height above it - so {@link EllipsoidSurfaceAppearance#renderState}
  209. * has backface culling enabled.
  210. *
  211. *
  212. * @memberof EllipsoidSurfaceAppearance.prototype
  213. *
  214. * @type {Boolean}
  215. * @readonly
  216. *
  217. * @default false
  218. */
  219. aboveGround : {
  220. get : function() {
  221. return this._aboveGround;
  222. }
  223. }
  224. });
  225. /**
  226. * The {@link VertexFormat} that all {@link EllipsoidSurfaceAppearance} instances
  227. * are compatible with, which requires only <code>position</code> and <code>st</code>
  228. * attributes. Other attributes are procedurally computed in the fragment shader.
  229. *
  230. * @type VertexFormat
  231. *
  232. * @constant
  233. */
  234. EllipsoidSurfaceAppearance.VERTEX_FORMAT = VertexFormat.POSITION_AND_ST;
  235. /**
  236. * Procedurally creates the full GLSL fragment shader source. For {@link EllipsoidSurfaceAppearance},
  237. * this is derived from {@link EllipsoidSurfaceAppearance#fragmentShaderSource}, {@link EllipsoidSurfaceAppearance#flat},
  238. * and {@link EllipsoidSurfaceAppearance#faceForward}.
  239. *
  240. * @function
  241. *
  242. * @returns String The full GLSL fragment shader source.
  243. */
  244. EllipsoidSurfaceAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource;
  245. /**
  246. * Determines if the geometry is translucent based on {@link EllipsoidSurfaceAppearance#translucent} and {@link Material#isTranslucent}.
  247. *
  248. * @function
  249. *
  250. * @returns {Boolean} <code>true</code> if the appearance is translucent.
  251. */
  252. EllipsoidSurfaceAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent;
  253. /**
  254. * Creates a render state. This is not the final render state instance; instead,
  255. * it can contain a subset of render state properties identical to the render state
  256. * created in the context.
  257. *
  258. * @function
  259. *
  260. * @returns {Object} The render state.
  261. */
  262. EllipsoidSurfaceAppearance.prototype.getRenderState = Appearance.prototype.getRenderState;
  263. return EllipsoidSurfaceAppearance;
  264. });