setup method
void
setup(
- List<Light> lights, [
- bool? physicallyCorrectLights
])
Implementation
void setup(List<Light> lights, [bool? physicallyCorrectLights]) {
double r = 0.0;
double g = 0.0;
double b = 0.0;
for (int i = 0; i < 9; i++) {
state.probe[i].setValues(0, 0, 0);
}
int directionalLength = 0;
int pointLength = 0;
int spotLength = 0;
int rectAreaLength = 0;
int hemiLength = 0;
int numDirectionalShadows = 0;
int numPointShadows = 0;
int numSpotShadows = 0;
int numSpotMaps = 0;
int numSpotShadowsWithMaps = 0;
int numLightProbes = 0;
lights.sort((a, b) => shadowCastingAndTexturingLightsFirst(a, b));
// artist-friendly light intensity scaling factor
double scaleFactor = (physicallyCorrectLights != true) ? math.pi : 1.0;
for (int i = 0, l = lights.length; i < l; i++) {
final light = lights[i];
final color = light.color ?? Color();
final intensity = light.intensity;
final distance = light.distance;
final shadowMap = (light.shadow != null && light.shadow!.map != null) ? light.shadow!.map!.texture : null;
if (light is AmbientLight) {
r += color.red * intensity;
g += color.green * intensity;
b += color.blue * intensity;
}
else if (light is LightProbe) {
for (int j = 0; j < 9; j++) {
state.probe[j].addScaled(light.sh!.coefficients[j], intensity);
}
}
else if (light is DirectionalLight) {
final uniforms = cache.get(light);
(uniforms["color"] as Color)..setFrom(light.color!)..scale(light.intensity * scaleFactor);
if (light.castShadow) {
final shadow = light.shadow!;
final shadowUniforms = shadowCache.get(light);
shadowUniforms?["shadowIntensity"] = shadow.intensity;
shadowUniforms?["shadowBias"] = shadow.bias;
shadowUniforms?["shadowNormalBias"] = shadow.normalBias;
shadowUniforms?["shadowRadius"] = shadow.radius;
shadowUniforms?["shadowMapSize"] = shadow.mapSize;
state.directionalShadow.listSetter(directionalLength, shadowUniforms);
state.directionalShadowMap.listSetter(directionalLength, shadowMap);
state.directionalShadowMatrix.listSetter( directionalLength, light.shadow!.matrix);
numDirectionalShadows++;
}
state.directional.listSetter(directionalLength, uniforms);
directionalLength++;
}
else if (light is SpotLight) {
final uniforms = cache.get(light);
(uniforms["position"] as Vector3).setFromMatrixPosition(light.matrixWorld);
(uniforms["color"] as Color)..setFrom(color)..scale(intensity * scaleFactor);
uniforms["distance"] = distance;
uniforms["coneCos"] = math.cos(light.angle!);
uniforms["penumbraCos"] = math.cos(light.angle! * (1 - light.penumbra!));
uniforms["decay"] = light.decay;
state.spot.listSetter(spotLength, uniforms);
final shadow = light.shadow!;
if ( light.map != null) {
state.spotLightMap.listSetter(numSpotMaps, light.map);
numSpotMaps ++;
// make sure the lightMatrix is up to date
// TODO : do it if required only
shadow.updateMatrices( light );
if (light.castShadow) numSpotShadowsWithMaps ++;
}
state.spotLightMatrix.add(shadow.matrix);
if (light.castShadow) {
final shadowUniforms = shadowCache.get(light);
shadowUniforms?['shadowIntensity'] = shadow.intensity;
shadowUniforms?["shadowBias"] = shadow.bias;
shadowUniforms?["shadowNormalBias"] = shadow.normalBias;
shadowUniforms?["shadowRadius"] = shadow.radius;
shadowUniforms?["shadowMapSize"] = shadow.mapSize;
state.spotShadow.listSetter(spotLength, shadowUniforms);
state.spotShadowMap.listSetter(spotLength, shadowMap);
state.spotShadowMatrix.listSetter( spotLength, light.shadow!.matrix);
numSpotShadows++;
}
spotLength++;
}
else if (light is RectAreaLight) {
final uniforms = cache.get(light);
// (a) intensity is the total visible light emitted
//uniforms.color.copy( color ).scale( intensity / ( light.width * light.height * math.PI ) );
// (b) intensity is the brightness of the light
uniforms["color"]..setFrom(color)..scale(intensity);
uniforms["halfWidth"].setValues(light.width! * 0.5, 0.0, 0.0);
uniforms["halfHeight"].setValues(0.0, light.height! * 0.5, 0.0);
// state.rectArea[ rectAreaLength ] = uniforms;
state.rectArea.listSetter(rectAreaLength, uniforms);
rectAreaLength++;
}
else if (light is PointLight) {
final uniforms = cache.get(light);
(uniforms["color"] as Color)..setFrom(light.color!)..scale(light.intensity * scaleFactor);
uniforms["distance"] = light.distance ?? 0;
uniforms["decay"] = light.decay;
if (light.castShadow) {
final shadow = light.shadow!;
final shadowUniforms = shadowCache.get(light);
shadowUniforms?['shadowIntensity'] = shadow.intensity;
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.listSetter(pointLength, shadowUniforms);
state.pointShadowMap.listSetter(pointLength, shadowMap);
state.pointShadowMatrix.listSetter(pointLength, light.shadow!.matrix);
numPointShadows++;
}
// state.point[ pointLength ] = uniforms;
state.point.listSetter(pointLength, uniforms);
pointLength++;
}
else if (light is HemisphereLight) {
final uniforms = cache.get(light);
uniforms["skyColor"]..setFrom(light.color)..scale(intensity * scaleFactor);
uniforms["groundColor"]..setFrom(light.groundColor)..scale(intensity * scaleFactor);
// state.hemi[ hemiLength ] = uniforms;
state.hemi.listSetter(hemiLength, uniforms);
hemiLength++;
}
else {
throw (" WebGLLigts type: ${light.type} is not support ..... ");
}
}
if (rectAreaLength > 0) {
if ( extensions.has( 'OES_texture_float_linear' ) == true ) {
state.rectAreaLTC1 = uniformsLib["LTC_FLOAT_1"];
state.rectAreaLTC2 = uniformsLib["LTC_FLOAT_2"];
}
else{
state.rectAreaLTC1 = uniformsLib["LTC_HALF_1"];
state.rectAreaLTC2 = uniformsLib["LTC_HALF_2"];
}
}
state.ambient[0] = r.toDouble();
state.ambient[1] = g.toDouble();
state.ambient[2] = b.toDouble();
final 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 ||
hash['numSpotMaps'] != numSpotMaps ||
hash['numLightProbes'] != numLightProbes ) {
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.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps;
state.spotLightMap.length = numSpotMaps;
state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps;
state.numLightProbes = numLightProbes;
hash["directionalLength"] = directionalLength;
hash["pointLength"] = pointLength;
hash["spotLength"] = spotLength;
hash["rectAreaLength"] = rectAreaLength;
hash["hemiLength"] = hemiLength;
hash["numDirectionalShadows"] = numDirectionalShadows;
hash["numPointShadows"] = numPointShadows;
hash["numSpotShadows"] = numSpotShadows;
hash['numSpotMaps'] = numSpotMaps;
hash['numLightProbes'] = numLightProbes;
state.version = nextVersion++;
}
}