@@ -653,7 +653,10 @@ class RenderWebGL extends EventEmitter {
653
653
gl . clearColor ( ...this . _backgroundColor4f ) ;
654
654
gl . clear ( gl . COLOR_BUFFER_BIT ) ;
655
655
656
- this . _drawThese ( this . _drawList , ShaderManager . DRAW_MODE . default , this . _projection ) ;
656
+ this . _drawThese ( this . _drawList , ShaderManager . DRAW_MODE . default , this . _projection , {
657
+ framebufferWidth : gl . canvas . width ,
658
+ framebufferHeight : gl . canvas . height
659
+ } ) ;
657
660
if ( this . _snapshotCallbacks . length > 0 ) {
658
661
const snapshot = gl . canvas . toDataURL ( ) ;
659
662
this . _snapshotCallbacks . forEach ( cb => cb ( snapshot ) ) ;
@@ -1209,9 +1212,15 @@ class RenderWebGL extends EventEmitter {
1209
1212
1210
1213
gl . clearColor ( 0 , 0 , 0 , 0 ) ;
1211
1214
gl . clear ( gl . COLOR_BUFFER_BIT ) ;
1212
- // Don't apply the ghost effect. TODO: is this an intentional design decision?
1213
1215
this . _drawThese ( [ drawableID ] , ShaderManager . DRAW_MODE . straightAlpha , projection ,
1214
- { effectMask : ~ ShaderManager . EFFECT_INFO . ghost . mask } ) ;
1216
+ {
1217
+ // Don't apply the ghost effect. TODO: is this an intentional design decision?
1218
+ effectMask : ~ ShaderManager . EFFECT_INFO . ghost . mask ,
1219
+ // We're doing this in screen-space, so the framebuffer dimensions should be those of the canvas in
1220
+ // screen-space. This is used to ensure SVG skins are rendered at the proper resolution.
1221
+ framebufferWidth : canvas . width ,
1222
+ framebufferHeight : canvas . height
1223
+ } ) ;
1215
1224
1216
1225
const data = new Uint8Array ( Math . floor ( clampedWidth * clampedHeight * 4 ) ) ;
1217
1226
gl . readPixels ( 0 , 0 , clampedWidth , clampedHeight , gl . RGBA , gl . UNSIGNED_BYTE , data ) ;
@@ -1713,18 +1722,6 @@ class RenderWebGL extends EventEmitter {
1713
1722
this . _regionId = null ;
1714
1723
}
1715
1724
1716
- /**
1717
- * Get the screen-space scale of a drawable, as percentages of the drawable's "normal" size.
1718
- * @param {Drawable } drawable The drawable whose screen-space scale we're fetching.
1719
- * @returns {Array<number> } The screen-space X and Y dimensions of the drawable's scale, as percentages.
1720
- */
1721
- _getDrawableScreenSpaceScale ( drawable ) {
1722
- return [
1723
- drawable . scale [ 0 ] * this . _gl . canvas . width / this . _nativeSize [ 0 ] ,
1724
- drawable . scale [ 1 ] * this . _gl . canvas . height / this . _nativeSize [ 1 ]
1725
- ] ;
1726
- }
1727
-
1728
1725
/**
1729
1726
* Draw a set of Drawables, by drawable ID
1730
1727
* @param {Array<int> } drawables The Drawable IDs to draw, possibly this._drawList.
@@ -1735,13 +1732,20 @@ class RenderWebGL extends EventEmitter {
1735
1732
* @param {object.<string,*> } opts.extraUniforms Extra uniforms for the shaders.
1736
1733
* @param {int } opts.effectMask Bitmask for effects to allow
1737
1734
* @param {boolean } opts.ignoreVisibility Draw all, despite visibility (e.g. stamping, touching color)
1735
+ * @param {int } opts.framebufferWidth The width of the framebuffer being drawn onto. Defaults to "native" width
1736
+ * @param {int } opts.framebufferHeight The height of the framebuffer being drawn onto. Defaults to "native" height
1738
1737
* @private
1739
1738
*/
1740
1739
_drawThese ( drawables , drawMode , projection , opts = { } ) {
1741
1740
1742
1741
const gl = this . _gl ;
1743
1742
let currentShader = null ;
1744
1743
1744
+ const framebufferSpaceScaleDiffers = (
1745
+ 'framebufferWidth' in opts && 'framebufferHeight' in opts &&
1746
+ opts . framebufferWidth !== this . _nativeSize [ 0 ] && opts . framebufferHeight !== this . _nativeSize [ 1 ]
1747
+ ) ;
1748
+
1745
1749
const numDrawables = drawables . length ;
1746
1750
for ( let drawableIndex = 0 ; drawableIndex < numDrawables ; ++ drawableIndex ) {
1747
1751
const drawableID = drawables [ drawableIndex ] ;
@@ -1756,8 +1760,13 @@ class RenderWebGL extends EventEmitter {
1756
1760
// the ignoreVisibility flag is used (e.g. for stamping or touchingColor).
1757
1761
if ( ! drawable . getVisible ( ) && ! opts . ignoreVisibility ) continue ;
1758
1762
1759
- // Combine drawable scale with the native vs. backing pixel ratio
1760
- const drawableScale = this . _getDrawableScreenSpaceScale ( drawable ) ;
1763
+ // drawableScale is the "framebuffer-pixel-space" scale of the drawable, as percentages of the drawable's
1764
+ // "native size" (so 100 = same as skin's "native size", 200 = twice "native size").
1765
+ // If the framebuffer dimensions are the same as the stage's "native" size, there's no need to calculate it.
1766
+ const drawableScale = framebufferSpaceScaleDiffers ? [
1767
+ drawable . scale [ 0 ] * opts . framebufferWidth / this . _nativeSize [ 0 ] ,
1768
+ drawable . scale [ 1 ] * opts . framebufferHeight / this . _nativeSize [ 1 ]
1769
+ ] : drawable . scale ;
1761
1770
1762
1771
// If the skin or texture isn't ready yet, skip it.
1763
1772
if ( ! drawable . skin || ! drawable . skin . getTexture ( drawableScale ) ) continue ;
0 commit comments