WebGL / Support DPR > 1 in linestring shader
A u_pixelRatio uniform was added to be used in the shaders. this is necessary since we're relying on the builtin gl_FragCoord vector, which will be scaled relative to the u_sizePx uniform in case of a device pixel ratio != 1. Also added tests for computed uniform values, instead of just testing that they were indeed set.
This commit is contained in:
@@ -100,6 +100,7 @@ class WebGLLayer extends Layer {
|
|||||||
}`,
|
}`,
|
||||||
lineStringFragmentShader: `
|
lineStringFragmentShader: `
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
uniform float u_pixelRatio;
|
||||||
varying vec2 v_segmentStart;
|
varying vec2 v_segmentStart;
|
||||||
varying vec2 v_segmentEnd;
|
varying vec2 v_segmentEnd;
|
||||||
varying float v_angleStart;
|
varying float v_angleStart;
|
||||||
@@ -118,8 +119,9 @@ class WebGLLayer extends Layer {
|
|||||||
float lineWidth = 1.5;
|
float lineWidth = 1.5;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
vec2 v_currentPoint = gl_FragCoord.xy / u_pixelRatio;
|
||||||
gl_FragColor = vec4(v_color.rgb * 0.75, 1.0);
|
gl_FragColor = vec4(v_color.rgb * 0.75, 1.0);
|
||||||
gl_FragColor *= segmentDistanceField(gl_FragCoord.xy, v_segmentStart, v_segmentEnd, lineWidth);
|
gl_FragColor *= segmentDistanceField(v_currentPoint, v_segmentStart, v_segmentEnd, lineWidth);
|
||||||
}`,
|
}`,
|
||||||
pointVertexShader: `
|
pointVertexShader: `
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export const DefaultUniform = {
|
|||||||
ZOOM: 'u_zoom',
|
ZOOM: 'u_zoom',
|
||||||
RESOLUTION: 'u_resolution',
|
RESOLUTION: 'u_resolution',
|
||||||
SIZE_PX: 'u_sizePx',
|
SIZE_PX: 'u_sizePx',
|
||||||
|
PIXEL_RATIO: 'u_pixelRatio',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -666,6 +667,7 @@ class WebGLHelper extends Disposable {
|
|||||||
applyFrameState(frameState) {
|
applyFrameState(frameState) {
|
||||||
const size = frameState.size;
|
const size = frameState.size;
|
||||||
const rotation = frameState.viewState.rotation;
|
const rotation = frameState.viewState.rotation;
|
||||||
|
const pixelRatio = frameState.pixelRatio;
|
||||||
|
|
||||||
const offsetScaleMatrix = resetTransform(this.offsetScaleMatrix_);
|
const offsetScaleMatrix = resetTransform(this.offsetScaleMatrix_);
|
||||||
scaleTransform(offsetScaleMatrix, 2 / size[0], 2 / size[1]);
|
scaleTransform(offsetScaleMatrix, 2 / size[0], 2 / size[1]);
|
||||||
@@ -693,6 +695,7 @@ class WebGLHelper extends Disposable {
|
|||||||
DefaultUniform.RESOLUTION,
|
DefaultUniform.RESOLUTION,
|
||||||
frameState.viewState.resolution
|
frameState.viewState.resolution
|
||||||
);
|
);
|
||||||
|
this.setUniformFloatValue(DefaultUniform.PIXEL_RATIO, pixelRatio);
|
||||||
this.setUniformFloatVec2(DefaultUniform.SIZE_PX, [size[0], size[1]]);
|
this.setUniformFloatVec2(DefaultUniform.SIZE_PX, [size[0], size[1]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ const SAMPLE_FRAMESTATE = {
|
|||||||
rotation: 0.4,
|
rotation: 0.4,
|
||||||
resolution: 2,
|
resolution: 2,
|
||||||
center: [10, 20],
|
center: [10, 20],
|
||||||
|
zoom: 3,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -154,6 +155,16 @@ describe('ol/webgl/WebGLHelper', function () {
|
|||||||
h.uniformLocations_[DefaultUniform.OFFSET_SCALE_MATRIX]
|
h.uniformLocations_[DefaultUniform.OFFSET_SCALE_MATRIX]
|
||||||
).not.to.eql(undefined);
|
).not.to.eql(undefined);
|
||||||
expect(h.uniformLocations_[DefaultUniform.TIME]).not.to.eql(undefined);
|
expect(h.uniformLocations_[DefaultUniform.TIME]).not.to.eql(undefined);
|
||||||
|
expect(h.uniformLocations_[DefaultUniform.ZOOM]).not.to.eql(undefined);
|
||||||
|
expect(h.uniformLocations_[DefaultUniform.RESOLUTION]).not.to.eql(
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
expect(h.uniformLocations_[DefaultUniform.SIZE_PX]).not.to.eql(
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
expect(h.uniformLocations_[DefaultUniform.PIXEL_RATIO]).not.to.eql(
|
||||||
|
undefined
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has processed uniforms', function () {
|
it('has processed uniforms', function () {
|
||||||
@@ -413,4 +424,50 @@ describe('ol/webgl/WebGLHelper', function () {
|
|||||||
expect(spy.getCall(2).args[4]).to.eql(5 * bytesPerFloat);
|
expect(spy.getCall(2).args[4]).to.eql(5 * bytesPerFloat);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#applyFrameState', function () {
|
||||||
|
let stubMatrix, stubFloat, stubVec2, stubTime;
|
||||||
|
beforeEach(function () {
|
||||||
|
stubTime = sinon.stub(Date, 'now');
|
||||||
|
stubTime.returns(1000);
|
||||||
|
h = new WebGLHelper();
|
||||||
|
stubMatrix = sinon.stub(h, 'setUniformMatrixValue');
|
||||||
|
stubFloat = sinon.stub(h, 'setUniformFloatValue');
|
||||||
|
stubVec2 = sinon.stub(h, 'setUniformFloatVec2');
|
||||||
|
|
||||||
|
stubTime.returns(2000);
|
||||||
|
h.applyFrameState({...SAMPLE_FRAMESTATE, pixelRatio: 2});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
stubTime.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets the default uniforms according the frame state', function () {
|
||||||
|
expect(stubMatrix.getCall(0).args).to.eql([
|
||||||
|
DefaultUniform.OFFSET_SCALE_MATRIX,
|
||||||
|
[
|
||||||
|
0.9210609940028851, -0.3894183423086505, 0, 0, 0.3894183423086505,
|
||||||
|
0.9210609940028851, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
expect(stubMatrix.getCall(1).args).to.eql([
|
||||||
|
DefaultUniform.OFFSET_ROTATION_MATRIX,
|
||||||
|
[
|
||||||
|
0.9210609940028851, -0.3894183423086505, 0, 0, 0.3894183423086505,
|
||||||
|
0.9210609940028851, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(stubFloat.getCall(0).args).to.eql([DefaultUniform.TIME, 1]);
|
||||||
|
expect(stubFloat.getCall(1).args).to.eql([DefaultUniform.ZOOM, 3]);
|
||||||
|
expect(stubFloat.getCall(2).args).to.eql([DefaultUniform.RESOLUTION, 2]);
|
||||||
|
expect(stubFloat.getCall(3).args).to.eql([DefaultUniform.PIXEL_RATIO, 2]);
|
||||||
|
|
||||||
|
expect(stubVec2.getCall(0).args).to.eql([
|
||||||
|
DefaultUniform.SIZE_PX,
|
||||||
|
[100, 150],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user