Làm thế nào để Color.Lerp giữa nhiều màu sắc?


12

Tôi đã thấy khá khó khăn để tìm một giải pháp cho vấn đề này trong các tài liệu của Unity.

Color.Lerp(Color a, Color b, float t) là một hàm thay đổi dần màu theo bước t, tạo cho nó giá trị cuối cùng của Màu b.

Làm thế nào để tôi Lerp giữa nhiều màu sắc khác nhau?

Câu trả lời:


13

Hãy _colors là một mảng màu sắc để cho chiều dài là số màu sắc trong mảng để t là giá trị 0..1 phao

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

cuối cùng bạn có thể sử dụng Lerp

Color.Lerp(oldColor, newColor, newT)

+1 - câu trả lời tuyệt vời - không yêu cầu bất kỳ nhánh lặp hoặc đặc biệt nào và hoàn toàn chung cho N màu.
jpaver

Khi giá trị 1 được nhấn, màu sẽ là màu cuối cùng trong mảng?
G3tinmybelly

G3tinmybelly bạn nói đúng. T == 1 không được quản lý chính xác. Vì vậy, chúng tôi có thể thêm trước: if (t == 1) return Arr [N-1]
dnk drone.vs.drones

10

Một cách tiếp cận có thể được thực hiện với nhiều hiệu ứng chuyển màu là tận dụng Gradient .

Bằng cách hiển thị một biến công khai thuộc loại này, nhà phát triển sử dụng Trình kiểm tra để khởi chạy Trình chỉnh sửa Gradient để thiết kế một dải màu chứa bất kỳ số lượng màu nào. Trình chỉnh sửa này cho phép bạn sử dụng bộ chọn màu thống nhất, tinh chỉnh vị trí của các phím màu / alpha và lưu / tải độ dốc.

nhập mô tả hình ảnh ở đây

Sau khi thiết kế, Gradient.Evaluate()phương thức sẽ chấp nhận một số float trong phạm vi 0-1 để trả về màu thích hợp.

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);
    }
}

Thật không may là API cho lập trình xây dựng một Gradient không phải là thanh lịch .


1
ColorBands có thể được sử dụng cho cùng một mục tiêu nhưng với nhiều tự do hơn về màu sắc
SteakOverflow 24/8/2016

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;
        }
    }
}

Vì vậy, đây là mã tôi đã sử dụng để lerp giữa ba màu của tôi, tôi hy vọng tôi sẽ được sử dụng cho bất kỳ ai quyết định tìm kiếm này.


0

Tôi cảm thấy như có thể có một giải pháp tốt hơn. Lý do duy nhất tôi thấy để lerp từ màu này sang màu khác là nếu bạn muốn liên tục thay đổi màu sắc ... http://en.wikipedia.org/wiki/Hue

Dưới đây là cách chuyển đổi HSV sang RGB: http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV

Với điều này, bạn có thể sử dụng màu HSV, chỉ cần thay đổi màu sắc, sau đó chuyển đổi sang RGB. Bên cạnh đó, với Color.Lerp, bạn có vấn đề không thống nhất. Nếu bạn chuyển từ màu cam sang màu vàng, sau đó sang màu xanh lục, bạn sẽ thấy rằng màu bắt đầu chuyển sang màu vàng rất nhanh sau đó bắt đầu chậm lại khi gần đến màu vàng, sau đó tăng tốc trở lại khi nó chuyển sang màu vàng và chuyển sang màu xanh lục. Vì vậy, nó sẽ làm chậm sự thay đổi màu sắc tại mọi điểm mà bạn đang theo dõi. Tôi nghĩ việc thay đổi màu sắc sẽ hiệu quả hơn nhiều - và về lâu dài, sẽ mang lại hiệu quả tốt hơn. :)


0

Làm thế nào về bạn viết phiên bản của riêng bạn, đòn bẩy Color.Lerp()nào?

Một phiên bản rất đơn giản có 3 màu và đặt cái thứ hai ở giữa có thể trông như thế này:

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);
}

0

Vì bạn không nói bạn muốn đổi màu thành gì, tôi sẽ đưa ra một ví dụ mơ hồ với màu được tạo trên phương thức.

Vấn đề là có một bộ sưu tập các màu và tổng thời lượng (như trong ví dụ tôi sẽ cung cấp) hoặc thời lượng giữa mỗi màu (tùy thuộc vào bạn).

Cá nhân tôi không nội suy mọi thứ trên Cập nhật mà tôi biết rằng tôi sẽ không liên tục nội suy (Máy ảnh là một ngoại lệ), vì vậy tôi sử dụng coroutines để xử lý việc đó.

Trong ví dụ này, tôi chia thời lượng cho trình kiểm tra cho số lượng màu, và sau đó tôi Lerp màu lặp thực tế cho màu lặp tiếp theo và thời lượng sẽ được chia theo thời gian trước đó. Đây là mẫu:

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.
    }
}

Hy vọng nó giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.