constructor( backend, parameters = {} ) {

		/**
		 * This flag can be used for type testing.
		 *
		 * @type {boolean}
		 * @readonly
		 * @default true
		 */
		this.isRenderer = true;

		//

		const {
			logarithmicDepthBuffer = false,
			alpha = true,
			depth = true,
			stencil = false,
			antialias = false,
			samples = 0,
			getFallback = null,
			colorBufferType = HalfFloatType,
			multiview = false
		} = parameters;

		/**
		 * A reference to the canvas element the renderer is drawing to.
		 * This value of this property will automatically be created by
		 * the renderer.
		 *
		 * @type {HTMLCanvasElement|OffscreenCanvas}
		 */
		this.domElement = backend.getDomElement();

		/**
		 * A reference to the current backend.
		 *
		 * @type {Backend}
		 */
		this.backend = backend;

		/**
		 * The number of MSAA samples.
		 *
		 * @type {number}
		 * @default 0
		 */
		this.samples = samples || ( antialias === true ) ? 4 : 0;

		/**
		 * Whether the renderer should automatically clear the current rendering target
		 * before execute a `render()` call. The target can be the canvas (default framebuffer)
		 * or the current bound render target (custom framebuffer).
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.autoClear = true;

		/**
		 * When `autoClear` is set to `true`, this property defines whether the renderer
		 * should clear the color buffer.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.autoClearColor = true;

		/**
		 * When `autoClear` is set to `true`, this property defines whether the renderer
		 * should clear the depth buffer.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.autoClearDepth = true;

		/**
		 * When `autoClear` is set to `true`, this property defines whether the renderer
		 * should clear the stencil buffer.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.autoClearStencil = true;

		/**
		 * Whether the default framebuffer should be transparent or opaque.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.alpha = alpha;

		/**
		 * Whether logarithmic depth buffer is enabled or not.
		 *
		 * @type {boolean}
		 * @default false
		 */
		this.logarithmicDepthBuffer = logarithmicDepthBuffer;

		/**
		 * Defines the output color space of the renderer.
		 *
		 * @type {string}
		 * @default SRGBColorSpace
		 */
		this.outputColorSpace = SRGBColorSpace;

		/**
		 * Defines the tone mapping of the renderer.
		 *
		 * @type {number}
		 * @default NoToneMapping
		 */
		this.toneMapping = NoToneMapping;

		/**
		 * Defines the tone mapping exposure.
		 *
		 * @type {number}
		 * @default 1
		 */
		this.toneMappingExposure = 1.0;

		/**
		 * Whether the renderer should sort its render lists or not.
		 *
		 * Note: Sorting is used to attempt to properly render objects that have some degree of transparency.
		 * By definition, sorting objects may not work in all cases. Depending on the needs of application,
		 * it may be necessary to turn off sorting and use other methods to deal with transparency rendering
		 * e.g. manually determining each object's rendering order.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.sortObjects = true;

		/**
		 * Whether the default framebuffer should have a depth buffer or not.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.depth = depth;

		/**
		 * Whether the default framebuffer should have a stencil buffer or not.
		 *
		 * @type {boolean}
		 * @default false
		 */
		this.stencil = stencil;

		/**
		 * Holds a series of statistical information about the GPU memory
		 * and the rendering process. Useful for debugging and monitoring.
		 *
		 * @type {Info}
		 */
		this.info = new Info();

		/**
		 * Stores override nodes for specific transformations or calculations.
		 * These nodes can be used to replace default behavior in the rendering pipeline.
		 *
		 * @type {Object}
		 * @property {?Node} modelViewMatrix - An override node for the model-view matrix.
		 * @property {?Node} modelNormalViewMatrix - An override node for the model normal view matrix.
		 */
		this.overrideNodes = {
			modelViewMatrix: null,
			modelNormalViewMatrix: null
		};

		/**
		 * The node library defines how certain library objects like materials, lights
		 * or tone mapping functions are mapped to node types. This is required since
		 * although instances of classes like `MeshBasicMaterial` or `PointLight` can
		 * be part of the scene graph, they are internally represented as nodes for
		 * further processing.
		 *
		 * @type {NodeLibrary}
		 */
		this.library = new NodeLibrary();

		/**
		 * A map-like data structure for managing lights.
		 *
		 * @type {Lighting}
		 */
		this.lighting = new Lighting();

		// internals

		/**
		 * This callback function can be used to provide a fallback backend, if the primary backend can't be targeted.
		 *
		 * @private
		 * @type {?Function}
		 */
		this._getFallback = getFallback;

		/**
		 * The renderer's pixel ratio.
		 *
		 * @private
		 * @type {number}
		 * @default 1
		 */
		this._pixelRatio = 1;

		/**
		 * The width of the renderer's default framebuffer in logical pixel unit.
		 *
		 * @private
		 * @type {number}
		 */
		this._width = this.domElement.width;

		/**
		 * The height of the renderer's default framebuffer in logical pixel unit.
		 *
		 * @private
		 * @type {number}
		 */
		this._height = this.domElement.height;

		/**
		 * The viewport of the renderer in logical pixel unit.
		 *
		 * @private
		 * @type {Vector4}
		 */
		this._viewport = new Vector4( 0, 0, this._width, this._height );

		/**
		 * The scissor rectangle of the renderer in logical pixel unit.
		 *
		 * @private
		 * @type {Vector4}
		 */
		this._scissor = new Vector4( 0, 0, this._width, this._height );

		/**
		 * Whether the scissor test should be enabled or not.
		 *
		 * @private
		 * @type {boolean}
		 */
		this._scissorTest = false;

		/**
		 * A reference to a renderer module for managing shader attributes.
		 *
		 * @private
		 * @type {?Attributes}
		 * @default null
		 */
		this._attributes = null;

		/**
		 * A reference to a renderer module for managing geometries.
		 *
		 * @private
		 * @type {?Geometries}
		 * @default null
		 */
		this._geometries = null;

		/**
		 * A reference to a renderer module for managing node related logic.
		 *
		 * @private
		 * @type {?Nodes}
		 * @default null
		 */
		this._nodes = null;

		/**
		 * A reference to a renderer module for managing the internal animation loop.
		 *
		 * @private
		 * @type {?Animation}
		 * @default null
		 */
		this._animation = null;

		/**
		 * A reference to a renderer module for managing shader program bindings.
		 *
		 * @private
		 * @type {?Bindings}
		 * @default null
		 */
		this._bindings = null;

		/**
		 * A reference to a renderer module for managing render objects.
		 *
		 * @private
		 * @type {?RenderObjects}
		 * @default null
		 */
		this._objects = null;

		/**
		 * A reference to a renderer module for managing render and compute pipelines.
		 *
		 * @private
		 * @type {?Pipelines}
		 * @default null
		 */
		this._pipelines = null;

		/**
		 * A reference to a renderer module for managing render bundles.
		 *
		 * @private
		 * @type {?RenderBundles}
		 * @default null
		 */
		this._bundles = null;

		/**
		 * A reference to a renderer module for managing render lists.
		 *
		 * @private
		 * @type {?RenderLists}
		 * @default null
		 */
		this._renderLists = null;

		/**
		 * A reference to a renderer module for managing render contexts.
		 *
		 * @private
		 * @type {?RenderContexts}
		 * @default null
		 */
		this._renderContexts = null;

		/**
		 * A reference to a renderer module for managing textures.
		 *
		 * @private
		 * @type {?Textures}
		 * @default null
		 */
		this._textures = null;

		/**
		 * A reference to a renderer module for backgrounds.
		 *
		 * @private
		 * @type {?Background}
		 * @default null
		 */
		this._background = null;

		/**
		 * This fullscreen quad is used for internal render passes
		 * like the tone mapping and color space output pass.
		 *
		 * @private
		 * @type {QuadMesh}
		 */
		this._quad = new QuadMesh( new NodeMaterial() );
		this._quad.material.name = 'Renderer_output';

		/**
		 * A reference to the current render context.
		 *
		 * @private
		 * @type {?RenderContext}
		 * @default null
		 */
		this._currentRenderContext = null;

		/**
		 * A custom sort function for the opaque render list.
		 *
		 * @private
		 * @type {?Function}
		 * @default null
		 */
		this._opaqueSort = null;

		/**
		 * A custom sort function for the transparent render list.
		 *
		 * @private
		 * @type {?Function}
		 * @default null
		 */
		this._transparentSort = null;

		/**
		 * The framebuffer target.
		 *
		 * @private
		 * @type {?RenderTarget}
		 * @default null
		 */
		this._frameBufferTarget = null;

		const alphaClear = this.alpha === true ? 0 : 1;

		/**
		 * The clear color value.
		 *
		 * @private
		 * @type {Color4}
		 */
		this._clearColor = new Color4( 0, 0, 0, alphaClear );

		/**
		 * The clear depth value.
		 *
		 * @private
		 * @type {number}
		 * @default 1
		 */
		this._clearDepth = 1;

		/**
		 * The clear stencil value.
		 *
		 * @private
		 * @type {number}
		 * @default 0
		 */
		this._clearStencil = 0;

		/**
		 * The current render target.
		 *
		 * @private
		 * @type {?RenderTarget}
		 * @default null
		 */
		this._renderTarget = null;

		/**
		 * The active cube face.
		 *
		 * @private
		 * @type {number}
		 * @default 0
		 */
		this._activeCubeFace = 0;

		/**
		 * The active mipmap level.
		 *
		 * @private
		 * @type {number}
		 * @default 0
		 */
		this._activeMipmapLevel = 0;

		/**
		 * The current output render target.
		 *
		 * @private
		 * @type {?RenderTarget}
		 * @default null
		 */
		this._outputRenderTarget = null;

		/**
		 * The MRT setting.
		 *
		 * @private
		 * @type {?MRTNode}
		 * @default null
		 */
		this._mrt = null;

		/**
		 * This function defines how a render object is going
		 * to be rendered.
		 *
		 * @private
		 * @type {?Function}
		 * @default null
		 */
		this._renderObjectFunction = null;

		/**
		 * Used to keep track of the current render object function.
		 *
		 * @private
		 * @type {?Function}
		 * @default null
		 */
		this._currentRenderObjectFunction = null;

		/**
		 * Used to keep track of the current render bundle.
		 *
		 * @private
		 * @type {?RenderBundle}
		 * @default null
		 */
		this._currentRenderBundle = null;

		/**
		 * Next to `_renderObjectFunction()`, this function provides another hook
		 * for influencing the render process of a render object. It is meant for internal
		 * use and only relevant for `compileAsync()` right now. Instead of using
		 * the default logic of `_renderObjectDirect()` which actually draws the render object,
		 * a different function might be used which performs no draw but just the node
		 * and pipeline updates.
		 *
		 * @private
		 * @type {?Function}
		 * @default null
		 */
		this._handleObjectFunction = this._renderObjectDirect;

		/**
		 * Indicates whether the device has been lost or not. In WebGL terms, the device
		 * lost is considered as a context lost. When this is set to `true`, rendering
		 * isn't possible anymore.
		 *
		 * @private
		 * @type {boolean}
		 * @default false
		 */
		this._isDeviceLost = false;

		/**
		 * A callback function that defines what should happen when a device/context lost occurs.
		 *
		 * @type {Function}
		 */
		this.onDeviceLost = this._onDeviceLost;

		/**
		 * Defines the type of color buffers. The default `HalfFloatType` is recommend for
		 * best quality. To save memory and bandwidth, `UnsignedByteType` might be used.
		 * This will reduce rendering quality though.
		 *
		 * @private
		 * @type {number}
		 * @default HalfFloatType
		 */
		this._colorBufferType = colorBufferType;

		/**
		 * Whether the renderer has been initialized or not.
		 *
		 * @private
		 * @type {boolean}
		 * @default false
		 */
		this._initialized = false;

		/**
		 * A reference to the promise which initializes the renderer.
		 *
		 * @private
		 * @type {?Promise<this>}
		 * @default null
		 */
		this._initPromise = null;

		/**
		 * An array of compilation promises which are used in `compileAsync()`.
		 *
		 * @private
		 * @type {?Array<Promise>}
		 * @default null
		 */
		this._compilationPromises = null;

		/**
		 * Whether the renderer should render transparent render objects or not.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.transparent = true;

		/**
		 * Whether the renderer should render opaque render objects or not.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.opaque = true;

		/**
		 * Shadow map configuration
		 * @typedef {Object} ShadowMapConfig
		 * @property {boolean} enabled - Whether to globally enable shadows or not.
		 * @property {number} type - The shadow map type.
		 */

		/**
		 * The renderer's shadow configuration.
		 *
		 * @type {ShadowMapConfig}
		 */
		this.shadowMap = {
			enabled: false,
			type: PCFShadowMap
		};

		/**
		 * XR configuration.
		 * @typedef {Object} XRConfig
		 * @property {boolean} enabled - Whether to globally enable XR or not.
		 */

		/**
		 * The renderer's XR manager.
		 *
		 * @type {XRManager}
		 */
		this.xr = new XRManager( this, multiview );

		/**
		 * Debug configuration.
		 * @typedef {Object} DebugConfig
		 * @property {boolean} checkShaderErrors - Whether shader errors should be checked or not.
		 * @property {?Function} onShaderError - A callback function that is executed when a shader error happens. Only supported with WebGL 2 right now.
		 * @property {Function} getShaderAsync - Allows the get the raw shader code for the given scene, camera and 3D object.
		 */

		/**
		 * The renderer's debug configuration.
		 *
		 * @type {DebugConfig}
		 */
		this.debug = {
			checkShaderErrors: true,
			onShaderError: null,
			getShaderAsync: async ( scene, camera, object ) => {

				await this.compileAsync( scene, camera );

				const renderList = this._renderLists.get( scene, camera );
				const renderContext = this._renderContexts.get( scene, camera, this._renderTarget );

				const material = scene.overrideMaterial || object.material;

				const renderObject = this._objects.get( object, material, scene, camera, renderList.lightsNode, renderContext, renderContext.clippingContext );

				const { fragmentShader, vertexShader } = renderObject.getNodeBuilderState();

				return { fragmentShader, vertexShader };

			}
		};

	}
Constructs a new renderer.

@param {Backend} backend - The backend the renderer is targeting (e.g. WebGPU or WebGL 2).
@param {Renderer~Options} [parameters] - The configuration parameter.