Skip to content

Commit

Permalink
Fix rendering images with nearest sampling and 2^n size (#11162)
Browse files Browse the repository at this point in the history
* Added render tests for image with a power of 2 size

* Added nearest resampling, test is failing

* Fix by disabling mipmaps

* Keeping same behavior with linear sampling

* Correcting expected.ping to use nearest filtering

* Adding check for useMipMap

* Refactoring

* Removing third argument from

* Fix broken refactoring

* Removing stray console.log

* Readd mipmaps

* minor refactor

* Mipmaps with nearest
  • Loading branch information
SnailBones authored Oct 27, 2021
1 parent 1cf7180 commit 309c54b
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 17 deletions.
6 changes: 3 additions & 3 deletions src/render/draw_raster.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,17 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty
const textureFilter = layer.paint.get('raster-resampling') === 'nearest' ? gl.NEAREST : gl.LINEAR;

context.activeTexture.set(gl.TEXTURE0);
tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST);
tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE);

context.activeTexture.set(gl.TEXTURE1);

if (parentTile) {
parentTile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST);
parentTile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE);
parentScaleBy = Math.pow(2, parentTile.tileID.overscaledZ - tile.tileID.overscaledZ);
parentTL = [tile.tileID.canonical.x * parentScaleBy % 1, tile.tileID.canonical.y * parentScaleBy % 1];

} else {
tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST);
tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE);
}

const uniformValues = rasterUniformValues(projMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer);
Expand Down
17 changes: 7 additions & 10 deletions src/render/texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,16 @@ class Texture {

update(image: TextureImage, options: ?{premultiply?: boolean, useMipmap?: boolean}, position?: { x: number, y: number }) {
const {width, height} = image;
const resize = (!this.size || this.size[0] !== width || this.size[1] !== height) && !position;
const {context} = this;
const {gl} = context;

this.useMipmap = Boolean(options && options.useMipmap);
gl.bindTexture(gl.TEXTURE_2D, this.texture);

context.pixelStoreUnpackFlipY.set(false);
context.pixelStoreUnpack.set(1);
context.pixelStoreUnpackPremultiplyAlpha.set(this.format === gl.RGBA && (!options || options.premultiply !== false));

if (resize) {
if (!position && (!this.size || this.size[0] !== width || this.size[1] !== height)) {
this.size = [width, height];

if (image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof HTMLVideoElement || image instanceof ImageData || (ImageBitmap && image instanceof ImageBitmap)) {
Expand All @@ -81,23 +79,22 @@ class Texture {
}
}

if (this.useMipmap && this.isSizePowerOfTwo()) {
this.useMipmap = Boolean(options && options.useMipmap && this.isSizePowerOfTwo());
if (this.useMipmap) {
gl.generateMipmap(gl.TEXTURE_2D);
}
}

bind(filter: TextureFilter, wrap: TextureWrap, minFilter: ?TextureFilter) {
bind(filter: TextureFilter, wrap: TextureWrap) {
const {context} = this;
const {gl} = context;
gl.bindTexture(gl.TEXTURE_2D, this.texture);

if (minFilter === gl.LINEAR_MIPMAP_NEAREST && !this.isSizePowerOfTwo()) {
minFilter = gl.LINEAR;
}

if (filter !== this.filter) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter || filter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
this.useMipmap ? (filter === gl.NEAREST ? gl.NEAREST_MIPMAP_NEAREST : gl.LINEAR_MIPMAP_NEAREST) : filter
);
this.filter = filter;
}

Expand Down
2 changes: 1 addition & 1 deletion src/source/raster_tile_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class RasterTileSource extends Evented implements Source {
tile.texture.update(img, {useMipmap: true});
} else {
tile.texture = new Texture(context, img, gl.RGBA, {useMipmap: true});
tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST);
tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);

if (context.extTextureFilterAnisotropic) {
gl.texParameterf(gl.TEXTURE_2D, context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, context.extTextureFilterAnisotropicMax);
Expand Down
2 changes: 1 addition & 1 deletion src/terrain/draw_terrain_raster.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ function drawTerrainRaster(painter: Painter, terrain: Terrain, sourceCache: Sour

// Bind the main draped texture
context.activeTexture.set(gl.TEXTURE0);
tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST);
tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);

const morph = vertexMorphing.getMorphValuesForProxy(coord.key);
const shaderMode = morph ? SHADER_MORPHING : SHADER_DEFAULT;
Expand Down
4 changes: 2 additions & 2 deletions src/terrain/terrain.js
Original file line number Diff line number Diff line change
Expand Up @@ -576,12 +576,12 @@ export class Terrain extends Elevation {
context.activeTexture.set(gl.TEXTURE2);
const demTexture = this._prepareDemTileUniforms(tile, demTile, uniforms) ?
(demTile.demTexture: any) : this.emptyDEMTexture;
demTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE, gl.NEAREST);
demTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE);
}

if (options && options.useDepthForOcclusion) {
context.activeTexture.set(gl.TEXTURE3);
this._depthTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE, gl.NEAREST);
this._depthTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE);
uniforms['u_depth_size_inv'] = [1 / this._depthFBO.width, 1 / this._depthFBO.height];
}

Expand Down
Binary file added test/integration/image/256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions test/integration/render-tests/image/power-of-two/style.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"version": 8,
"metadata": {
"test": {
"width": 256,
"height": 256
}
},
"center": [34.5, 54.5],
"zoom": 6,
"sources": {
"image": {
"type": "image",
"coordinates": [[34, 55], [35, 55], [35, 54], [34, 54]],
"url": "local://image/256.png"
}
},
"layers": [
{
"id": "image",
"type": "raster",
"source": "image",
"paint": {
"raster-fade-duration": 0,
"raster-resampling": "nearest"
}
}
]
}

0 comments on commit 309c54b

Please sign in to comment.