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 == false) return;
  if (scope.autoUpdate == false && scope.needsUpdate == false) 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);

  // 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 == false && shadow.needsUpdate == false) 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 && shadow is! PointLightShadow && type == VSMShadowMap) {
      shadow.map = WebGLRenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt());
      shadow.map!.texture.name = '${light.name}.shadowMap';

      shadow.mapPass = WebGLRenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt());

      shadow.camera!.updateProjectionMatrix();
    }

    if (shadow.map == null) {
      final pars = WebGLRenderTargetOptions({
        "minFilter": NearestFilter,
        "magFilter": NearestFilter,
        "format": RGBAFormat
      });

      shadow.map = WebGLRenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt(), 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;
  }

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