@cesium/engine 2.4.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/Build/Workers/{BoxGeometry-af7d05ef.js → BoxGeometry-7aa4ce7f.js} +1 -1
  2. package/Build/Workers/{CylinderGeometry-dbaa1678.js → CylinderGeometry-8fc7c44b.js} +1 -1
  3. package/Build/Workers/{EllipseGeometry-6508b78b.js → EllipseGeometry-16b3736a.js} +1 -1
  4. package/Build/Workers/{EllipseOutlineGeometry-2a2510bb.js → EllipseOutlineGeometry-05d35d18.js} +1 -1
  5. package/Build/Workers/{EllipsoidGeometry-8155e3a2.js → EllipsoidGeometry-a503d1d6.js} +1 -1
  6. package/Build/Workers/{EllipsoidOutlineGeometry-c045678d.js → EllipsoidOutlineGeometry-7b09f24d.js} +1 -1
  7. package/Build/Workers/{FrustumGeometry-d3ff16d0.js → FrustumGeometry-87ce8622.js} +1 -1
  8. package/Build/Workers/{GeometryAttribute-13da9466.js → GeometryAttribute-8fcff0d5.js} +1 -1
  9. package/Build/Workers/{GeometryPipeline-03bc5709.js → GeometryPipeline-70d69a43.js} +1 -1
  10. package/Build/Workers/{PolygonGeometryLibrary-d447448d.js → PolygonGeometryLibrary-bad6329a.js} +1 -1
  11. package/Build/Workers/{PolygonPipeline-460cce4e.js → PolygonPipeline-dd13ee78.js} +1 -1
  12. package/Build/Workers/{PrimitivePipeline-e648752b.js → PrimitivePipeline-111ee29f.js} +1 -1
  13. package/Build/Workers/cesiumWorkerBootstrapper.js +1 -1
  14. package/Build/Workers/combineGeometry.js +1 -1
  15. package/Build/Workers/createBoxGeometry.js +1 -1
  16. package/Build/Workers/createBoxOutlineGeometry.js +1 -1
  17. package/Build/Workers/createCircleGeometry.js +1 -1
  18. package/Build/Workers/createCircleOutlineGeometry.js +1 -1
  19. package/Build/Workers/createCoplanarPolygonGeometry.js +1 -1
  20. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +1 -1
  21. package/Build/Workers/createCorridorGeometry.js +1 -1
  22. package/Build/Workers/createCorridorOutlineGeometry.js +1 -1
  23. package/Build/Workers/createCylinderGeometry.js +1 -1
  24. package/Build/Workers/createCylinderOutlineGeometry.js +1 -1
  25. package/Build/Workers/createEllipseGeometry.js +1 -1
  26. package/Build/Workers/createEllipseOutlineGeometry.js +1 -1
  27. package/Build/Workers/createEllipsoidGeometry.js +1 -1
  28. package/Build/Workers/createEllipsoidOutlineGeometry.js +1 -1
  29. package/Build/Workers/createFrustumGeometry.js +1 -1
  30. package/Build/Workers/createFrustumOutlineGeometry.js +1 -1
  31. package/Build/Workers/createGeometry.js +1 -1
  32. package/Build/Workers/createGroundPolylineGeometry.js +1 -1
  33. package/Build/Workers/createPlaneGeometry.js +1 -1
  34. package/Build/Workers/createPlaneOutlineGeometry.js +1 -1
  35. package/Build/Workers/createPolygonGeometry.js +1 -1
  36. package/Build/Workers/createPolygonOutlineGeometry.js +1 -1
  37. package/Build/Workers/createPolylineGeometry.js +1 -1
  38. package/Build/Workers/createPolylineVolumeGeometry.js +1 -1
  39. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +1 -1
  40. package/Build/Workers/createRectangleGeometry.js +1 -1
  41. package/Build/Workers/createRectangleOutlineGeometry.js +1 -1
  42. package/Build/Workers/createSimplePolylineGeometry.js +1 -1
  43. package/Build/Workers/createSphereGeometry.js +1 -1
  44. package/Build/Workers/createSphereOutlineGeometry.js +1 -1
  45. package/Build/Workers/createVectorTileGeometries.js +1 -1
  46. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +0 -22
  47. package/Build/Workers/createWallGeometry.js +1 -1
  48. package/Build/Workers/createWallOutlineGeometry.js +1 -1
  49. package/Build/Workers/package.js +1 -1
  50. package/Build/Workers/transferTypedArrayTest.js +1 -1
  51. package/Source/Core/ArcGISTiledElevationTerrainProvider.js +0 -75
  52. package/Source/Core/CesiumTerrainProvider.js +0 -75
  53. package/Source/Core/CustomHeightmapTerrainProvider.js +0 -38
  54. package/Source/Core/EllipsoidTerrainProvider.js +0 -37
  55. package/Source/Core/Geometry.js +1 -1
  56. package/Source/Core/GoogleEarthEnterpriseMetadata.js +0 -53
  57. package/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +1 -101
  58. package/Source/Core/GoogleMaps.js +1 -1
  59. package/Source/Core/Ion.js +1 -2
  60. package/Source/Core/TerrainProvider.js +0 -22
  61. package/Source/Core/VRTheWorldTerrainProvider.js +0 -59
  62. package/Source/Core/sampleTerrain.js +0 -7
  63. package/Source/Core/sampleTerrainMostDetailed.js +0 -7
  64. package/Source/DataSources/Cesium3DTilesetVisualizer.js +6 -5
  65. package/Source/DataSources/KmlTour.js +1 -12
  66. package/Source/DataSources/ModelVisualizer.js +0 -12
  67. package/Source/Renderer/Context.js +10 -2
  68. package/Source/Scene/ArcGisMapServerImageryProvider.js +7 -335
  69. package/Source/Scene/ArcGisMapService.js +1 -1
  70. package/Source/Scene/Billboard.js +7 -0
  71. package/Source/Scene/BingMapsImageryProvider.js +0 -326
  72. package/Source/Scene/{parseBoundingVolumeSemantics.js → BoundingVolumeSemantics.js} +71 -15
  73. package/Source/Scene/Camera.js +1 -1
  74. package/Source/Scene/Cesium3DTile.js +35 -18
  75. package/Source/Scene/Cesium3DTileContent.js +0 -16
  76. package/Source/Scene/Cesium3DTilesVoxelProvider.js +0 -123
  77. package/Source/Scene/Cesium3DTileset.js +183 -184
  78. package/Source/Scene/Cesium3DTilesetBaseTraversal.js +1 -1
  79. package/Source/Scene/Cesium3DTilesetCache.js +1 -3
  80. package/Source/Scene/Cesium3DTilesetSkipTraversal.js +5 -2
  81. package/Source/Scene/Cesium3DTilesetTraversal.js +2 -2
  82. package/Source/Scene/ClassificationPrimitive.js +5 -43
  83. package/Source/Scene/Composite3DTileContent.js +0 -27
  84. package/Source/Scene/CreditDisplay.js +0 -54
  85. package/Source/Scene/DerivedCommand.js +15 -10
  86. package/Source/Scene/Empty3DTileContent.js +0 -21
  87. package/Source/Scene/Geometry3DTileContent.js +0 -29
  88. package/Source/Scene/Globe.js +1 -9
  89. package/Source/Scene/GlobeSurfaceTile.js +13 -8
  90. package/Source/Scene/GlobeSurfaceTileProvider.js +8 -60
  91. package/Source/Scene/GltfPipeline/removeUnusedElements.js +27 -0
  92. package/Source/Scene/GltfPipeline/updateVersion.js +21 -4
  93. package/Source/Scene/GoogleEarthEnterpriseImageryProvider.js +1 -339
  94. package/Source/Scene/GoogleEarthEnterpriseMapsProvider.js +0 -326
  95. package/Source/Scene/GridImageryProvider.js +0 -274
  96. package/Source/Scene/GroundPolylinePrimitive.js +5 -38
  97. package/Source/Scene/GroundPrimitive.js +5 -43
  98. package/Source/Scene/I3SDataProvider.js +4 -99
  99. package/Source/Scene/I3SLayer.js +15 -22
  100. package/Source/Scene/Imagery.js +1 -9
  101. package/Source/Scene/ImageryLayer.js +1 -40
  102. package/Source/Scene/ImageryProvider.js +0 -138
  103. package/Source/Scene/Implicit3DTileContent.js +4 -25
  104. package/Source/Scene/IonImageryProvider.js +1 -369
  105. package/Source/Scene/MapboxImageryProvider.js +0 -276
  106. package/Source/Scene/MapboxStyleImageryProvider.js +0 -274
  107. package/Source/Scene/Model/CustomShaderPipelineStage.js +178 -164
  108. package/Source/Scene/Model/Model.js +9 -250
  109. package/Source/Scene/Model/Model3DTileContent.js +0 -50
  110. package/Source/Scene/Model/ModelAnimationCollection.js +1 -1
  111. package/Source/Scene/Model/PointCloudStylingPipelineStage.js +1 -1
  112. package/Source/Scene/Multiple3DTileContent.js +0 -27
  113. package/Source/Scene/Primitive.js +10 -38
  114. package/Source/Scene/QuadtreePrimitive.js +3 -5
  115. package/Source/Scene/QuadtreeTileProvider.js +0 -10
  116. package/Source/Scene/Scene.js +3 -3
  117. package/Source/Scene/ScreenSpaceCameraController.js +5 -5
  118. package/Source/Scene/SingleTileImageryProvider.js +6 -302
  119. package/Source/Scene/TileCoordinatesImageryProvider.js +0 -273
  120. package/Source/Scene/TileMapServiceImageryProvider.js +3 -48
  121. package/Source/Scene/Tileset3DTileContent.js +0 -22
  122. package/Source/Scene/TimeDynamicPointCloud.js +0 -28
  123. package/Source/Scene/UrlTemplateImageryProvider.js +0 -375
  124. package/Source/Scene/Vector3DTileContent.js +0 -29
  125. package/Source/Scene/VoxelPrimitive.js +9 -49
  126. package/Source/Scene/VoxelProvider.js +0 -24
  127. package/Source/Scene/WebMapServiceImageryProvider.js +0 -274
  128. package/Source/Scene/WebMapTileServiceImageryProvider.js +0 -274
  129. package/Source/Scene/computeFlyToLocationForRectangle.js +0 -6
  130. package/Source/Scene/createGooglePhotorealistic3DTileset.js +5 -0
  131. package/Source/Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates.glsl +1 -1
  132. package/Source/Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates.js +1 -1
  133. package/Source/Shaders/EllipsoidFS.glsl +1 -1
  134. package/Source/Shaders/EllipsoidFS.js +1 -1
  135. package/Source/Shaders/GlobeFS.glsl +1 -1
  136. package/Source/Shaders/GlobeFS.js +1 -1
  137. package/Source/Widget/CesiumWidget.js +2 -19
  138. package/index.d.ts +62 -1183
  139. package/index.js +63 -66
  140. package/package.json +2 -2
  141. package/Source/Core/createWorldTerrain.js +0 -61
  142. package/Source/Scene/createOsmBuildings.js +0 -82
  143. package/Source/Scene/createWorldImagery.js +0 -47
@@ -71,25 +71,21 @@ CustomShaderPipelineStage.process = function (
71
71
  primitive,
72
72
  frameState
73
73
  ) {
74
- const shaderBuilder = renderResources.shaderBuilder;
75
- const customShader = renderResources.model.customShader;
74
+ const { shaderBuilder, model, alphaOptions } = renderResources;
75
+ const { customShader } = model;
76
76
 
77
77
  // Check the lighting model and translucent options first, as sometimes
78
78
  // these are used even if there is no vertex or fragment shader text.
79
+ const { lightingModel, translucencyMode } = customShader;
79
80
 
80
81
  // if present, the lighting model overrides the material's lighting model.
81
- if (defined(customShader.lightingModel)) {
82
- renderResources.lightingOptions.lightingModel = customShader.lightingModel;
82
+ if (defined(lightingModel)) {
83
+ renderResources.lightingOptions.lightingModel = lightingModel;
83
84
  }
84
85
 
85
- const alphaOptions = renderResources.alphaOptions;
86
- if (
87
- customShader.translucencyMode === CustomShaderTranslucencyMode.TRANSLUCENT
88
- ) {
86
+ if (translucencyMode === CustomShaderTranslucencyMode.TRANSLUCENT) {
89
87
  alphaOptions.pass = Pass.TRANSLUCENT;
90
- } else if (
91
- customShader.translucencyMode === CustomShaderTranslucencyMode.OPAQUE
92
- ) {
88
+ } else if (translucencyMode === CustomShaderTranslucencyMode.OPAQUE) {
93
89
  // Use the default opqaue pass (either OPAQUE or 3D_TILES), regardless of whether
94
90
  // the material pipeline stage used translucent. The default is configured
95
91
  // in AlphaPipelineStage
@@ -163,12 +159,15 @@ CustomShaderPipelineStage.process = function (
163
159
  );
164
160
  };
165
161
 
162
+ /**
163
+ * @private
164
+ * @param {ModelComponents.Attribute[]} attributes
165
+ * @returns {Object<string, ModelComponents.Attribute>}
166
+ */
166
167
  function getAttributesByName(attributes) {
167
168
  const names = {};
168
169
  for (let i = 0; i < attributes.length; i++) {
169
- const attribute = attributes[i];
170
- const attributeInfo = ModelUtility.getAttributeInfo(attribute);
171
-
170
+ const attributeInfo = ModelUtility.getAttributeInfo(attributes[i]);
172
171
  names[attributeInfo.variableName] = attributeInfo;
173
172
  }
174
173
  return names;
@@ -218,39 +217,49 @@ function inferAttributeDefaults(attributeName) {
218
217
  };
219
218
  }
220
219
 
221
- function generateVertexShaderLines(
222
- customShader,
223
- attributesByName,
224
- vertexLines
225
- ) {
226
- const categories = partitionAttributes(
220
+ /**
221
+ * @private
222
+ * @param {CustomShader} customShader
223
+ * @param {Object<string, ModelComponents.Attribute>} attributesByName
224
+ * @returns {object}
225
+ */
226
+ function generateVertexShaderLines(customShader, attributesByName) {
227
+ if (!defined(customShader.vertexShaderText)) {
228
+ return { enabled: false };
229
+ }
230
+
231
+ const primitiveAttributes = customShader.usedVariablesVertex.attributeSet;
232
+ const addToShader = getPrimitiveAttributesUsedInShader(
227
233
  attributesByName,
228
- customShader.usedVariablesVertex.attributeSet,
234
+ primitiveAttributes,
235
+ false
236
+ );
237
+ const needsDefault = getAttributesNeedingDefaults(
238
+ attributesByName,
239
+ primitiveAttributes,
229
240
  false
230
241
  );
231
- const addToShader = categories.addToShader;
232
- const needsDefault = categories.missingAttributes;
233
242
 
234
- let variableName;
235
243
  let vertexInitialization;
236
244
  const attributeFields = [];
237
245
  const initializationLines = [];
238
- for (variableName in addToShader) {
239
- if (addToShader.hasOwnProperty(variableName)) {
240
- const attributeInfo = addToShader[variableName];
241
- const attributeField = [attributeInfo.glslType, variableName];
242
- attributeFields.push(attributeField);
243
-
244
- // Initializing attribute structs are just a matter of copying the
245
- // attribute or varying: E.g.:
246
- // " vsInput.attributes.position = a_position;"
247
- vertexInitialization = `vsInput.attributes.${variableName} = attributes.${variableName};`;
248
- initializationLines.push(vertexInitialization);
246
+ for (const variableName in addToShader) {
247
+ if (!addToShader.hasOwnProperty(variableName)) {
248
+ continue;
249
249
  }
250
+ const attributeInfo = addToShader[variableName];
251
+ const attributeField = [attributeInfo.glslType, variableName];
252
+ attributeFields.push(attributeField);
253
+
254
+ // Initializing attribute structs are just a matter of copying the
255
+ // attribute or varying: E.g.:
256
+ // " vsInput.attributes.position = a_position;"
257
+ vertexInitialization = `vsInput.attributes.${variableName} = attributes.${variableName};`;
258
+ initializationLines.push(vertexInitialization);
250
259
  }
251
260
 
252
261
  for (let i = 0; i < needsDefault.length; i++) {
253
- variableName = needsDefault[i];
262
+ const variableName = needsDefault[i];
254
263
  const attributeDefaults = inferAttributeDefaults(variableName);
255
264
  if (!defined(attributeDefaults)) {
256
265
  CustomShaderPipelineStage._oneTimeWarning(
@@ -259,7 +268,7 @@ function generateVertexShaderLines(
259
268
  );
260
269
  // This primitive isn't compatible with the shader. Return early
261
270
  // to skip the vertex shader
262
- return;
271
+ return { enabled: false };
263
272
  }
264
273
 
265
274
  attributeFields.push(attributeDefaults.attributeField);
@@ -267,9 +276,11 @@ function generateVertexShaderLines(
267
276
  initializationLines.push(vertexInitialization);
268
277
  }
269
278
 
270
- vertexLines.enabled = true;
271
- vertexLines.attributeFields = attributeFields;
272
- vertexLines.initializationLines = initializationLines;
279
+ return {
280
+ enabled: true,
281
+ attributeFields: attributeFields,
282
+ initializationLines: initializationLines,
283
+ };
273
284
  }
274
285
 
275
286
  function generatePositionBuiltins(customShader) {
@@ -303,40 +314,50 @@ function generatePositionBuiltins(customShader) {
303
314
  };
304
315
  }
305
316
 
306
- function generateFragmentShaderLines(
307
- customShader,
308
- attributesByName,
309
- fragmentLines
310
- ) {
311
- const categories = partitionAttributes(
317
+ /**
318
+ * @private
319
+ * @param {CustomShader} customShader
320
+ * @param {Object<string, ModelComponents.Attribute>} attributesByName
321
+ * @returns {object}
322
+ */
323
+ function generateFragmentShaderLines(customShader, attributesByName) {
324
+ if (!defined(customShader.fragmentShaderText)) {
325
+ return { enabled: false };
326
+ }
327
+
328
+ const primitiveAttributes = customShader.usedVariablesFragment.attributeSet;
329
+ const addToShader = getPrimitiveAttributesUsedInShader(
330
+ attributesByName,
331
+ primitiveAttributes,
332
+ true
333
+ );
334
+ const needsDefault = getAttributesNeedingDefaults(
312
335
  attributesByName,
313
- customShader.usedVariablesFragment.attributeSet,
336
+ primitiveAttributes,
314
337
  true
315
338
  );
316
- const addToShader = categories.addToShader;
317
- const needsDefault = categories.missingAttributes;
318
339
 
319
- let variableName;
320
340
  let fragmentInitialization;
321
341
  const attributeFields = [];
322
342
  const initializationLines = [];
323
- for (variableName in addToShader) {
324
- if (addToShader.hasOwnProperty(variableName)) {
325
- const attributeInfo = addToShader[variableName];
326
-
327
- const attributeField = [attributeInfo.glslType, variableName];
328
- attributeFields.push(attributeField);
329
-
330
- // Initializing attribute structs are just a matter of copying the
331
- // value from the processed attributes
332
- // " fsInput.attributes.positionMC = attributes.positionMC;"
333
- fragmentInitialization = `fsInput.attributes.${variableName} = attributes.${variableName};`;
334
- initializationLines.push(fragmentInitialization);
343
+ for (const variableName in addToShader) {
344
+ if (!addToShader.hasOwnProperty(variableName)) {
345
+ continue;
335
346
  }
347
+ const attributeInfo = addToShader[variableName];
348
+
349
+ const attributeField = [attributeInfo.glslType, variableName];
350
+ attributeFields.push(attributeField);
351
+
352
+ // Initializing attribute structs are just a matter of copying the
353
+ // value from the processed attributes
354
+ // " fsInput.attributes.positionMC = attributes.positionMC;"
355
+ fragmentInitialization = `fsInput.attributes.${variableName} = attributes.${variableName};`;
356
+ initializationLines.push(fragmentInitialization);
336
357
  }
337
358
 
338
359
  for (let i = 0; i < needsDefault.length; i++) {
339
- variableName = needsDefault[i];
360
+ const variableName = needsDefault[i];
340
361
  const attributeDefaults = inferAttributeDefaults(variableName);
341
362
  if (!defined(attributeDefaults)) {
342
363
  CustomShaderPipelineStage._oneTimeWarning(
@@ -346,7 +367,7 @@ function generateFragmentShaderLines(
346
367
 
347
368
  // This primitive isn't compatible with the shader. Return early
348
369
  // so the fragment shader is skipped
349
- return;
370
+ return { enabled: false };
350
371
  }
351
372
 
352
373
  attributeFields.push(attributeDefaults.attributeField);
@@ -357,13 +378,13 @@ function generateFragmentShaderLines(
357
378
  // Built-ins for positions in various coordinate systems.
358
379
  const positionBuiltins = generatePositionBuiltins(customShader);
359
380
 
360
- fragmentLines.enabled = true;
361
- fragmentLines.attributeFields = attributeFields.concat(
362
- positionBuiltins.attributeFields
363
- );
364
- fragmentLines.initializationLines = positionBuiltins.initializationLines.concat(
365
- initializationLines
366
- );
381
+ return {
382
+ enabled: true,
383
+ attributeFields: attributeFields.concat(positionBuiltins.attributeFields),
384
+ initializationLines: positionBuiltins.initializationLines.concat(
385
+ initializationLines
386
+ ),
387
+ };
367
388
  }
368
389
 
369
390
  // These attributes are derived from positionMC, and are handled separately
@@ -373,92 +394,101 @@ const builtinAttributes = {
373
394
  positionEC: true,
374
395
  };
375
396
 
376
- function partitionAttributes(
397
+ /**
398
+ * Get the primitive attributes that are referenced in the shader
399
+ *
400
+ * @private
401
+ * @param {Object<string, ModelComponents.Attribute>} primitiveAttributes set of all the primitive's attributes
402
+ * @param {Object<string, ModelComponents.Attribute>} shaderAttributeSet set of all attributes used in the shader
403
+ * @param {boolean} isFragmentShader
404
+ * @returns {Object<string, ModelComponents.Attribute>} A dictionary of the primitive attributes used in the shader
405
+ */
406
+ function getPrimitiveAttributesUsedInShader(
377
407
  primitiveAttributes,
378
408
  shaderAttributeSet,
379
409
  isFragmentShader
380
410
  ) {
381
- // shaderAttributes = set of all attributes used in the shader
382
- // primitiveAttributes = set of all the primitive's attributes
383
- // partition into three categories:
384
- // - addToShader = shaderAttributes intersect primitiveAttributes
385
- // - missingAttributes = shaderAttributes - primitiveAttributes - builtinAttributes
386
- // - unneededAttributes = (primitiveAttributes - shaderAttributes) U builtinAttributes
387
- //
388
- // addToShader are attributes that should be added to the shader.
389
- // missingAttributes are attributes for which we need to provide a default value
390
- // unneededAttributes are other attributes that can be skipped.
391
-
392
- let renamed;
393
- let attributeName;
394
411
  const addToShader = {};
395
- for (attributeName in primitiveAttributes) {
396
- if (primitiveAttributes.hasOwnProperty(attributeName)) {
397
- const attribute = primitiveAttributes[attributeName];
398
-
399
- // normals and tangents are in model coordinates in the attributes but
400
- // in eye coordinates in the fragment shader.
401
- renamed = attributeName;
402
- if (isFragmentShader && attributeName === "normalMC") {
403
- renamed = "normalEC";
404
- } else if (isFragmentShader && attributeName === "tangentMC") {
405
- renamed = "tangentEC";
406
- }
407
-
408
- if (shaderAttributeSet.hasOwnProperty(renamed)) {
409
- addToShader[renamed] = attribute;
410
- }
412
+ for (const attributeName in primitiveAttributes) {
413
+ if (!primitiveAttributes.hasOwnProperty(attributeName)) {
414
+ continue;
415
+ }
416
+ const attribute = primitiveAttributes[attributeName];
417
+
418
+ // normals and tangents are in model coordinates in the attributes but
419
+ // in eye coordinates in the fragment shader.
420
+ let renamed = attributeName;
421
+ if (isFragmentShader && attributeName === "normalMC") {
422
+ renamed = "normalEC";
423
+ } else if (isFragmentShader && attributeName === "tangentMC") {
424
+ renamed = "tangentEC";
425
+ attribute.glslType = "vec3";
411
426
  }
412
- }
413
427
 
414
- const missingAttributes = [];
415
- for (attributeName in shaderAttributeSet) {
416
- if (shaderAttributeSet.hasOwnProperty(attributeName)) {
417
- if (builtinAttributes.hasOwnProperty(attributeName)) {
418
- // Builtins are handled separately from attributes, so skip them here
419
- continue;
420
- }
421
-
422
- // normals and tangents are in model coordinates in the attributes but
423
- // in eye coordinates in the fragment shader.
424
- renamed = attributeName;
425
- if (isFragmentShader && attributeName === "normalEC") {
426
- renamed = "normalMC";
427
- } else if (isFragmentShader && attributeName === "tangentEC") {
428
- renamed = "tangentMC";
429
- }
430
-
431
- if (!primitiveAttributes.hasOwnProperty(renamed)) {
432
- missingAttributes.push(attributeName);
433
- }
428
+ if (shaderAttributeSet.hasOwnProperty(renamed)) {
429
+ addToShader[renamed] = attribute;
434
430
  }
435
431
  }
432
+ return addToShader;
433
+ }
436
434
 
437
- return {
438
- addToShader: addToShader,
439
- missingAttributes: missingAttributes,
440
- };
435
+ /**
436
+ * Get the attributes that will need to have default values defined.
437
+ * Attributes referenced in the shader which are not already defined
438
+ * for the primitive and are not built-in will need default values.
439
+ *
440
+ * @private
441
+ * @param {Object<string, ModelComponents.Attribute>} primitiveAttributes set of all the primitive's attributes
442
+ * @param {Object<string, ModelComponents.Attribute>} shaderAttributeSet set of all attributes used in the shader
443
+ * @param {boolean} isFragmentShader
444
+ * @returns {string[]} The names of the attributes needing defaults
445
+ */
446
+ function getAttributesNeedingDefaults(
447
+ primitiveAttributes,
448
+ shaderAttributeSet,
449
+ isFragmentShader
450
+ ) {
451
+ const needDefaults = [];
452
+ for (const attributeName in shaderAttributeSet) {
453
+ if (!shaderAttributeSet.hasOwnProperty(attributeName)) {
454
+ continue;
455
+ }
456
+ if (builtinAttributes.hasOwnProperty(attributeName)) {
457
+ // Builtins are handled separately from attributes, so skip them here
458
+ continue;
459
+ }
460
+
461
+ // normals and tangents are in model coordinates in the attributes but
462
+ // in eye coordinates in the fragment shader.
463
+ let renamed = attributeName;
464
+ if (isFragmentShader && attributeName === "normalEC") {
465
+ renamed = "normalMC";
466
+ } else if (isFragmentShader && attributeName === "tangentEC") {
467
+ renamed = "tangentMC";
468
+ }
469
+
470
+ if (!primitiveAttributes.hasOwnProperty(renamed)) {
471
+ needDefaults.push(attributeName);
472
+ }
473
+ }
474
+ return needDefaults;
441
475
  }
442
476
 
477
+ /**
478
+ * @private
479
+ * @param {CustomShader} customShader
480
+ * @param {ModelComponents.Primitive} primitive
481
+ * @returns {object}
482
+ */
443
483
  function generateShaderLines(customShader, primitive) {
444
- // Assume shader code is disabled unless proven otherwise
445
- const vertexLines = {
446
- enabled: false,
447
- };
448
- const fragmentLines = {
449
- enabled: false,
450
- };
451
-
452
484
  // Attempt to generate vertex and fragment shader lines before adding any
453
485
  // code to the shader.
454
486
  const attributesByName = getAttributesByName(primitive.attributes);
455
- if (defined(customShader.vertexShaderText)) {
456
- generateVertexShaderLines(customShader, attributesByName, vertexLines);
457
- }
458
-
459
- if (defined(customShader.fragmentShaderText)) {
460
- generateFragmentShaderLines(customShader, attributesByName, fragmentLines);
461
- }
487
+ const vertexLines = generateVertexShaderLines(customShader, attributesByName);
488
+ const fragmentLines = generateFragmentShaderLines(
489
+ customShader,
490
+ attributesByName
491
+ );
462
492
 
463
493
  // positionWC must be computed in the vertex shader
464
494
  // for use in the fragmentShader. However, this can be skipped if:
@@ -473,17 +503,12 @@ function generateShaderLines(customShader, primitive) {
473
503
  return {
474
504
  vertexLines: vertexLines,
475
505
  fragmentLines: fragmentLines,
476
- vertexLinesEnabled: vertexLines.enabled,
477
- fragmentLinesEnabled: fragmentLines.enabled,
478
506
  customShaderEnabled: vertexLines.enabled || fragmentLines.enabled,
479
507
  shouldComputePositionWC: shouldComputePositionWC,
480
508
  };
481
509
  }
482
510
 
483
511
  function addVertexLinesToShader(shaderBuilder, vertexLines) {
484
- // Vertex Lines ---------------------------------------------------------
485
-
486
- let i;
487
512
  let structId = CustomShaderPipelineStage.STRUCT_ID_ATTRIBUTES_VS;
488
513
  shaderBuilder.addStruct(
489
514
  structId,
@@ -491,11 +516,9 @@ function addVertexLinesToShader(shaderBuilder, vertexLines) {
491
516
  ShaderDestination.VERTEX
492
517
  );
493
518
 
494
- const attributeFields = vertexLines.attributeFields;
495
- for (i = 0; i < attributeFields.length; i++) {
496
- const field = attributeFields[i];
497
- const glslType = field[0];
498
- const variableName = field[1];
519
+ const { attributeFields, initializationLines } = vertexLines;
520
+ for (let i = 0; i < attributeFields.length; i++) {
521
+ const [glslType, variableName] = attributeFields[i];
499
522
  shaderBuilder.addStructField(structId, glslType, variableName);
500
523
  }
501
524
 
@@ -545,12 +568,10 @@ function addVertexLinesToShader(shaderBuilder, vertexLines) {
545
568
  ShaderDestination.VERTEX
546
569
  );
547
570
 
548
- const initializationLines = vertexLines.initializationLines;
549
571
  shaderBuilder.addFunctionLines(functionId, initializationLines);
550
572
  }
551
573
 
552
574
  function addFragmentLinesToShader(shaderBuilder, fragmentLines) {
553
- let i;
554
575
  let structId = CustomShaderPipelineStage.STRUCT_ID_ATTRIBUTES_FS;
555
576
  shaderBuilder.addStruct(
556
577
  structId,
@@ -558,14 +579,9 @@ function addFragmentLinesToShader(shaderBuilder, fragmentLines) {
558
579
  ShaderDestination.FRAGMENT
559
580
  );
560
581
 
561
- let field;
562
- let glslType;
563
- let variableName;
564
- const attributeFields = fragmentLines.attributeFields;
565
- for (i = 0; i < attributeFields.length; i++) {
566
- field = attributeFields[i];
567
- glslType = field[0];
568
- variableName = field[1];
582
+ const { attributeFields, initializationLines } = fragmentLines;
583
+ for (let i = 0; i < attributeFields.length; i++) {
584
+ const [glslType, variableName] = attributeFields[i];
569
585
  shaderBuilder.addStructField(structId, glslType, variableName);
570
586
  }
571
587
 
@@ -613,14 +629,13 @@ function addFragmentLinesToShader(shaderBuilder, fragmentLines) {
613
629
  ShaderDestination.FRAGMENT
614
630
  );
615
631
 
616
- const initializationLines = fragmentLines.initializationLines;
617
632
  shaderBuilder.addFunctionLines(functionId, initializationLines);
618
633
  }
619
634
 
620
635
  const scratchShaderLines = [];
621
636
 
622
637
  function addLinesToShader(shaderBuilder, customShader, generatedCode) {
623
- const vertexLines = generatedCode.vertexLines;
638
+ const { vertexLines, fragmentLines } = generatedCode;
624
639
  const shaderLines = scratchShaderLines;
625
640
 
626
641
  if (vertexLines.enabled) {
@@ -636,7 +651,6 @@ function addLinesToShader(shaderBuilder, customShader, generatedCode) {
636
651
  shaderBuilder.addVertexLines(shaderLines);
637
652
  }
638
653
 
639
- const fragmentLines = generatedCode.fragmentLines;
640
654
  if (fragmentLines.enabled) {
641
655
  addFragmentLinesToShader(shaderBuilder, fragmentLines);
642
656