mirror of https://github.com/CesiumGS/cesium.git
Merge branch 'main' into misaligned-glyph-fix
This commit is contained in:
commit
aff7ef353e
|
|
@ -7,6 +7,7 @@
|
|||
#### Fixes :wrench:
|
||||
|
||||
- Materials loaded from type now respect submaterials present in the referenced material type. [#10566](https://github.com/CesiumGS/cesium/issues/10566)
|
||||
- Reverts `createImageBitmap` options update to continue support for older browsers [#12846](https://github.com/CesiumGS/cesium/issues/12846)
|
||||
- Fix flickering artifact in Gaussian splat models caused by incorrect sorting results. [#12662](https://github.com/CesiumGS/cesium/issues/12662)
|
||||
- Fixes vertical misalignment of glyphs in labels with small fonts [#8474](https://github.com/CesiumGS/cesium/issues/8474)
|
||||
|
||||
|
|
@ -14,6 +15,10 @@
|
|||
|
||||
- Adds an async factory method for the Material class that allows callers to wait on resource loading. [#10566](https://github.com/CesiumGS/cesium/issues/10566)
|
||||
|
||||
## 1.133.1 - 2025-09-08
|
||||
|
||||
This is an npm-only release to fix a dependency issue published in 1.133.0
|
||||
|
||||
## 1.133 - 2025-09-02
|
||||
|
||||
- Give the [new version of Sandcastle](https://dev-sandcastle.cesium.com/) a try today!
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "cesium",
|
||||
"version": "1.133.0",
|
||||
"version": "1.133.1",
|
||||
"description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.",
|
||||
"homepage": "http://cesium.com/cesiumjs/",
|
||||
"license": "Apache-2.0",
|
||||
|
|
@ -51,8 +51,8 @@
|
|||
"./Specs/**/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"@cesium/engine": "^20.0.0",
|
||||
"@cesium/widgets": "^13.1.0"
|
||||
"@cesium/engine": "^20.0.1",
|
||||
"@cesium/widgets": "^13.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cesium/eslint-config": "^12.0.0",
|
||||
|
|
@ -171,4 +171,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -231,6 +231,8 @@ Resource.supportsImageBitmapOptions = function () {
|
|||
})
|
||||
.then(function (blob) {
|
||||
const imageBitmapOptions = {
|
||||
// 'from-image' is deprecated, new option is 'none'. However, we still need to support older browsers,
|
||||
// and there's no good way to detect support for these options. For now, continue to use 'from-image'. See: https://github.com/CesiumGS/cesium/issues/12846
|
||||
imageOrientation: "flipY", // default is "from-image"
|
||||
premultiplyAlpha: "none", // default is "default"
|
||||
colorSpaceConversion: "none", // default is "default"
|
||||
|
|
@ -2036,7 +2038,9 @@ Resource.createImageBitmapFromBlob = function (blob, options) {
|
|||
);
|
||||
|
||||
return createImageBitmap(blob, {
|
||||
imageOrientation: options.flipY ? "flipY" : "from-image",
|
||||
// 'from-image' is deprecated, new option is 'none'. However, we still need to support older browsers,
|
||||
// and there's no good way to detect support for these options. For now, continue to use 'from-image'. See: https://github.com/CesiumGS/cesium/issues/12846
|
||||
imageOrientation: options.flipY ? "flipY" : "none",
|
||||
premultiplyAlpha: options.premultiplyAlpha ? "premultiply" : "none",
|
||||
colorSpaceConversion: options.skipColorSpaceConversion ? "none" : "default",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ describe("Core/loadImageFromTypedArray", function () {
|
|||
})
|
||||
.then(function () {
|
||||
expect(window.createImageBitmap).toHaveBeenCalledWith(blob, {
|
||||
imageOrientation: "from-image",
|
||||
imageOrientation: "none",
|
||||
premultiplyAlpha: "none",
|
||||
colorSpaceConversion: "default",
|
||||
});
|
||||
|
|
@ -91,7 +91,7 @@ describe("Core/loadImageFromTypedArray", function () {
|
|||
return loadImageFromTypedArray(options)
|
||||
.then(function () {
|
||||
expect(window.createImageBitmap).toHaveBeenCalledWith(blob, {
|
||||
imageOrientation: "from-image",
|
||||
imageOrientation: "none",
|
||||
premultiplyAlpha: "none",
|
||||
colorSpaceConversion: "none",
|
||||
});
|
||||
|
|
@ -102,7 +102,7 @@ describe("Core/loadImageFromTypedArray", function () {
|
|||
})
|
||||
.then(function () {
|
||||
expect(window.createImageBitmap).toHaveBeenCalledWith(blob, {
|
||||
imageOrientation: "from-image",
|
||||
imageOrientation: "none",
|
||||
premultiplyAlpha: "none",
|
||||
colorSpaceConversion: "default",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@cesium/engine",
|
||||
"version": "20.0.0",
|
||||
"version": "20.0.1",
|
||||
"description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.",
|
||||
"keywords": [
|
||||
"3D",
|
||||
|
|
|
|||
|
|
@ -56,6 +56,14 @@ viewer.zoomTo(imageryLayer);
|
|||
// Add a button to toggle the display of the Bing Maps Labels Only layer
|
||||
Sandcastle.addToggleButton("Show Bing Maps Labels Only", true, (checked) => {
|
||||
bingMapsLabelsOnly.show = checked;
|
||||
const rightLabel = document.querySelector(".split-label.right");
|
||||
if (checked) {
|
||||
rightLabel.innerHTML =
|
||||
"Bing Maps (unlabeled)<br />+<br />Washington Imagery<br />+<br />Bing Maps (labels only)";
|
||||
} else {
|
||||
rightLabel.innerHTML =
|
||||
"Bing Maps (unlabeled)<br />+<br />Washington Imagery";
|
||||
}
|
||||
});
|
||||
|
||||
// The remaining code synchronizes the position of the slider with the split position
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<div id="cesiumContainer" class="fullSize"></div>
|
||||
<div id="loadingOverlay"><h1>Loading...</h1></div>
|
||||
<div id="toolbar">
|
||||
<table class="infoPanel">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Click on the Cesium display to start.</td>
|
||||
|
|
|
|||
|
|
@ -14,12 +14,10 @@ const viewer = new Cesium.Viewer("cesiumContainer", {
|
|||
});
|
||||
viewer.scene.skyAtmosphere.show = true;
|
||||
|
||||
const iTwinId = "535a24a3-9b29-4e23-bb5d-9cedb524c743";
|
||||
const realityMeshId = "85897090-3bcc-470b-bec7-20bb639cc1b9";
|
||||
const tileset = await Cesium.ITwinData.createTilesetForRealityDataId(
|
||||
iTwinId,
|
||||
realityMeshId,
|
||||
);
|
||||
const tileset = await Cesium.ITwinData.createTilesetForRealityDataId({
|
||||
iTwinId: "535a24a3-9b29-4e23-bb5d-9cedb524c743",
|
||||
realityDataId: "85897090-3bcc-470b-bec7-20bb639cc1b9",
|
||||
});
|
||||
viewer.scene.primitives.add(tileset);
|
||||
tileset.maximumScreenSpaceError = 2;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
<style>
|
||||
@import url(../templates/bucket.css);
|
||||
|
||||
#toolbar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
<div id="cesiumContainer" class="fullSize"></div>
|
||||
<div id="loadingOverlay"><h1>Loading...</h1></div>
|
||||
|
|
|
|||
|
|
@ -421,8 +421,6 @@ function createButtons(scene) {
|
|||
},
|
||||
},
|
||||
]);
|
||||
|
||||
document.getElementById("toolbar").style.width = "10%";
|
||||
}
|
||||
|
||||
function createPrimitives(scene) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<h1>Loading...</h1>
|
||||
</div>
|
||||
<div id="toolbar">
|
||||
<table class="infoPanel">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<div id="cesiumContainer" class="fullSize"></div>
|
||||
<div id="loadingOverlay"><h1>Loading...</h1></div>
|
||||
<div id="toolbar">
|
||||
<table class="infoPanel">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Click on the Cesium display to start.</td>
|
||||
|
|
|
|||
|
|
@ -80,12 +80,12 @@ function unselectFeature(feature) {
|
|||
}
|
||||
|
||||
// Create tilesets using the iModel ids
|
||||
const surroundingArea = await Cesium.ITwinData.createTilesetFromIModelId(
|
||||
"f856f57d-3d28-4265-9c4f-5e60c0662c15",
|
||||
);
|
||||
const station = await Cesium.ITwinData.createTilesetFromIModelId(
|
||||
"669dde67-eb69-4e0b-bcf2-f722eee94746",
|
||||
);
|
||||
const surroundingArea = await Cesium.ITwinData.createTilesetFromIModelId({
|
||||
iModelId: "f856f57d-3d28-4265-9c4f-5e60c0662c15",
|
||||
});
|
||||
const station = await Cesium.ITwinData.createTilesetFromIModelId({
|
||||
iModelId: "669dde67-eb69-4e0b-bcf2-f722eee94746",
|
||||
});
|
||||
// Change how highlighting with the feature selection changes the color
|
||||
surroundingArea.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.REPLACE;
|
||||
station.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.REPLACE;
|
||||
|
|
@ -94,12 +94,10 @@ scene.primitives.add(surroundingArea);
|
|||
scene.primitives.add(station);
|
||||
|
||||
// Create tileset of the reality data mesh
|
||||
const iTwinId = "535a24a3-9b29-4e23-bb5d-9cedb524c743";
|
||||
const realityMeshId = "85897090-3bcc-470b-bec7-20bb639cc1b9";
|
||||
const realityMesh = await Cesium.ITwinData.createTilesetForRealityDataId(
|
||||
iTwinId,
|
||||
realityMeshId,
|
||||
);
|
||||
const realityMesh = await Cesium.ITwinData.createTilesetForRealityDataId({
|
||||
iTwinId: "535a24a3-9b29-4e23-bb5d-9cedb524c743",
|
||||
realityDataId: "85897090-3bcc-470b-bec7-20bb639cc1b9",
|
||||
});
|
||||
scene.primitives.add(realityMesh);
|
||||
|
||||
Sandcastle.addToolbarButton(
|
||||
|
|
|
|||
|
|
@ -38,18 +38,18 @@ const birdsEyeView = {
|
|||
viewer.scene.camera.flyTo(birdsEyeView);
|
||||
|
||||
// Load feature service geojson files
|
||||
const points = await Cesium.ITwinData.loadGeospatialFeatures(
|
||||
iTwinId,
|
||||
"2380dc1b-1dac-4709-aa5c-f6cb38c4e9f5",
|
||||
);
|
||||
const lines = await Cesium.ITwinData.loadGeospatialFeatures(
|
||||
iTwinId,
|
||||
"613d2310-4d01-43b7-bc92-873a2ca4a4a0",
|
||||
);
|
||||
const areas = await Cesium.ITwinData.loadGeospatialFeatures(
|
||||
iTwinId,
|
||||
"93e7ef51-5210-49f2-92a3-c7f6685e102f",
|
||||
);
|
||||
const points = await Cesium.ITwinData.loadGeospatialFeatures({
|
||||
iTwinId: iTwinId,
|
||||
collectionId: "2380dc1b-1dac-4709-aa5c-f6cb38c4e9f5",
|
||||
});
|
||||
const lines = await Cesium.ITwinData.loadGeospatialFeatures({
|
||||
iTwinId: iTwinId,
|
||||
collectionId: "613d2310-4d01-43b7-bc92-873a2ca4a4a0",
|
||||
});
|
||||
const areas = await Cesium.ITwinData.loadGeospatialFeatures({
|
||||
iTwinId: iTwinId,
|
||||
collectionId: "93e7ef51-5210-49f2-92a3-c7f6685e102f",
|
||||
});
|
||||
|
||||
// Add some styling to the lines and points to differentiate types
|
||||
const pinBuilder = new Cesium.PinBuilder();
|
||||
|
|
@ -90,17 +90,15 @@ viewer.dataSources.add(lines);
|
|||
viewer.dataSources.add(areas);
|
||||
|
||||
// Create tileset of the reality data mesh and pointcloud
|
||||
const realityMeshId = "62e4432d-621d-489a-87ff-1fc56a2b5369";
|
||||
const realityMesh = await Cesium.ITwinData.createTilesetForRealityDataId(
|
||||
iTwinId,
|
||||
realityMeshId,
|
||||
);
|
||||
const realityMesh = await Cesium.ITwinData.createTilesetForRealityDataId({
|
||||
iTwinId: iTwinId,
|
||||
realityDataId: "62e4432d-621d-489a-87ff-1fc56a2b5369",
|
||||
});
|
||||
viewer.scene.primitives.add(realityMesh);
|
||||
const pointcloudId = "ebf2ee74-f0de-4cd6-a311-19a169c55fdc";
|
||||
const pointcloud = await Cesium.ITwinData.createTilesetForRealityDataId(
|
||||
iTwinId,
|
||||
pointcloudId,
|
||||
);
|
||||
const pointcloud = await Cesium.ITwinData.createTilesetForRealityDataId({
|
||||
iTwinId: iTwinId,
|
||||
realityDataId: "ebf2ee74-f0de-4cd6-a311-19a169c55fdc",
|
||||
});
|
||||
// increase the size of the pointcloud points and turn on attenuation to
|
||||
// make them more visible in the viewer
|
||||
pointcloud.maximumScreenSpaceError = 1;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<h1>Loading...</h1>
|
||||
</div>
|
||||
<div id="toolbar">
|
||||
<table class="infoPanel">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
<style>
|
||||
@import url(../templates/bucket.css);
|
||||
|
||||
#toolbar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
<div id="cesiumContainer" class="fullSize"></div>
|
||||
<div id="loadingOverlay"><h1>Loading...</h1></div>
|
||||
|
|
|
|||
|
|
@ -510,8 +510,6 @@ function createButtons(scene) {
|
|||
},
|
||||
},
|
||||
]);
|
||||
|
||||
document.getElementById("toolbar").style.width = "10%";
|
||||
}
|
||||
|
||||
function createPrimitives(scene) {
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
<style>
|
||||
@import url(../templates/bucket.css);
|
||||
</style>
|
||||
<div id="cesiumContainer" class="fullSize"></div>
|
||||
<div id="loadingOverlay">
|
||||
<h1>Loading...</h1>
|
||||
</div>
|
||||
<div id="toolbar"></div>
|
||||
|
|
@ -1,610 +0,0 @@
|
|||
import * as Cesium from "cesium";
|
||||
|
||||
// ImprovedNoise from Three.js
|
||||
// https://github.com/mrdoob/three.js/blob/dev/examples/jsm/math/ImprovedNoise.js
|
||||
|
||||
const lerp = Cesium.Math.lerp;
|
||||
|
||||
const _p = [
|
||||
151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140,
|
||||
36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234,
|
||||
75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237,
|
||||
149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48,
|
||||
27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105,
|
||||
92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73,
|
||||
209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86,
|
||||
164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38,
|
||||
147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189,
|
||||
28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101,
|
||||
155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232,
|
||||
178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12,
|
||||
191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31,
|
||||
181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,
|
||||
138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215,
|
||||
61, 156, 180,
|
||||
];
|
||||
|
||||
for (let i = 0; i < 256; i++) {
|
||||
_p[256 + i] = _p[i];
|
||||
}
|
||||
|
||||
function fade(t) {
|
||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
function grad(hash, x, y, z) {
|
||||
const h = hash & 15;
|
||||
const u = h < 8 ? x : y,
|
||||
v = h < 4 ? y : h === 12 || h === 14 ? x : z;
|
||||
return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility class providing a 3D noise function.
|
||||
*
|
||||
* The code is based on [IMPROVED NOISE]{@link https://cs.nyu.edu/~perlin/noise/}
|
||||
* by Ken Perlin, 2002.
|
||||
*
|
||||
* @three_import import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js';
|
||||
*/
|
||||
class ImprovedNoise {
|
||||
/**
|
||||
* Returns a noise value for the given parameters.
|
||||
*
|
||||
* @param {number} x - The x coordinate.
|
||||
* @param {number} y - The y coordinate.
|
||||
* @param {number} z - The z coordinate.
|
||||
* @return {number} The noise value.
|
||||
*/
|
||||
noise(x, y, z) {
|
||||
const floorX = Math.floor(x),
|
||||
floorY = Math.floor(y),
|
||||
floorZ = Math.floor(z);
|
||||
|
||||
const X = floorX & 255,
|
||||
Y = floorY & 255,
|
||||
Z = floorZ & 255;
|
||||
|
||||
x -= floorX;
|
||||
y -= floorY;
|
||||
z -= floorZ;
|
||||
|
||||
const xMinus1 = x - 1,
|
||||
yMinus1 = y - 1,
|
||||
zMinus1 = z - 1;
|
||||
|
||||
const u = fade(x),
|
||||
v = fade(y),
|
||||
w = fade(z);
|
||||
|
||||
const A = _p[X] + Y,
|
||||
AA = _p[A] + Z,
|
||||
AB = _p[A + 1] + Z,
|
||||
B = _p[X + 1] + Y,
|
||||
BA = _p[B] + Z,
|
||||
BB = _p[B + 1] + Z;
|
||||
|
||||
return lerp(
|
||||
lerp(
|
||||
lerp(grad(_p[AA], x, y, z), grad(_p[BA], xMinus1, y, z), u),
|
||||
lerp(grad(_p[AB], x, yMinus1, z), grad(_p[BB], xMinus1, yMinus1, z), u),
|
||||
v,
|
||||
),
|
||||
lerp(
|
||||
lerp(
|
||||
grad(_p[AA + 1], x, y, zMinus1),
|
||||
grad(_p[BA + 1], xMinus1, y, zMinus1),
|
||||
u,
|
||||
),
|
||||
lerp(
|
||||
grad(_p[AB + 1], x, yMinus1, zMinus1),
|
||||
grad(_p[BB + 1], xMinus1, yMinus1, zMinus1),
|
||||
u,
|
||||
),
|
||||
v,
|
||||
),
|
||||
w,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// End ImprovedNoise from Three.js
|
||||
|
||||
// GeometryPrimitive
|
||||
const {
|
||||
Cartesian3,
|
||||
destroyObject,
|
||||
DrawCommand,
|
||||
VertexArray,
|
||||
GeometryPipeline,
|
||||
Matrix4,
|
||||
} = Cesium;
|
||||
|
||||
/**
|
||||
* Custom Primitive for Geometry
|
||||
*/
|
||||
class GeometryPrimitive {
|
||||
/**
|
||||
*
|
||||
* @param {*} options
|
||||
* @param {*} options.modelMatrix
|
||||
* @param {*} options.vertexShaderSource
|
||||
* @param {*} options.fragmentShaderSource
|
||||
* @param {*} options.uniformMap
|
||||
* @param {*} options.renderState
|
||||
* @param {*} options.pass
|
||||
*/
|
||||
constructor(geometry, options) {
|
||||
this.options = options;
|
||||
this.geometry = geometry;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} frameState
|
||||
*/
|
||||
update(frameState) {
|
||||
if (Cesium.defined(this._drawCommand)) {
|
||||
frameState.commandList.push(this._drawCommand);
|
||||
return;
|
||||
}
|
||||
if (this.geometry.constructor.createGeometry) {
|
||||
this.geometry = this.geometry.constructor.createGeometry(this.geometry);
|
||||
}
|
||||
|
||||
const context = frameState.context;
|
||||
|
||||
const attributeLocations = GeometryPipeline.createAttributeLocations(
|
||||
this.geometry,
|
||||
);
|
||||
const vertexArray = VertexArray.fromGeometry({
|
||||
context: context,
|
||||
geometry: this.geometry,
|
||||
attributeLocations,
|
||||
});
|
||||
|
||||
// calculate boundingSphere
|
||||
const boundingSphere = this.geometry.boundingSphere;
|
||||
boundingSphere.center = Matrix4.multiplyByPoint(
|
||||
this.options.modelMatrix,
|
||||
boundingSphere.center,
|
||||
new Cartesian3(),
|
||||
);
|
||||
boundingSphere.radius = 1000000;
|
||||
|
||||
this._boundingSphereWC = [boundingSphere];
|
||||
|
||||
const shaderProgram = Cesium.ShaderProgram.fromCache({
|
||||
context: context,
|
||||
attributeLocations,
|
||||
vertexShaderSource: this.options.vertexShaderSource,
|
||||
fragmentShaderSource: this.options.fragmentShaderSource,
|
||||
});
|
||||
|
||||
this._drawCommand = new DrawCommand({
|
||||
owner: this,
|
||||
boundingVolume: boundingSphere,
|
||||
primitiveType: this.geometry.primitiveType,
|
||||
vertexArray: vertexArray,
|
||||
shaderProgram,
|
||||
...this.options,
|
||||
});
|
||||
}
|
||||
|
||||
destroy() {
|
||||
return destroyObject(this);
|
||||
}
|
||||
|
||||
isDestroyed() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// GeometryPrimitive end
|
||||
|
||||
function makeTexture3D(context) {
|
||||
const size = 100;
|
||||
const dataLength = size * size * size;
|
||||
const data = new Uint8Array(dataLength);
|
||||
let i = 0;
|
||||
const scale = 0.05;
|
||||
const perlin = new ImprovedNoise();
|
||||
let vector = new Cesium.Cartesian3();
|
||||
const halfSize = Cesium.Cartesian3.fromElements(
|
||||
size / 2,
|
||||
size / 2,
|
||||
size / 2,
|
||||
new Cesium.Cartesian3(),
|
||||
);
|
||||
|
||||
for (let z = 0; z < size; z++) {
|
||||
for (let y = 0; y < size; y++) {
|
||||
for (let x = 0; x < size; x++) {
|
||||
vector = Cesium.Cartesian3.fromElements(x, y, z, vector);
|
||||
vector = Cesium.Cartesian3.subtract(vector, halfSize, vector);
|
||||
vector = Cesium.Cartesian3.divideByScalar(vector, size, vector);
|
||||
|
||||
const d = 1.0 - Cesium.Cartesian3.magnitude(vector);
|
||||
const tv =
|
||||
(128 +
|
||||
128 *
|
||||
perlin.noise((x * scale) / 1.5, y * scale, (z * scale) / 1.5)) *
|
||||
d *
|
||||
d;
|
||||
|
||||
data[i] = tv;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Cesium.Texture3D({
|
||||
context: context,
|
||||
width: size,
|
||||
height: size,
|
||||
depth: size,
|
||||
flipY: false,
|
||||
pixelFormat: Cesium.PixelFormat.RED,
|
||||
pixelDatatype: Cesium.PixelDatatype.UNSIGNED_BYTE,
|
||||
source: {
|
||||
arrayBufferView: data,
|
||||
width: size,
|
||||
height: size,
|
||||
depth: size,
|
||||
},
|
||||
sampler: new Cesium.Sampler({
|
||||
minificationFilter: Cesium.TextureMinificationFilter.LINEAR,
|
||||
magnificationFilter: Cesium.TextureMagnificationFilter.LINEAR,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
const vertexShader = /* glsl */ `
|
||||
in vec3 position3DHigh;
|
||||
in vec3 position3DLow;
|
||||
in vec3 normal;
|
||||
in vec2 st;
|
||||
in float batchId;
|
||||
|
||||
out vec3 vOrigin;
|
||||
out vec3 vDirection;
|
||||
out vec3 vPosition;
|
||||
|
||||
vec4 translateRelativeToEye(vec3 high, vec3 low) {
|
||||
vec3 highDifference = high - czm_encodedCameraPositionMCHigh;
|
||||
if(length(highDifference) == 0.0f) {
|
||||
highDifference = vec3(0);
|
||||
}
|
||||
vec3 lowDifference = low - czm_encodedCameraPositionMCLow;
|
||||
return vec4(highDifference + lowDifference, 1.0f);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 p = translateRelativeToEye(position3DHigh, position3DLow);
|
||||
|
||||
vOrigin = czm_encodedCameraPositionMCHigh + czm_encodedCameraPositionMCLow;
|
||||
|
||||
vec3 modelPosition = position3DHigh + position3DLow;
|
||||
vPosition = modelPosition;
|
||||
|
||||
vDirection = modelPosition - vOrigin;
|
||||
|
||||
gl_Position = czm_modelViewProjectionRelativeToEye * p;
|
||||
}`;
|
||||
|
||||
const fragmentShader = /* glsl */ `
|
||||
precision highp float;
|
||||
precision highp sampler3D;
|
||||
|
||||
in vec3 vOrigin;
|
||||
in vec3 vDirection;
|
||||
|
||||
// https://github.com/mrdoob/three.js/blob/dev/examples/webgl_volume_cloud.html
|
||||
uniform vec3 base;
|
||||
uniform sampler3D map;
|
||||
uniform float threshold;
|
||||
uniform float range;
|
||||
uniform float opacity;
|
||||
uniform float steps;
|
||||
uniform float frame;
|
||||
|
||||
uint wang_hash(uint seed)
|
||||
{
|
||||
seed = (seed ^ 61u) ^ (seed >> 16u);
|
||||
seed *= 9u;
|
||||
seed = seed ^ (seed >> 4u);
|
||||
seed *= 0x27d4eb2du;
|
||||
seed = seed ^ (seed >> 15u);
|
||||
return seed;
|
||||
}
|
||||
|
||||
float randomFloat(inout uint seed)
|
||||
{
|
||||
return float(wang_hash(seed)) / 4294967296.;
|
||||
}
|
||||
|
||||
vec2 hitBox( vec3 orig, vec3 dir ) {
|
||||
const vec3 box_min = vec3( - 0.5 );
|
||||
const vec3 box_max = vec3( 0.5 );
|
||||
vec3 inv_dir = 1.0 / dir;
|
||||
vec3 tmin_tmp = ( box_min - orig ) * inv_dir;
|
||||
vec3 tmax_tmp = ( box_max - orig ) * inv_dir;
|
||||
vec3 tmin = min( tmin_tmp, tmax_tmp );
|
||||
vec3 tmax = max( tmin_tmp, tmax_tmp );
|
||||
float t0 = max( tmin.x, max( tmin.y, tmin.z ) );
|
||||
float t1 = min( tmax.x, min( tmax.y, tmax.z ) );
|
||||
return vec2( t0, t1 );
|
||||
}
|
||||
|
||||
float sample1( vec3 p ) {
|
||||
return texture( map, p ).r;
|
||||
}
|
||||
|
||||
float shading( vec3 coord ) {
|
||||
float step = 0.01;
|
||||
return sample1( coord + vec3( - step ) ) - sample1( coord + vec3( step ) );
|
||||
}
|
||||
|
||||
vec4 linearToSRGB( in vec4 value ) {
|
||||
return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 rayDir = normalize( vDirection );
|
||||
vec2 bounds = hitBox( vOrigin, rayDir );
|
||||
if ( bounds.x > bounds.y ) discard;
|
||||
bounds.x = max( bounds.x, 0.0 );
|
||||
vec3 p = vOrigin + bounds.x * rayDir;
|
||||
vec3 inc = 1.0 / abs( rayDir );
|
||||
float delta = min( inc.x, min( inc.y, inc.z ) );
|
||||
delta /= steps;
|
||||
|
||||
// Nice little seed from
|
||||
// https://blog.demofox.org/2020/05/25/casual-shadertoy-path-tracing-1-basic-camera-diffuse-emissive/
|
||||
uint seed = uint( gl_FragCoord.x ) * uint( 1973 ) + uint( gl_FragCoord.y ) * uint( 9277 ) + uint( frame ) * uint( 26699 );
|
||||
vec3 size = vec3( textureSize( map, 0 ) );
|
||||
float randNum = randomFloat( seed ) * 2.0 - 1.0;
|
||||
p += rayDir * randNum * ( 1.0 / size );
|
||||
|
||||
vec4 ac = vec4( base, 0.0 );
|
||||
for ( float t = bounds.x; t < bounds.y; t += delta ) {
|
||||
float d = sample1( p + 0.5 );
|
||||
d = smoothstep( threshold - range, threshold + range, d ) * opacity;
|
||||
float col = shading( p + 0.5 ) * 3.0 + ( ( p.x + p.y ) * 0.25 ) + 0.2;
|
||||
ac.rgb += ( 1.0 - ac.a ) * d * col;
|
||||
ac.a += ( 1.0 - ac.a ) * d;
|
||||
if ( ac.a >= 0.95 ) break;
|
||||
p += rayDir * delta;
|
||||
}
|
||||
vec4 color = linearToSRGB( ac );
|
||||
color = czm_gammaCorrect( color );
|
||||
if ( color.a == 0.0 ) discard;
|
||||
out_FragColor = color;
|
||||
}
|
||||
`;
|
||||
|
||||
const viewer = new Cesium.Viewer("cesiumContainer", {
|
||||
orderIndependentTranslucency: true,
|
||||
});
|
||||
const texture3D = makeTexture3D(viewer.scene.context);
|
||||
texture3D.generateMipmap();
|
||||
|
||||
const boxSideLength = 1.0;
|
||||
const zoomScale = 10000;
|
||||
const centerPoint = Cesium.Cartesian3.fromDegrees(
|
||||
113,
|
||||
33,
|
||||
(boxSideLength / 0.5) * zoomScale,
|
||||
);
|
||||
|
||||
const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(centerPoint);
|
||||
|
||||
const boxSize = new Cesium.Cartesian3(
|
||||
boxSideLength,
|
||||
boxSideLength,
|
||||
boxSideLength,
|
||||
);
|
||||
|
||||
const renderState = Cesium.RenderState.fromCache({
|
||||
depthMask: false,
|
||||
blending: {
|
||||
enabled: true,
|
||||
color: {
|
||||
red: 0.0,
|
||||
green: 0.0,
|
||||
blue: 0.0,
|
||||
alpha: 0.0,
|
||||
},
|
||||
},
|
||||
depthTest: {
|
||||
enabled: true,
|
||||
func: Cesium.DepthFunction.LESS_OR_EQUAL,
|
||||
},
|
||||
cull: {
|
||||
enabled: true,
|
||||
face: Cesium.CullFace.FRONT,
|
||||
},
|
||||
});
|
||||
|
||||
const zoomMat = Cesium.Matrix4.fromScale(
|
||||
new Cesium.Cartesian3(zoomScale, zoomScale, zoomScale),
|
||||
new Cesium.Matrix4(),
|
||||
);
|
||||
|
||||
Cesium.Matrix4.multiply(modelMatrix, zoomMat, modelMatrix);
|
||||
|
||||
const halfBox = Cesium.Cartesian3.multiplyByScalar(
|
||||
boxSize,
|
||||
0.5,
|
||||
new Cesium.Cartesian3(),
|
||||
);
|
||||
const negHalfBox = Cesium.Cartesian3.negate(halfBox, new Cesium.Cartesian3());
|
||||
|
||||
const boxGeometry = new Cesium.BoxGeometry({
|
||||
minimum: negHalfBox,
|
||||
maximum: halfBox,
|
||||
});
|
||||
|
||||
const uniforms = {
|
||||
base: new Cesium.Color(0.1912, 0.2542, 0.3515, 0),
|
||||
map: texture3D,
|
||||
opacity: 0.25,
|
||||
range: 0.1,
|
||||
steps: 100,
|
||||
frame: 0,
|
||||
threshold: 0.25,
|
||||
};
|
||||
|
||||
window.uniforms = uniforms;
|
||||
|
||||
const cmdUniforms = {};
|
||||
for (const key in uniforms) {
|
||||
if (key) {
|
||||
cmdUniforms[key] = function () {
|
||||
return uniforms[key];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const primitive = new GeometryPrimitive(boxGeometry, {
|
||||
uniformMap: cmdUniforms,
|
||||
vertexShaderSource: vertexShader,
|
||||
fragmentShaderSource: fragmentShader,
|
||||
renderState: renderState,
|
||||
modelMatrix,
|
||||
pass: Cesium.Pass.TRANSLUCENT,
|
||||
});
|
||||
|
||||
viewer.scene.primitives.add(primitive);
|
||||
|
||||
const cameraState = {
|
||||
destination: centerPoint,
|
||||
orientation: {
|
||||
heading: 4.159717744111784,
|
||||
pitch: -0.4648127266675117,
|
||||
roll: boxSideLength * zoomScale * 2,
|
||||
},
|
||||
duration: 0,
|
||||
};
|
||||
// viewer.camera.flyTo(camState);
|
||||
const hpr = new Cesium.HeadingPitchRange(
|
||||
cameraState.orientation.heading,
|
||||
cameraState.orientation.pitch,
|
||||
boxSideLength * zoomScale * 2,
|
||||
);
|
||||
viewer.camera.lookAt(cameraState.destination, hpr);
|
||||
|
||||
// create params control UI
|
||||
function createSlider(
|
||||
toolbar,
|
||||
{ labelText, min, max, step, defaultValue, callback },
|
||||
) {
|
||||
const container = document.createElement("div");
|
||||
container.style.cssText = `
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 8px;
|
||||
`;
|
||||
|
||||
const label = document.createElement("label");
|
||||
label.textContent = labelText;
|
||||
label.style.cssText = `
|
||||
color: #ffffff;
|
||||
font-family: Arial, sans-serif;
|
||||
min-width: 60px;
|
||||
font-size: 14px;
|
||||
`;
|
||||
|
||||
const slider = document.createElement("input");
|
||||
slider.type = "range";
|
||||
slider.min = min;
|
||||
slider.max = max;
|
||||
slider.step = step;
|
||||
slider.value = defaultValue;
|
||||
slider.style.cssText = `
|
||||
width: 100px;
|
||||
cursor: pointer;
|
||||
accent-color: #4CAF50;
|
||||
`;
|
||||
slider.addEventListener("input", (e) => callback(e.target.value));
|
||||
|
||||
const valueDisplay = document.createElement("span");
|
||||
valueDisplay.textContent = defaultValue;
|
||||
valueDisplay.style.cssText = `
|
||||
color: #ffffff;
|
||||
font-family: monospace;
|
||||
width: 30px;
|
||||
text-align: right;
|
||||
`;
|
||||
slider.addEventListener("input", (e) => {
|
||||
valueDisplay.textContent = parseFloat(e.target.value).toFixed(2);
|
||||
});
|
||||
|
||||
container.appendChild(label);
|
||||
container.appendChild(slider);
|
||||
container.appendChild(valueDisplay);
|
||||
toolbar.appendChild(container);
|
||||
|
||||
return slider;
|
||||
}
|
||||
|
||||
function createUi() {
|
||||
const toolbar = document.getElementById("toolbar");
|
||||
|
||||
toolbar.style.cssText = `
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
padding: 15px 20px 5px 20px;
|
||||
background: rgba(40, 40, 40, 0.85);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
backdrop-filter: blur(5px);
|
||||
z-index: 1000;
|
||||
`;
|
||||
|
||||
createSlider(toolbar, {
|
||||
labelText: "opacity",
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
defaultValue: uniforms.opacity,
|
||||
callback: (val) => {
|
||||
uniforms.opacity = parseFloat(val);
|
||||
},
|
||||
});
|
||||
|
||||
createSlider(toolbar, {
|
||||
labelText: "range",
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
defaultValue: uniforms.range,
|
||||
callback: (val) => {
|
||||
uniforms.range = parseFloat(val);
|
||||
},
|
||||
});
|
||||
createSlider(toolbar, {
|
||||
labelText: "steps",
|
||||
min: 20,
|
||||
max: 200,
|
||||
step: 1,
|
||||
defaultValue: uniforms.steps,
|
||||
callback: (val) => {
|
||||
uniforms.steps = parseFloat(val);
|
||||
},
|
||||
});
|
||||
createSlider(toolbar, {
|
||||
labelText: "threshold",
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
defaultValue: uniforms.threshold,
|
||||
callback: (val) => {
|
||||
uniforms.threshold = parseFloat(val);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
createUi();
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
legacyId: development/VolumeCloud.html
|
||||
title: VolumeCloud - Dev
|
||||
description: Rendering Volume Cloud with Texture3D and Custom GLSL. Transplanted from Three.js
|
||||
labels:
|
||||
- Development
|
||||
thumbnail: thumbnail.jpg
|
||||
development: true
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 93 KiB |
|
|
@ -281,14 +281,14 @@ const vertexShader = /* glsl */ `
|
|||
void main()
|
||||
{
|
||||
vec4 p = translateRelativeToEye(position3DHigh, position3DLow);
|
||||
|
||||
|
||||
vOrigin = czm_encodedCameraPositionMCHigh + czm_encodedCameraPositionMCLow;
|
||||
|
||||
vec3 modelPosition = position3DHigh + position3DLow;
|
||||
vPosition = modelPosition;
|
||||
|
||||
vDirection = modelPosition - vOrigin;
|
||||
|
||||
|
||||
gl_Position = czm_modelViewProjectionRelativeToEye * p;
|
||||
}`;
|
||||
|
||||
|
|
@ -525,7 +525,6 @@ function createSlider(
|
|||
slider.style.cssText = `
|
||||
width: 100px;
|
||||
cursor: pointer;
|
||||
accent-color: #4CAF50;
|
||||
`;
|
||||
slider.addEventListener("input", (e) => callback(e.target.value));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@cesium/sandcastle",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"scripts/buildGallery.js"
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-stay-scrolled": "^9.0.0",
|
||||
"react-use": "^17.6.0",
|
||||
"react-use": "^17.6.0",
|
||||
"yargs": "^18.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -44,6 +44,16 @@
|
|||
input[type="radio"] {
|
||||
margin: revert-layer;
|
||||
}
|
||||
|
||||
.cesium-viewer {
|
||||
/* Cesium defines it's own styles for all elements in the viewer and those
|
||||
* styles don't expect a reset. Remove from everything in that section of the page */
|
||||
*,
|
||||
:before,
|
||||
:after {
|
||||
all: revert-layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -51,7 +61,7 @@
|
|||
* The values for these styles were extracted from the matching stratakit components
|
||||
*/
|
||||
|
||||
select:not(.stratakit-mimic-button) {
|
||||
select:not(.stratakit-mimic-button):not(.cesium-viewer select) {
|
||||
background: var(--stratakit-color-bg-neutral-base);
|
||||
padding: var(--stratakit-space-x1);
|
||||
border-radius: var(--stratakit-ext-radius-sm);
|
||||
|
|
@ -75,7 +85,7 @@ select:not(.stratakit-mimic-button) {
|
|||
}
|
||||
}
|
||||
|
||||
button:not(.stratakit-mimic-button) {
|
||||
button:not(.stratakit-mimic-button):not(.cesium-viewer button) {
|
||||
/* Missing shadows and pressed, active and disabled states but "good enough" for now */
|
||||
background: var(--stratakit-color-bg-neutral-base);
|
||||
padding: var(--stratakit-space-x1) var(--stratakit-space-x3);
|
||||
|
|
@ -101,8 +111,8 @@ button:not(.stratakit-mimic-button) {
|
|||
}
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="number"] {
|
||||
input[type="text"]:not(.cesium-viewer input),
|
||||
input[type="number"]:not(.cesium-viewer input) {
|
||||
background: var(--stratakit-color-bg-page-base);
|
||||
border-radius: var(--stratakit-ext-radius-sm);
|
||||
border: var(--stratakit-ext-border-border) solid;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@cesium/widgets",
|
||||
"version": "13.1.0",
|
||||
"version": "13.1.1",
|
||||
"description": "A widgets library for use with CesiumJS. CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.",
|
||||
"keywords": [
|
||||
"3D",
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
"node": ">=20.19.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cesium/engine": "^20.0.0",
|
||||
"@cesium/engine": "^20.0.1",
|
||||
"nosleep.js": "^0.12.0"
|
||||
},
|
||||
"type": "module",
|
||||
|
|
|
|||
Loading…
Reference in New Issue