<!-- SOLIDIVISM · part 481 -->
draw' ) ) {

					const starts = object._multiDrawStarts;
					const counts = object._multiDrawCounts;
					const drawCount = object._multiDrawCount;
					const bytesPerElement = index ? attributes.get( index ).bytesPerElement : 1;
					const uniforms = properties.get( material ).currentProgram.getUniforms();
					for ( let i = 0; i < drawCount; i ++ ) {

						uniforms.setValue( _gl, '_gl_DrawID', i );
						renderer.render( starts[ i ] / bytesPerElement, counts[ i ] );

					}

				} else {

					renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );

				}

			} else if ( object.isInstancedMesh ) {

				renderer.renderInstances( drawStart, drawCount, object.count );

			} else if ( geometry.isInstancedBufferGeometry ) {

				const maxInstanceCount = geometry._maxInstanceCount !== undefined ? geometry._maxInstanceCount : Infinity;
				const instanceCount = Math.min( geometry.instanceCount, maxInstanceCount );

				renderer.renderInstances( drawStart, drawCount, instanceCount );

			} else {

				renderer.render( drawStart, drawCount );

			}

		};

		// Compile

		function prepareMaterial( material, scene, camera, object ) {

			if ( _nodesHandler !== null && material.isNodeMaterial ) _nodesHandler.setObject( object, material );

			if ( _clippingEnabled === true ) clipping.setState( material, camera, false );

			if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {

				material.side = BackSide;
				material.needsUpdate = true;
				getProgram( material, scene, object );

				material.side = FrontSide;
				material.needsUpdate = true;
				getProgram( material, scene, object );

				material.side = DoubleSide;

			} else {

				getProgram( material, scene, object );

			}

		}

		/**
		 * Compiles all materials in the scene with the camera. This is useful to precompile shaders
		 * before the first rendering. If you want to add a 3D object to an existing scene, use the third
		 * optional parameter for applying the target scene.
		 *
		 * Note that the (target) scene's lighting and environment must be configured before calling this method.
		 *
		 * @param {Object3D} scene - The scene or another type of 3D object to precompile.
		 * @param {Camera} camera - The camera.
		 * @param {?Scene} [targetScene=null] - The target scene.
		 * @return {Set<Material>} The precompiled materials.
		 */
		this.compile = function ( scene, camera, targetScene = null ) {

			if ( targetScene === null ) targetScene = scene;
			if ( _nodesHandler !== null ) _nodesHandler.renderStart( scene, camera, targetScene );

			currentRenderState = renderStates.get( targetScene );
			currentRenderState.init( camera );

			renderStateStack.push( currentRenderState );

			// gather lights from both the target scene and the new object that will be added to the scene.

			targetScene.traverseVisible( function ( object ) {

				if ( object.isLight && object.layers.test( camera.layers ) ) {

					currentRenderState.pushLight( object );

					if ( object.castShadow ) {

						currentRenderState.pushShadow( object );

					}

				}

			} );

			if ( scene !== targetScene ) {

				scene.traverseVisible( function ( object ) {

					if ( object.isLight && object.layers.test( camera.layers ) ) {

						currentRenderState.pushLight( object );

						if ( object.castShadow ) {

							currentRenderState.pushShadow( object );

						}

					}

				} );

			}

			currentRenderState.setupLights();
			if ( _nodesHandler !== null ) _nodesHandler.updateLights( currentRenderState.state.lightsArray );

			_localClippingEnabled = this.localClippingEnabled;
			_clippingEnabled = clipping.init( this.clippingPlanes, _localClippingEnabled );

			if ( _clippingEnabled === true ) clipping.setGlobalState( this.clippingPlanes, camera );

			// node materials reference the shadow map when they are built, so it must exist by now

			if ( _nodesHandler !== null ) shadowMap.render( currentRenderState.state.shadowsArray, targetScene, camera );

			// Only initialize materials in the new scene, not the targetScene.

			const materials = new Set();

			scene.traverse( function ( object ) {

				if ( ! ( object.isMesh || object.isPoints || object.isLine || object.isSprite ) ) {

					return;

				}

				const material = object.material;

				if ( material ) {

					if ( Array.isArray( material ) ) {

						for ( let i = 0; i < material.length; i ++ ) {

							const material2 = material[ i ];

							prepareMaterial( material2, targetScene, camera, object );
							materials.add( material2 );

						}

					} else {

						prepareMaterial( material, targetScene, camera, object );
						materials.add( material );

					}

				}

			} );

			currentRenderState = renderStateStack.pop();
			if ( _nodesHandler !== null ) _nodesHandler.renderEnd();

			return materials;

		};

		// compileAsync

		/**
		 * Asynchronous version of {@link WebGLRende