1. A concise explanation of the problem you’re experiencing.
Doarama/Ayvri uses Polylines to draw a trail along a GPS track. For one of our scenes, which takes place on the south island of New Zealand, several of the Polyline segments show a severe artifact. Here’s a screenshot to illustrate:
The Avatar is between two “vertices” of the polyline. The verts have an ‘s’ attribute that is the distance along the track. The frag shader gets an interpolated ‘s’ varying that when compared to a uniform renders the head of the trail at the same position as the avatar. When the player is paused, that ‘s’ varying should be constant regardless of the camera orientation. However we see that as you rotate the camera that interpolated ‘s’ value changes quite drastically.
2. A minimal code example. If you’ve found a bug, this helps us reproduce and repair it.
I’ve made a sandcastle with what I believe is the simplest way to illustrate the problem:
var viewer = new Cesium.Viewer(‘cesiumContainer’);
var scene = viewer.scene;
scene.primitives.add(new MyPrimitive());
function MyPrimitive() {
this.drawCommand = undefined;
}
viewer.camera.direction = new Cesium.Cartesian3(-0.06591410604895044, 0.7639222932135962, 0.6419330654788303);
viewer.camera.position = new Cesium.Cartesian3(-4603058.000871598, 625436.1800700076, -4356832.714301822);
viewer.camera.right = new Cesium.Cartesian3(-0.6173673309847033, -0.5366348950050431, 0.5752221901976228);
viewer.camera.up = new Cesium.Cartesian3(-0.783908737836613, 0.3583932468590986, -0.5069924766199216);
MyPrimitive.prototype.update = function(frameState) {
if (Cesium.defined(this.drawCommand)) {
var passes = frameState.passes;
if (passes.render) {
frameState.commandList.push(this.drawCommand);
}
}
var context = frameState.context;
var vertexBuffer = Cesium.Buffer.createVertexBuffer({
context: context,
typedArray:new Float32Array([-4603807.848438633, 632734.7529515522, -4354387.611030213, -4602842.925324642, 623848.9285398922, -4356570.90385363]),
usage: Cesium.BufferUsage.STATIC_DRAW
});
var indexBuffer = Cesium.Buffer.createIndexBuffer({
context: context,
typedArray: new Uint16Array([0,1]),
usage: Cesium.BufferUsage.STATIC_DRAW,
indexDatatype: Cesium.IndexDatatype.UNSIGNED_SHORT
});
var attributes = [{
index: 0,
enabled: true,
vertexBuffer: vertexBuffer,
componentsPerAttribute: 3,
componentDatatype : Cesium.ComponentDatatype.FLOAT,
normalize: false,
offsetInBytes: 0,
strideInBytes: 0
}];
var vs = “attribute vec3 position; \n” +
“void main() { \n” +
" gl_Position = czm_modelViewProjection * vec4(position, 1.0); \n" +
“} \n”;
var fs = “void main() { \n” +
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n" +
“} \n”;
var shaderProgram = Cesium.ShaderProgram.fromCache({
context: context,
vertexShaderSource: vs,
fragmentShaderSource: fs
});
var vertexArray = new Cesium.VertexArray({
context : context,
attributes : attributes,
indexBuffer : indexBuffer
});
var renderState = Cesium.RenderState.fromCache({
cull: {
enabled: true,
face: Cesium.CullFace.FRONT
},
depthTest: {
enabled: false
},
depthMask: true,
blending: undefined
});
var drawCommand = new Cesium.DrawCommand({
vertexArray : vertexArray,
shaderProgram : shaderProgram,
modelMatrix : Cesium.Matrix4.IDENTITY,
cull : false,
primitiveType : Cesium.PrimitiveType.LINES,
pass : Cesium.Pass.OPAQUE,
renderState : renderState,
});
this.drawCommand = drawCommand;
};
``
That example uses a custom primitive to render a LINES primitive, but it exhibits the same problem as the Polyline. If you run that you can zoom the camera in and out and watch the near side of the line disappear. It doesn’t appear to be clipping the near plane. Messing with the near plane changes how much of the line stays visible, in a way that makes it seem like depth precision is the culprit here.
3. Context. Why do you need to do this? We might know a better way to accomplish your goal.
This is key to our project. I’m writing a custom Primitive for our trail rendering, but it exhibits the same issue. I’d just like to understand what’s going on here so I can perhaps work around it in the shader.
4. The Cesium version you’re using, your operating system and browser.
Artifact is visible in Sandcastle on macOS 10.13.3 using Chrome 67