Merge branch 'main' into misaligned-glyph-fix

This commit is contained in:
Gabby Getz 2025-09-12 10:54:31 -04:00 committed by GitHub
commit aff7ef353e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 94 additions and 693 deletions

View File

@ -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!

View File

@ -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 @@
}
}
}
}
}

View File

@ -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",
});

View File

@ -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",
});

View File

@ -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",

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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>

View File

@ -421,8 +421,6 @@ function createButtons(scene) {
},
},
]);
document.getElementById("toolbar").style.width = "10%";
}
function createPrimitives(scene) {

View File

@ -6,7 +6,7 @@
<h1>Loading...</h1>
</div>
<div id="toolbar">
<table class="infoPanel">
<table>
<tbody>
<tr>
<td>

View File

@ -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>

View File

@ -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(

View File

@ -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;

View File

@ -6,7 +6,7 @@
<h1>Loading...</h1>
</div>
<div id="toolbar">
<table class="infoPanel">
<table>
<tbody>
<tr>
<td>

View File

@ -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>

View File

@ -510,8 +510,6 @@ function createButtons(scene) {
},
},
]);
document.getElementById("toolbar").style.width = "10%";
}
function createPrimitives(scene) {

View File

@ -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>

View File

@ -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();

View File

@ -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

View File

@ -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));

View File

@ -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": {

View File

@ -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;

View File

@ -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",