Comment Colorer.Lerp entre plusieurs couleurs?

12

J'ai trouvé assez difficile de trouver une solution à cela dans les documents Unity.

Color.Lerp(Color a, Color b, float t) est une fonction qui modifie progressivement une couleur selon une étape t, lui donnant la valeur finale de la Couleur b.

Comment puis-je Lerp entre plusieurs couleurs l'une après l'autre?

Zee
la source

Réponses:

13

Soit _colors un tableau de couleurs soit LENGHT soit le nombre de couleurs du tableau soit t la valeur flottante 0..1

float scaledTime = t * (float) (LENGHT - 1);
Color oldColor = _colors[(int) scaledTime];
Color newColor = _colors[(int) (scaledTime + 1f)];
float newT = scaledTime - Mathf.Round(scaledTime); 

enfin, vous pouvez utiliser Lerp

Color.Lerp(oldColor, newColor, newT)
dnk drone.vs.drones
la source
+1 - excellente réponse - ne nécessite aucune boucle ou branche spéciale, et est complètement général pour N couleurs.
jpaver
Lorsque la valeur 1 est atteinte, la couleur sera-t-elle la dernière couleur du tableau?
G3tinmybelly
G3tinmybelly vous avez raison. Le t == 1 n'est pas géré correctement. Nous pouvons donc ajouter avant: if (t == 1) return Arr [N-1]
dnk drone.vs.drones
10

Une approche qui peut être adoptée avec plusieurs transitions de couleurs consiste à tirer parti d'un dégradé .

En exposant une variable publique de ce type, un développeur peut utiliser l'inspecteur pour lancer l'éditeur de dégradé afin de concevoir un dégradé contenant un nombre quelconque de couleurs. Cet éditeur vous permet d'utiliser les sélecteurs de couleur de l'unité, de régler avec précision le placement des touches de couleur / alpha et de sauvegarder / charger les dégradés.

entrez la description de l'image ici

Une fois conçue, la Gradient.Evaluate()méthode acceptera un flotteur dans la plage 0-1 pour retourner la couleur appropriée.

using UnityEngine;

public class GradientTest : MonoBehaviour
{
    public Gradient myGradient;
    public float strobeDuration = 2f;

    public void Update() {
        float t = Mathf.PingPong(Time.time / strobeDuration, 1f);
        Camera.main.backgroundColor = myGradient.Evaluate(t);
    }
}

Malheureusement, l'API pour la construction par programme d'un dégradé n'est pas aussi élégante .

Kelly Thomas
la source
1
Les ColorBands peuvent être utilisés pour le même objectif mais avec plus de liberté sur la couleur
SteakOverflow
1
public float every;   //The public variable "every" refers to "Lerp the color every X"
float colorstep;
Color[] colors = new Color[4]; //Insert how many colors you want to lerp between here, hard coded to 4
int i;
Color lerpedColor = Color.red;  //This should optimally be the color you are going to begin with

void Start () {

    //In here, set the array colors you are going to use, optimally, repeat the first color in the end to keep transitions smooth

    colors [0] = Color.red;
    colors [1] = Color.yellow;    
    colors [2] = Color.cyan;
    colors [3] = Color.red;

}


// Update is called once per frame
void Update () {

    if (colorstep < every) { //As long as the step is less than "every"
        lerpedColor = Color.Lerp (colors[i], colors[i+1], colorstep);
        this.GetComponent<Camera> ().backgroundColor = lerpedColor;
        colorstep +=0.025f;  //The lower this is, the smoother the transition, set it yourself
    } else { //Once the step equals the time we want to wait for the color, increment to lerp to the next color

        colorstep = 0;

        if (i < (colors.Length - 2)){ //Keep incrementing until i + 1 equals the Lengh
        i++;
        }
        else { //and then reset to zero
            i=0;
        }
    }
}

C'est donc le code que j'ai fini par utiliser pour lerp entre trois couleurs à moi, j'espère que je serai utile à quiconque décide de le chercher.

Zee
la source
0

J'ai l'impression qu'il pourrait y avoir une meilleure solution. La seule raison pour laquelle je verrais passer de couleur en couleur est si vous vouliez changer continuellement la teinte ... http://en.wikipedia.org/wiki/Hue

Voici comment convertir HSV en RVB: http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV

Avec cela, vous pouvez utiliser les couleurs HSV, changer simplement la teinte, puis convertir en RVB. De plus, avec Color.Lerp, vous avez le problème de l'incohérence. Si vous passez de l'orange au jaune, puis au vert, vous constaterez que la couleur commence à devenir jaune très rapidement, puis commence à ralentir à l'approche du jaune, puis accélère à nouveau une fois qu'elle passe au jaune et passe au vert. Cela ralentira donc le changement de couleur à chaque point auquel vous vous attarderez. Je pense que changer la teinte serait beaucoup plus efficace - et à long terme, donnerait un meilleur effet. :)

Superdoggy
la source
0

Que diriez-vous d'écrire votre propre version, qui exploite Color.Lerp()?

Une version très simple qui prend 3 couleurs et place la seconde au milieu pourrait ressembler à ceci:

Color Lerp3(Color a, Color b, Color c, float t)
{
    if (t < 0.5f) // 0.0 to 0.5 goes to a -> b
        return Color.Lerp(a, b, t / 0.5f);
    else // 0.5 to 1.0 goes to b -> c
        return Color.Lerp(b, c, (t - 0.5f) / 0.5f);
}
Pyjama Panda
la source
0

Puisque vous n'avez pas dit ce que vous vouliez changer de couleur, je vais donner un vague exemple avec une couleur créée sur la méthode.

Le point est d'avoir une collection de couleurs, et une durée au total (comme sur l'exemple que je vais fournir) ou une durée entre chacune (c'est à vous de décider).

Personnellement, je n'interpole pas les choses sur Update que je sais que je n'interpolerai pas constamment (la caméra étant une exception), donc j'utilise des coroutines pour gérer cela.

Sur cet exemple, je divise la durée donnée sur l'inspecteur par la quantité de couleurs, puis je Lerp la couleur réelle de l'itérateur à la couleur de l'itérateur suivant, et la durée sera de la durée précédemment épissée. Voici l'exemple:

public class ColorLerping : MonoBehaviour
{
    public Color sampleColor; /// Just for debugging purposes.
    public float lerpDuration;
    public Color[] colors;

    void Awake()
    {
        StartCoroutine(LerpColors());
    }

    private IEnumerator LerpColors()
    {
        if(colors.Length > 0)
        {
            /// Split the time between the color quantities.
            float dividedDuration = lerpDuration / colors.Lenght;

            for(int i = 0; i < colors.Length - 1; i++)
            {
                float t = 0.0f;

                while(t < (1.0f + Mathf.Epsilon))
                {
                    sampleColor = Color.Lerp(colors[i], colors[i + 1], t);
                    t += Time.deltaTime / dividedDuration;
                    yield return null;
                }

                // Since it is posible that t does not reach 1.0, force it at the end.
                sampleColor = Color.Lerp(colors[i], colors[i + 1], 1.0f);
            }

        }
        else yield return null; /// Do nothing if there are no colors.
    }
}

J'espère que cela aide.

LifGwaethrakindo
la source