internal void Read(ParameterReader paramReader)
        {
            while (paramReader.Read())
            {
                switch (paramReader.HeadToken)
                {
                case "id_start":
                {
                    var light = new Light {
                        Id = ( LightId )paramReader.ReadInt32()
                    };
                    {
                        light.Read(paramReader);
                    }

                    Lights.Add(light);

                    break;
                }

                case "group_start":
                    throw new InvalidDataException("Expected group end before group start");

                case "group_end":
                    if (paramReader.ReadUInt32() != Id)
                    {
                        throw new InvalidDataException($"Expected group end with id {Id}");
                    }

                    return;
                }
            }
        }
        public override void Read(EndianBinaryReader reader, ISection section = null)
        {
            var paramReader = new ParameterReader(reader);

            while (paramReader.Read())
            {
                switch (paramReader.HeadToken)
                {
                case "exposure":
                    Exposure = paramReader.ReadSingle();
                    break;

                case "gamma":
                    Gamma = paramReader.ReadSingle();
                    break;

                case "saturate_power":
                    SaturatePower = paramReader.ReadUInt32();
                    break;

                case "saturate_coef":
                    SaturateCoefficient = paramReader.ReadSingle();
                    break;

                case "flare":
                    FlarePower = paramReader.ReadSingle();
                    FlareShaft = paramReader.ReadSingle();
                    FlareGhost = paramReader.ReadSingle();
                    break;

                case "sigma":
                    GlareRadius = paramReader.ReadVector3();
                    break;

                case "intensity":
                    GlareIntensity = paramReader.ReadVector3();
                    break;

                case "auto_exposure":
                    AutoExposure = paramReader.ReadBoolean();
                    break;

                case "tone_map_type":
                    ToneMapType = ( ToneMapType )paramReader.ReadInt32();
                    break;

                case "fade_color":
                    FadeColor     = paramReader.ReadVector3();
                    FadeBlendFunc = ( FadeBlendFunc )paramReader.ReadInt32();
                    break;

                case "tone_transform":
                    ToneTransStart = paramReader.ReadVector3();
                    ToneTransEnd   = paramReader.ReadVector3();
                    break;
                }
            }
        }
        public override void Read(EndianBinaryReader reader, ISection section = null)
        {
            var paramReader = new ParameterReader(reader);

            while (paramReader.Read())
            {
                if (paramReader.HeadToken != "group_start")
                {
                    continue;
                }

                var group = new FogGroup {
                    Id = paramReader.ReadUInt32()
                };
                {
                    group.Read(paramReader);
                }

                Groups.Add(group);
            }
        }
        internal void Read(ParameterReader paramReader)
        {
            while (paramReader.Read())
            {
                switch (paramReader.HeadToken)
                {
                case "type":
                    Type = ( FogType )paramReader.ReadInt32();
                    break;

                case "density":
                    Density = paramReader.ReadSingle();
                    break;

                case "linear":
                    Start = paramReader.ReadSingle();
                    End   = paramReader.ReadSingle();
                    break;

                case "color":
                    Color = paramReader.ReadVector4();
                    break;

                case "group_start":
                    throw new InvalidDataException("Expected group end before group start");

                case "group_end":
                    if (paramReader.ReadUInt32() != Id)
                    {
                        throw new InvalidDataException($"Expected group end with id {Id}");
                    }

                    return;
                }
            }
        }