Skip to content

Commit

Permalink
fix: optimize frame rate calculation and shader performance
Browse files Browse the repository at this point in the history
- Remove redundant interval uniform from shader
- Calculate interval directly in shader to reduce data transfer
- Only update frame rate when FPS > 50 to avoid performance degradation
- Replace requestAnimationFrame with setInterval for stable frame rate updates
  • Loading branch information
hongfaqiu committed Nov 1, 2024
1 parent e0fffb9 commit 7486fb6
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 33 deletions.
7 changes: 7 additions & 0 deletions example/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# example

## 0.4.5

### Patch Changes

- Updated dependencies
- [email protected]

## 0.4.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "example",
"private": true,
"version": "0.4.4",
"version": "0.4.5",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
11 changes: 11 additions & 0 deletions packages/cesium-wind-layer/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# cesium-wind-layer

## 0.7.4

### Patch Changes

- fix: optimize frame rate calculation and shader performance

- Remove redundant interval uniform from shader
- Calculate interval directly in shader to reduce data transfer
- Only update frame rate when FPS > 50 to avoid performance degradation
- Replace requestAnimationFrame with setInterval for stable frame rate updates

## 0.7.3

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/cesium-wind-layer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cesium-wind-layer",
"version": "0.7.3",
"version": "0.7.4",
"publishConfig": {
"access": "public"
},
Expand Down
9 changes: 8 additions & 1 deletion packages/cesium-wind-layer/src/shaders/calculateSpeed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@ uniform vec2 speedRange; // (min, max)
uniform vec2 dimension; // (lon, lat)
uniform vec2 minimum; // minimum of each dimension
uniform vec2 maximum; // maximum of each dimension
uniform vec2 interval; // interval of each dimension
uniform float speedScaleFactor;
in vec2 v_textureCoordinates;
vec2 getInterval(vec2 maximum, vec2 minimum, vec2 dimension) {
return (maximum - minimum) / (dimension - 1.0);
}
vec2 mapPositionToNormalizedIndex2D(vec2 lonLat) {
// ensure the range of longitude and latitude
lonLat.x = clamp(lonLat.x, minimum.x, maximum.x);
lonLat.y = clamp(lonLat.y, minimum.y, maximum.y);
vec2 interval = getInterval(maximum, minimum, dimension);
vec2 index2D = vec2(0.0);
index2D.x = (lonLat.x - minimum.x) / interval.x;
index2D.y = (lonLat.y - minimum.y) / interval.y;
Expand All @@ -47,6 +52,8 @@ vec2 bilinearInterpolation(vec2 lonLat) {
float lon = lonLat.x;
float lat = lonLat.y;
vec2 interval = getInterval(maximum, minimum, dimension);
// Calculate grid cell coordinates
float lon0 = floor(lon / interval.x) * interval.x;
float lon1 = lon0 + interval.x;
Expand Down
49 changes: 19 additions & 30 deletions packages/cesium-wind-layer/src/windParticlesComputing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export class WindParticlesComputing {
updatePosition: CustomPrimitive;
postProcessingPosition: CustomPrimitive;
};
private bounds: WindData['bounds'];
windData: Required<WindData>;
private frameRateMonitor: FrameRateMonitor;
private frameRate: number = 60;
Expand All @@ -34,7 +33,6 @@ export class WindParticlesComputing {
this.context = context;
this.options = options;
this.viewerParameters = viewerParameters;
this.bounds = windData.bounds;
this.windData = windData;

this.frameRateMonitor = new FrameRateMonitor({
Expand All @@ -49,27 +47,20 @@ export class WindParticlesComputing {
}

private initFrameRate() {
let lastUpdate = performance.now();
const updateInterval = 1000; // Update every 1000ms (1 second)

const updateFrameRate = () => {
const currentTime = performance.now();
const deltaTime = currentTime - lastUpdate;

// Only update frame rate once per second
if (deltaTime >= updateInterval) {
if (this.frameRateMonitor.lastFramesPerSecond) {
this.frameRate = this.frameRateMonitor.lastFramesPerSecond;
this.frameRateAdjustment = 60 / Math.max(this.frameRate, 1);
}
lastUpdate = currentTime;
// avoid update frame rate when frame rate is too low
if (this.frameRateMonitor.lastFramesPerSecond > 50) {
this.frameRate = this.frameRateMonitor.lastFramesPerSecond;
this.frameRateAdjustment = 60 / Math.max(this.frameRate, 1);
}
}

requestAnimationFrame(updateFrameRate);
};

// Initial frame rate calculation
updateFrameRate();

// Use setInterval instead of requestAnimationFrame
const intervalId = setInterval(updateFrameRate, 1000);

// Monitor frame rate changes
this.frameRateMonitor.lowFrameRate.addEventListener((scene, frameRate) => {
console.warn(`Low frame rate detected: ${frameRate} FPS`);
Expand All @@ -78,6 +69,13 @@ export class WindParticlesComputing {
this.frameRateMonitor.nominalFrameRate.addEventListener((scene, frameRate) => {
console.log(`Frame rate returned to normal: ${frameRate} FPS`);
});

// Add cleanup method to destroy
const originalDestroy = this.destroy.bind(this);
this.destroy = () => {
clearInterval(intervalId);
originalDestroy();
};
}

createWindTextures() {
Expand Down Expand Up @@ -141,14 +139,6 @@ export class WindParticlesComputing {
}

createComputingPrimitives() {
const dimension = new Cartesian2(this.windData.width, this.windData.height);
const minimum = new Cartesian2(this.bounds.west, this.bounds.south);
const maximum = new Cartesian2(this.bounds.east, this.bounds.north);
const interval = new Cartesian2(
(maximum.x - minimum.x) / (dimension.x - 1),
(maximum.y - minimum.y) / (dimension.y - 1)
);

this.primitives = {
calculateSpeed: new CustomPrimitive({
commandType: 'Compute',
Expand All @@ -162,10 +152,9 @@ export class WindParticlesComputing {
speedScaleFactor: () => {
return (this.viewerParameters.pixelSize + 50) * this.options.speedFactor * this.frameRateAdjustment;
},
dimension: () => dimension,
minimum: () => minimum,
maximum: () => maximum,
interval: () => interval,
dimension: () => new Cartesian2(this.windData.width, this.windData.height),
minimum: () => new Cartesian2(this.windData.bounds.west, this.windData.bounds.south),
maximum: () => new Cartesian2(this.windData.bounds.east, this.windData.bounds.north),
},
fragmentShaderSource: ShaderManager.getCalculateSpeedShader(),
outputTexture: this.particlesTextures.particlesSpeed,
Expand Down

0 comments on commit 7486fb6

Please sign in to comment.