setup method

void setup(
  1. List<Light> lights, [
  2. bool? physicallyCorrectLights
])

Implementation

void setup(List<Light> lights, [bool? physicallyCorrectLights]) {
  num r = 0.0;
  num g = 0.0;
  num b = 0.0;

  for (var i = 0; i < 9; i++) {
    state.probe[i].set(0, 0, 0);
  }

  var directionalLength = 0;
  var pointLength = 0;
  var spotLength = 0;
  var rectAreaLength = 0;
  var hemiLength = 0;

  var numDirectionalShadows = 0;
  var numPointShadows = 0;
  var numSpotShadows = 0;

  lights.sort((a, b) => shadowCastingLightsFirst(a, b));

  // artist-friendly light intensity scaling factor
  num scaleFactor = (physicallyCorrectLights != true) ? Math.PI : 1.0;

  for (var i = 0, l = lights.length; i < l; i++) {
    var light = lights[i];

    var color = light.color!;
    var intensity = light.intensity;
    var distance = light.distance;

    var shadowMap = (light.shadow != null && light.shadow!.map != null)
        ? light.shadow!.map!.texture
        : null;

    if (light.type == "AmbientLight") {
      r += color.r * intensity * scaleFactor;
      g += color.g * intensity * scaleFactor;
      b += color.b * intensity * scaleFactor;
    } else if (light.type == "LightProbe") {
      for (var j = 0; j < 9; j++) {
        state.probe[j].addScaledVector(light.sh!.coefficients[j], intensity);
      }
    } else if (light.type == "DirectionalLight") {
      var uniforms = cache.get(light);

      uniforms["color"]
          .copy(light.color)
          .multiplyScalar(light.intensity * scaleFactor);

      if (light.castShadow) {
        var shadow = light.shadow!;

        var shadowUniforms = shadowCache.get(light);

        shadowUniforms["shadowBias"] = shadow.bias;
        shadowUniforms["shadowNormalBias"] = shadow.normalBias;
        shadowUniforms["shadowRadius"] = shadow.radius;
        shadowUniforms["shadowMapSize"] = shadow.mapSize;

        // state.directionalShadow[ directionalLength ] = shadowUniforms;
        listSetter(
            state.directionalShadow, directionalLength, shadowUniforms);

        // state["directionalShadowMap"][ directionalLength ] = shadowMap;
        listSetter(state.directionalShadowMap, directionalLength, shadowMap);

        // state["directionalShadowMatrix"][ directionalLength ] = light.shadow!.matrix;
        listSetter(state.directionalShadowMatrix, directionalLength,
            light.shadow!.matrix);

        numDirectionalShadows++;
      }

      // state.directional[ directionalLength ] = uniforms;
      listSetter(state.directional, directionalLength, uniforms);

      directionalLength++;
    } else if (light.type == "SpotLight") {
      var uniforms = cache.get(light);

      uniforms["position"].setFromMatrixPosition(light.matrixWorld);
      uniforms["color"].copy(color).multiplyScalar(intensity * scaleFactor);

      uniforms["distance"] = distance;

      uniforms["coneCos"] = Math.cos(light.angle!);
      uniforms["penumbraCos"] =
          Math.cos(light.angle! * (1 - light.penumbra!));
      uniforms["decay"] = light.decay;

      if (light.castShadow) {
        var shadow = light.shadow!;

        var shadowUniforms = shadowCache.get(light);

        shadowUniforms["shadowBias"] = shadow.bias;
        shadowUniforms["shadowNormalBias"] = shadow.normalBias;
        shadowUniforms["shadowRadius"] = shadow.radius;
        shadowUniforms["shadowMapSize"] = shadow.mapSize;

        // state.spotShadow[ spotLength ] = shadowUniforms;
        listSetter(state.spotShadow, spotLength, shadowUniforms);

        // state.spotShadowMap[ spotLength ] = shadowMap;
        // print("1 spotShadowMap: ${state.spotShadowMap} ${spotLength} ${shadowMap} ");
        listSetter(state.spotShadowMap, spotLength, shadowMap);

        // state.spotShadowMatrix[ spotLength ] = light.shadow!.matrix;
        listSetter(state.spotShadowMatrix, spotLength, light.shadow!.matrix);

        numSpotShadows++;
      }

      // state.spot[ spotLength ] = uniforms;
      listSetter(state.spot, spotLength, uniforms);

      spotLength++;
    } else if (light.type == "RectAreaLight") {
      var uniforms = cache.get(light);

      // (a) intensity is the total visible light emitted
      //uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) );

      // (b) intensity is the brightness of the light
      uniforms["color"].copy(color).multiplyScalar(intensity);

      uniforms["halfWidth"].set(light.width! * 0.5, 0.0, 0.0);
      uniforms["halfHeight"].set(0.0, light.height! * 0.5, 0.0);

      // state.rectArea[ rectAreaLength ] = uniforms;
      listSetter(state.rectArea, rectAreaLength, uniforms);

      rectAreaLength++;
    } else if (light.type == "PointLight") {
      var uniforms = cache.get(light);

      uniforms["color"]
          .copy(light.color)
          .multiplyScalar(light.intensity * scaleFactor);

      // TODO distance 默认0 ??
      uniforms["distance"] = light.distance ?? 0;
      uniforms["decay"] = light.decay;

      if (light.castShadow) {
        var shadow = light.shadow!;

        var shadowUniforms = shadowCache.get(light);

        shadowUniforms["shadowBias"] = shadow.bias;
        shadowUniforms["shadowNormalBias"] = shadow.normalBias;
        shadowUniforms["shadowRadius"] = shadow.radius;
        shadowUniforms["shadowMapSize"] = shadow.mapSize;
        shadowUniforms["shadowCameraNear"] = shadow.camera!.near;
        shadowUniforms["shadowCameraFar"] = shadow.camera!.far;

        // state.pointShadow[ pointLength ] = shadowUniforms;
        listSetter(state.pointShadow, pointLength, shadowUniforms);

        // state.pointShadowMap[ pointLength ] = shadowMap;
        listSetter(state.pointShadowMap, pointLength, shadowMap);

        // state.pointShadowMatrix[ pointLength ] = light.shadow!.matrix;
        listSetter(
            state.pointShadowMatrix, pointLength, light.shadow!.matrix);

        numPointShadows++;
      }

      // state.point[ pointLength ] = uniforms;
      listSetter(state.point, pointLength, uniforms);

      pointLength++;
    } else if (light.type == "HemisphereLight") {
      var uniforms = cache.get(light);

      uniforms["skyColor"]
          .copy(light.color)
          .multiplyScalar(intensity * scaleFactor);
      uniforms["groundColor"]
          .copy(light.groundColor)
          .multiplyScalar(intensity * scaleFactor);

      // state.hemi[ hemiLength ] = uniforms;
      listSetter(state.hemi, hemiLength, uniforms);

      hemiLength++;
    } else {
      throw (" WebGLLigts type: ${light.type} is not support ..... ");
    }
  }

  if (rectAreaLength > 0) {
    if (capabilities.isWebGL2) {
      // WebGL 2

      state.rectAreaLTC1 = UniformsLib["LTC_FLOAT_1"];
      state.rectAreaLTC2 = UniformsLib["LTC_FLOAT_2"];
    } else {
      // WebGL 1

      if (extensions.has('OES_texture_float_linear') == true) {
        state.rectAreaLTC1 = UniformsLib["LTC_FLOAT_1"];
        state.rectAreaLTC2 = UniformsLib["LTC_FLOAT_2"];
      } else if (extensions.has('OES_texture_half_float_linear') == true) {
        state.rectAreaLTC1 = UniformsLib["LTC_HALF_1"];
        state.rectAreaLTC2 = UniformsLib["LTC_HALF_2"];
      } else {
        print(
            'THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.');
      }
    }
  }

  state.ambient[0] = r.toDouble();
  state.ambient[1] = g.toDouble();
  state.ambient[2] = b.toDouble();

  var hash = state.hash;

  if (hash["directionalLength"] != directionalLength ||
      hash["pointLength"] != pointLength ||
      hash["spotLength"] != spotLength ||
      hash["rectAreaLength"] != rectAreaLength ||
      hash["hemiLength"] != hemiLength ||
      hash["numDirectionalShadows"] != numDirectionalShadows ||
      hash["numPointShadows"] != numPointShadows ||
      hash["numSpotShadows"] != numSpotShadows) {
    state.directional.length = directionalLength;
    state.spot.length = spotLength;
    state.rectArea.length = rectAreaLength;
    state.point.length = pointLength;
    state.hemi.length = hemiLength;

    state.directionalShadow.length = numDirectionalShadows;
    state.directionalShadowMap.length = numDirectionalShadows;
    state.pointShadow.length = numPointShadows;
    state.pointShadowMap.length = numPointShadows;
    state.spotShadow.length = numSpotShadows;
    state.spotShadowMap.length = numSpotShadows;
    state.directionalShadowMatrix.length = numDirectionalShadows;
    state.pointShadowMatrix.length = numPointShadows;
    state.spotShadowMatrix.length = numSpotShadows;

    hash["directionalLength"] = directionalLength;
    hash["pointLength"] = pointLength;
    hash["spotLength"] = spotLength;
    hash["rectAreaLength"] = rectAreaLength;
    hash["hemiLength"] = hemiLength;

    hash["numDirectionalShadows"] = numDirectionalShadows;
    hash["numPointShadows"] = numPointShadows;
    hash["numSpotShadows"] = numSpotShadows;

    state.version = nextVersion++;
  }
}