Skip to content

Commit 46274c7

Browse files
authored
Merge pull request #649 from adroitwhiz/no-vector-blur
Always use SVG mipmaps that match or exceed the skins' screen-space size
2 parents 8074814 + 0d86ec9 commit 46274c7

File tree

1 file changed

+11
-17
lines changed

1 file changed

+11
-17
lines changed

src/SVGSkin.js

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const Skin = require('./Skin');
44
const SvgRenderer = require('scratch-svg-renderer').SVGRenderer;
55

66
const MAX_TEXTURE_DIMENSION = 2048;
7-
const MIN_TEXTURE_SCALE = 1 / 256;
7+
88
/**
99
* All scaled renderings of the SVG are stored in an array. The 1.0 scale of
1010
* the SVG is stored at the 8th index. The smallest possible 1 / 256 scale
@@ -108,26 +108,20 @@ class SVGSkin extends Skin {
108108
// The texture only ever gets uniform scale. Take the larger of the two axes.
109109
const scaleMax = scale ? Math.max(Math.abs(scale[0]), Math.abs(scale[1])) : 100;
110110
const requestedScale = Math.min(scaleMax / 100, this._maxTextureScale);
111-
let newScale = 1;
112-
let textureIndex = 0;
113111

114-
if (requestedScale < 1) {
115-
while ((newScale > MIN_TEXTURE_SCALE) && (requestedScale <= newScale * .75)) {
116-
newScale /= 2;
117-
textureIndex -= 1;
118-
}
119-
} else {
120-
while ((newScale < this._maxTextureScale) && (requestedScale >= 1.5 * newScale)) {
121-
newScale *= 2;
122-
textureIndex += 1;
123-
}
124-
}
112+
// Math.ceil(Math.log2(scale)) means we use the "1x" texture at (0.5, 1] scale,
113+
// the "2x" texture at (1, 2] scale, the "4x" texture at (2, 4] scale, etc.
114+
// This means that one texture pixel will always be between 0.5x and 1x the size of one rendered pixel,
115+
// but never bigger than one rendered pixel--this prevents blurriness from blowing up the texture too much.
116+
const mipLevel = Math.max(Math.ceil(Math.log2(requestedScale)) + INDEX_OFFSET, 0);
117+
// Can't use bitwise stuff here because we need to handle negative exponents
118+
const mipScale = Math.pow(2, mipLevel - INDEX_OFFSET);
125119

126-
if (this._svgRenderer.loaded && !this._scaledMIPs[textureIndex + INDEX_OFFSET]) {
127-
this._scaledMIPs[textureIndex + INDEX_OFFSET] = this.createMIP(newScale);
120+
if (this._svgRenderer.loaded && !this._scaledMIPs[mipLevel]) {
121+
this._scaledMIPs[mipLevel] = this.createMIP(mipScale);
128122
}
129123

130-
return this._scaledMIPs[textureIndex + INDEX_OFFSET] || super.getTexture();
124+
return this._scaledMIPs[mipLevel] || super.getTexture();
131125
}
132126

133127
/**

0 commit comments

Comments
 (0)