Flickering

I am experiencing a flickering issue when trying to update modelMatrix and positions. I have seen the posts about using the callback and have it implemented. The flickering goes away when I speed up playback to around 50x.

When I put my code in the orientation Sandcastle example things work as expected. To use the example, click the View Aircraft toolbar.

Any ideas?

Thanks in advance.

var viewer = new Cesium.Viewer('cesiumContainer', {
    terrainProviderViewModels : , //Disable terrain changing
    infoBox : false, //Disable InfoBox widget
    selectionIndicator : false //Disable selection indicator
});

//Enable lighting based on sun/moon positions
viewer.scene.globe.enableLighting = true;

//Use STK World Terrain
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
    url : '//cesiumjs.org/stk-terrain/world',
    requestWaterMask : true,
    requestVertexNormals : true
});

//Enable depth testing so things behind the terrain disappear.
viewer.scene.globe.depthTestAgainstTerrain = true;

//Set the random number seed for consistent results.
Cesium.Math.setRandomNumberSeed(3);

//Set bounds of our simulation time
var start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16));
var stop = Cesium.JulianDate.addSeconds(start, 360, new Cesium.JulianDate());

//Make sure viewer is at the desired time.
viewer.clock.startTime = start.clone();
viewer.clock.stopTime = stop.clone();
viewer.clock.currentTime = start.clone();
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end
viewer.clock.multiplier = 10;

//Set timeline to simulation bounds
viewer.timeline.zoomTo(start, stop);

//Generate a random circular pattern with varying heights.
function computeCirclularFlight(lon, lat, radius) {
    var property = new Cesium.SampledPositionProperty();
    for (var i = 0; i <= 360; i += 45) {
        var radians = Cesium.Math.toRadians(i);
        var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate());
        var position = Cesium.Cartesian3.fromDegrees(lon + (radius * 1.5 * Math.cos(radians)), lat + (radius * Math.sin(radians)), Cesium.Math.nextRandomNumber() * 500 + 1750);
        property.addSample(time, position);

        //Also create a point for each sample we generate.
        viewer.entities.add({
            position : position,
            point : {
                pixelSize : 8,
                color : Cesium.Color.TRANSPARENT,
                outlineColor : Cesium.Color.YELLOW,
                outlineWidth : 3
            }
        });
    }
    return property;
}

//Compute the entity position property.
var position = computeCirclularFlight(-112.110693, 36.0994841, 0.03);

//Actually create the entity
var entity = viewer.entities.add({

    //Set the entity availability to the same interval as the simulation time.
    availability : new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
        start : start,
        stop : stop
    })]),

    //Use our computed positions
    position : position,

    //Automatically compute orientation based on position movement.
    orientation : new Cesium.VelocityOrientationProperty(position),

    //Load the Cesium plane model to represent the entity
    model : {
        uri : '../../SampleData/models/CesiumAir/Cesium_Air.gltf',
        minimumPixelSize : 64
    },

    //Show the path as a pink line sampled in 1 second increments.
    path : {
        resolution : 1,
        material : new Cesium.PolylineGlowMaterialProperty({
            glowPower : 0.1,
            color : Cesium.Color.YELLOW
        }),
        width : 1
    }
});

//Add button to view the path from the top down
Sandcastle.addDefaultToolbarButton('View Top Down', function() {
    viewer.trackedEntity = undefined;
    viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90)));
});

//Add button to view the path from the side
Sandcastle.addToolbarButton('View Side', function() {
    viewer.trackedEntity = undefined;
    viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(Cesium.Math.toRadians(-90), Cesium.Math.toRadians(-15), 7500));
});

//Add button to track the entity as it moves
Sandcastle.addToolbarButton('View Aircraft', function() {
    viewer.trackedEntity = entity;
});

////////////////////////////////////
// Code additions //
////////////////////////////////////
var refFrame = viewer.scene.primitives.add(new Cesium.DebugModelMatrixPrimitive({
        id : 'refFrame',
        length : 10,
        width : 5
    }));

var velVector = viewer.entities.add({
                name : 'Velocity Vector',
                polyline : {
                    width : 10,
                    material : new Cesium.PolylineArrowMaterialProperty(Cesium.Color.PURPLE)
                }
            });

viewer.clock.onTick.addEventListener(function() {
    refFrame.modelMatrix = Cesium.Matrix4.fromTranslationQuaternionRotationScale(
        entity.position.getValue(viewer.clock.currentTime),
        entity.orientation.getValue(viewer.clock.currentTime),
        new Cesium.Cartesian3(1, 1, 1),
        new Cesium.Matrix4()
    );
    
    var p1 = entity.position.getValue(viewer.clock.currentTime);
    var p2 = entity.position.getValue(Cesium.JulianDate.addSeconds(viewer.clock.currentTime,1,new Cesium.JulianDate()));
    velVector.polyline.positions = new Cesium.CallbackProperty(function() {
                                        return [p1,p2];
                                    }, false);
    
});

////////////////////////////////////
// End of Code additions //
////////////////////////////////////

//Add a combo box for selecting each interpolation mode.
Sandcastle.addToolbarMenu([{
    text : 'Interpolation: Linear Approximation',
    onselect : function() {
        entity.position.setInterpolationOptions({
            interpolationDegree : 1,
            interpolationAlgorithm : Cesium.LinearApproximation
        });
    }
}, {
    text : 'Interpolation: Lagrange Polynomial Approximation',
    onselect : function() {
        entity.position.setInterpolationOptions({
            interpolationDegree : 5,
            interpolationAlgorithm : Cesium.LagrangePolynomialApproximation
        });
    }
}, {
    text : 'Interpolation: Hermite Polynomial Approximation',
    onselect : function() {
        entity.position.setInterpolationOptions({
            interpolationDegree : 2,
            interpolationAlgorithm : Cesium.HermitePolynomialApproximation
        });
    }
}], 'interpolationMenu');

Also, there is no flickering when you adjust the current time by sliding the timeline.

Sorry for the delayed reply. There are two separate issues with your code.

First, you should only assign the velVector.polyline.positions property once. The nature of CallbackProperty is that you only create it once and it returns a new value every frame. By reassigning it every frame the system is doing more work than it needs to.

Second, instead of computing p1 and p2 inside of onTick, it’s better to use the time and result properties passed to the callback and compute them there. time will be the current time and result will be an existing array you can modify (the result property is optional but reduces memory churn and improves performance).

The working updated code is as follows:

var refFrame = viewer.scene.primitives.add(new Cesium.DebugModelMatrixPrimitive({

id : ‘refFrame’,

length : 10,

width : 5

}));

var velVector = viewer.entities.add({

name : ‘Velocity Vector’,

polyline : {

width : 10,

material : new Cesium.PolylineArrowMaterialProperty(Cesium.Color.PURPLE),

positions : new Cesium.CallbackProperty(function(time, result) {

result[0] = entity.position.getValue(time);

result[1] = entity.position.getValue(Cesium.JulianDate.addSeconds(time,1,new Cesium.JulianDate()));

result.length = 2;

return result;

}, false)

}

});

viewer.clock.onTick.addEventListener(function() {

refFrame.modelMatrix = Cesium.Matrix4.fromTranslationQuaternionRotationScale(

entity.position.getValue(viewer.clock.currentTime),

entity.orientation.getValue(viewer.clock.currentTime),

new Cesium.Cartesian3(1, 1, 1),

new Cesium.Matrix4()

);

});

If you have any questions, please let me know.