/// <summary>
        /// Populates an agent's info.visualObservations list with buffered
        /// and processed textures based on observation settings.
        /// </summary>
        /// <param name="observation">Observation.</param>
        /// <param name="agentVisualObservations">Empty list.</param>
        internal void ApplyBuffer(Observation observation,
                                  List <Texture2D> agentVisualObservations)
        {
            List <Texture2D> textures = new List <Texture2D>();
            int addedFrames           = observation.addFrames;

            if (observation.blackAndWhite)
            {
                DesaturateTexture(input);
            }

            if (!observation.motionOnly)
            {
                // Input is always the first texture,
                // unless Stacking Mode = Motion Only.
                textures.Add(input);
            }

            if (addedFrames > 0)
            {
                Texture2D[] buffered = bufferQueue.ToArray();
                int         interval = observation.skipFrames + 1;

                if (observation.subtract)
                {
                    // Create difference textures:
                    // Subtract current from buffered...
                    SubtractTextures(input,
                                     buffered[buffered.Length - interval],
                                     subtracted[0]);

                    for (int i = 1; i < addedFrames; i++)
                    {
                        // ...Subtract buffered from buffered.
                        SubtractTextures(buffered[buffered.Length
                                                  - i * interval],
                                         buffered[buffered.Length
                                                  - (i + 1) * interval],
                                         subtracted[i]);
                    }

                    if (observation.motion)
                    {
                        CopyTexture(subtracted[0], combined);

                        for (int i = 1; i < addedFrames; i++)
                        {
                            // Add difference textures to motion texture.
                            // Pixel values of added textures are proportional
                            // to their place in the buffer, older -> fainter.
                            AddTextures(subtracted[i],
                                        combined,
                                        1f - i / (float)addedFrames);
                        }
                        // Stacking Mode = Motion.
                        textures.Add(combined);
                    }
                    else
                    {
                        for (int i = 0; i < addedFrames; i++)
                        {
                            // Stacking Mode = Subtract.
                            textures.Add(subtracted[i]);
                        }
                    }
                }
                else
                {
                    for (int i = 1; i <= addedFrames; i++)
                    {
                        // Stacking Mode = Normal.
                        textures.Add(buffered[buffered.Length - i * interval]);
                    }
                }
                // Rotate buffered frames.
                bufferQueue.Enqueue(CopyTexture(input, bufferQueue.Dequeue()));
            }

            if (observation.mergeFrames)
            {
                agentVisualObservations.Add(MergeTextures(textures, combined));
            }
            else
            {
                foreach (Texture2D tex in textures)
                {
                    agentVisualObservations.Add(tex);
                }
            }
        }
 /// <summary>
 /// Retrieves an empty black Texture2D matching observation size.
 /// </summary>
 /// <param name="observation">Observation.</param>
 /// <returns>Texture2D.</returns>
 public static Texture2D CreateTexture(Observation observation)
 {
     return(CreateTexture(observation.width, observation.height));
 }