diff --git a/js/MobiusQueryParameters.ts b/js/MobiusQueryParameters.ts index ea93293..ce5746c 100644 --- a/js/MobiusQueryParameters.ts +++ b/js/MobiusQueryParameters.ts @@ -22,6 +22,37 @@ const MobiusQueryParameters = QueryStringMachine.getAll( { mobiusCanvasSkipGamma: { type: 'boolean', defaultValue: true + }, + + /** + * Controls whether the preserveDrawingBuffer:true is set on WebGL Canvases. This allows canvas.toDataURL() to work + * (used for certain methods that require screenshot generation using foreign object rasterization, etc.). + * Generally reduces WebGL performance, so it should not always be on (thus the query parameter). + */ + threeRendererPreserveDrawingBuffer: { type: 'flag' }, + + /** + * Sets device pixel ratio. This is usually used for HiDPI device to prevent blurring output canvas. When setting the + * renderer pixel ratio to window.devicePixelRatio, it will have the highest resolution for that device. Setting + * anything lower will be more blurry, but will save vRAM. Note that we observed window.devicePixelRatio to be 2 + * on Mac/chrome, 2 on iPad 7, and 3 on iPhone 15 Pro Max. + * + * Added as part of https://github.com/phetsims/density-buoyancy-common/issues/316 + */ + threeRendererPixelRatio: { + type: 'number', + defaultValue: window.devicePixelRatio || 1 + }, + + /** + * Antialiasing makes diagonal lines look smoother, but uses more vRAM. Set to false to turn off antialiasing for + * THREE.js renderer. + * + * Added as part of https://github.com/phetsims/density-buoyancy-common/issues/316 + */ + threeRendererAntialias: { + type: 'boolean', + defaultValue: true } } ); diff --git a/js/ThreeIsometricNode.ts b/js/ThreeIsometricNode.ts index 4a38494..f458811 100644 --- a/js/ThreeIsometricNode.ts +++ b/js/ThreeIsometricNode.ts @@ -31,6 +31,7 @@ type SelfOptions = { viewOffset?: Vector2; }; +// Constructor options are passed directly to ThreeStage as well as used by this Node. export type ThreeIsometricNodeOptions = SelfOptions & ThreeStageOptions & NodeOptions; export default class ThreeIsometricNode extends Node { diff --git a/js/ThreeStage.ts b/js/ThreeStage.ts index 4736d52..7d6489b 100644 --- a/js/ThreeStage.ts +++ b/js/ThreeStage.ts @@ -30,6 +30,8 @@ export type ThreeStageOptions = { // The initial camera position cameraPosition?: Vector3; + threeRendererOptions?: THREE.WebGLRendererParameters; + threeRendererPixelRatio?: number; }; export default class ThreeStage { @@ -56,7 +58,13 @@ export default class ThreeStage { const options = optionize()( { backgroundColorProperty: new Property( Color.BLACK ), - cameraPosition: new Vector3( 0, 0, 10 ) + cameraPosition: new Vector3( 0, 0, 10 ), + threeRendererOptions: { + antialias: MobiusQueryParameters.threeRendererAntialias, + alpha: true, + preserveDrawingBuffer: MobiusQueryParameters.threeRendererPreserveDrawingBuffer + }, + threeRendererPixelRatio: MobiusQueryParameters.threeRendererPixelRatio }, providedOptions ); this.activeScale = 1; @@ -73,18 +81,14 @@ export default class ThreeStage { if ( ThreeUtils.isWebGLEnabled() ) { try { - this.threeRenderer = new THREE.WebGLRenderer( { - antialias: true, - alpha: true, - preserveDrawingBuffer: phet.chipper.queryParameters.preserveDrawingBuffer - } ); + this.threeRenderer = new THREE.WebGLRenderer( options.threeRendererOptions ); } catch( e ) { // For https://github.com/phetsims/density/issues/105, we'll need to generate the full API without WebGL console.log( e ); } } - this.threeRenderer && this.threeRenderer.setPixelRatio( window.devicePixelRatio || 1 ); + this.threeRenderer && this.threeRenderer.setPixelRatio( options.threeRendererPixelRatio ); // Dialog shown on context loss, constructed lazily because Dialog requires sim bounds during construction this.contextLossDialog = null;