CesiumGS / CesiumGS/cesium

Smeared imagery on some mobile devices

Open
#2,541 12 comments 0 reactions 0 assignees View on GitHub
category - terrain and imagery type - bug
Dominant language
JavaScript
Stars
15.7k
Forks
3.9k
Avg merge
4d 6h
Merged PRs (30d)
34

Description

Originally reported here:
https://groups.google.com/d/topic/cesium-dev/ouQyJY0LiRs/discussion

The immediate cause is that the `webMercatorT` vertex attribute is receiving incorrect values in the imagery reprojection shader. The attribute is set with the following code (in `ImageryLayer`):

```
reproject.vertexArray.getAttribute(1).vertexBuffer.copyFromArrayView(webMercatorT);
```

I've confirmed that the `webMerctorT` `Float32Array` is correct. On the problematic mobile devices (HTC One M7 in my case), this line actually corrupts the attribute - values that were provided when the vertex array was originally created are actually replaced with garbage.

The best part is that this problem goes away if we don't use `OES_vertex_array_object`. Comment out `this._vertexArrayObject = getExtension(gl, ['OES_vertex_array_object']);` in `Context` and everything is fine.

I tried to demonstrate this problem with a simpler test, but apparently my test is too simple because it passed even on my M7. Here's what I tried:

```
it('can update vertex buffer', function() {
var vs = '\
attribute vec4 position;\
attribute float test;\
varying float v_test;\
void main()\
{\
v_test = test;\
gl_PointSize = 1.0;\
gl_Position = position;\
}';
var fs = '\
varying float v_test;\
void main()\
{\
gl_FragColor = vec4(v_test == 0.5);\
}';

var context = createContext();
var sp = context.createShaderProgram(vs, fs);

var va = context.createVertexArray([
{
index : sp.vertexAttributes.position.index,
vertexBuffer : context.createVertexBuffer(new Float32Array([0, 0, 0, 1, 0, 0, 0, 1]), BufferUsage.STATIC_DRAW),
componentsPerAttribute : 4
},
{
index : sp.vertexAttributes.test.index,
vertexBuffer : context.createVertexBuffer(new Float32Array([0.0, 0.0]), BufferUsage.STATIC_DRAW),
componentsPerAttribute : 1
}
]);

ClearCommand.ALL.execute(context);
expect(context.readPixels()).toEqual([0, 0, 0, 0]);

var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va
});

va.getAttribute(1).vertexBuffer.copyFromArrayView(new Float32Array([0.5, 0.5]));

command.execute(context);
expect(context.readPixels()).toEqual([255, 255, 255, 255]);

sp = sp.destroy();
va = va.destroy();
});
```

Maybe @pjcozzi or @bagnell could take a quick look at the reprojection code in `ImageryLayer` to see if I'm doing something stupid, maybe along the lines of that impossible-to-debug Firefox-on-Mac-only problem from awhile back that turned out to be my failure to explicitly specify vertex attribute indices.

If not, I guess we'll need to try harder to turn this into a test case to report it as a bug to the browser vendors. Since it happens in both Chrome and Firefox on this device, though, it's probably a GPU/driver bug and we'll need a workaround instead (such as not using VAOs on these devices).

Contributor guide

Open the contributing guide

Research direction

Start with the ImageryLayer reprojection code that updates webMercatorT and the Context setup for OES_vertex_array_object. Reproduce on the HTC One M7 with VAOs enabled, compare behavior when the extension is disabled, and use the provided vertex-buffer test as a starting point for a regression case. Done means the imagery is no longer smeared on the affected device and the behavior is covered or a documented workaround is established.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
computer-graphics, mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.