render method

void render(
  1. List<Light> lights,
  2. Object3D scene,
  3. Camera camera
)

Implementation

void render(List<Light> lights, Object3D scene, Camera camera) {
  if (!scope.enabled) return;
  if (!scope.autoUpdate && !scope.needsUpdate) return;

  if (lights.isEmpty) return;

  final currentRenderTarget = _renderer.getRenderTarget();
  final activeCubeFace = _renderer.getActiveCubeFace();
  final activeMipmapLevel = _renderer.getActiveMipmapLevel();

  final state = _renderer.state;

  // Set GL state for depth map.
  state.setBlending(NoBlending);
  state.buffers["color"].setClear(1.0, 1.0, 1.0, 1.0, false);
  state.buffers["depth"].setTest(true);
  state.setScissorTest(false);

		final toVSM = ( _previousType != VSMShadowMap && type == VSMShadowMap );
		final fromVSM = ( _previousType == VSMShadowMap && type != VSMShadowMap );

  // render depth map

  for (int i = 0, il = lights.length; i < il; i++) {
    final light = lights[i];
    final shadow = light.shadow;

    if (shadow == null) {
      continue;
    }

    if (!shadow.autoUpdate && !shadow.needsUpdate) continue;

    _shadowMapSize.setFrom(shadow.mapSize);

    final shadowFrameExtents = shadow.getFrameExtents();
    _shadowMapSize.multiply(shadowFrameExtents);
    _viewportSize.setFrom(shadow.mapSize);

    if (_shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize) {
      if (_shadowMapSize.x > _maxTextureSize) {
        _viewportSize.x = (_maxTextureSize / shadowFrameExtents.x).floorToDouble();
        _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;
        shadow.mapSize.x = _viewportSize.x;
      }

      if (_shadowMapSize.y > _maxTextureSize) {
        _viewportSize.y = (_maxTextureSize / shadowFrameExtents.y).floorToDouble();
        _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;
        shadow.mapSize.y = _viewportSize.y;
      }
    }

    if (shadow.map == null || toVSM || fromVSM && shadow is! PointLightShadow && type == VSMShadowMap) {
				final Map<String,dynamic> pars = (type != VSMShadowMap ) ? { 'minFilter': NearestFilter, 'magFilter': NearestFilter } : {};

				if ( shadow.map != null ) {
					shadow.map?.dispose();
				}

      shadow.map = WebGLRenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt(), WebGLRenderTargetOptions(pars));
      shadow.map!.texture.name = '${light.name}.shadowMap';

      shadow.camera!.updateProjectionMatrix();
    }

    _renderer.setRenderTarget(shadow.map);
    _renderer.clear();

    final viewportCount = shadow.getViewportCount();

    for (int vp = 0; vp < viewportCount; vp++) {
      final viewport = shadow.getViewport(vp);
      _viewport.setValues(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w);
      state.viewport(_viewport);
      shadow.updateMatrices(light, viewportIndex: vp);
      _frustum = shadow.getFrustum();
      renderObject(scene, camera, shadow.camera!, light, type);
    }

    // do blur pass for VSM

    if (shadow is! PointLightShadow && type == VSMShadowMap) {
      vSMPass(shadow, camera);
    }

    shadow.needsUpdate = false;
  }
  _previousType = type;

  scope.needsUpdate = false;
  _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel);
}