Làm cách nào để trộn 2 ánh sáng cho chu kỳ ngày / đêm trong Unity?


16

Trước khi tôi nói bất cứ điều gì khác: Tôi đang sử dụng ánh sáng kép, nghĩa là tôi cần pha trộn cả gần và xa.

Vì vậy, bây giờ tôi đã làm việc này, tôi có một chu kỳ cả ngày / đêm được thiết lập cho trình kết xuất và ánh sáng, và mọi thứ đều hoạt động tốt và không cần xử lý chuyên sâu.

Vấn đề duy nhất tôi gặp phải là tìm hiểu làm thế nào tôi có thể pha trộn hai ánh sáng với nhau, tôi đã tìm ra cách chuyển đổi ánh sáng, nhưng vấn đề là trông có vẻ đột ngột và làm gián đoạn trải nghiệm.

Tôi đã thực hiện nhiều giờ nghiên cứu về vấn đề này, đã thử tất cả các loại bóng, pixel bằng cách trộn pixel và mọi thứ khác đều không có kết quả. Pha trộn pixel theo pixel trong C # hóa ra là một quá trình chuyên sâu theo sở thích của tôi, mặc dù tôi vẫn đang làm việc để làm sạch nó và làm cho nó chạy trơn tru hơn. Shader trông có vẻ đầy hứa hẹn, nhưng tôi không thể tìm thấy một shader nào có thể pha trộn đúng hai bóng đèn.

Có ai có bất kỳ dẫn đầu về cách tôi có thể thực hiện điều này? Tôi chỉ cần một số chuyển đổi suôn sẻ giữa ánh sáng ban ngày và ban đêm. Có lẽ tôi có thể phủ hai kết cấu và sử dụng kênh alpha? Hoặc điều tương tự?


Nếu bạn có Pro, có lẽ bạn có thể kết xuất hai kết cấu lightmap thành một phần ba, và sau đó sử dụng kết cấu thứ ba này làm lightmap? Điều đó sẽ giống như trộn pixel, nhưng ồ ạt nhanh hơn.
Không bao giờ bắt đầu

Tôi có Pro. Làm thế nào tôi có thể kết xuất hai kết cấu ánh sáng với nhau? Đây là hướng dẫn chính của tôi nhưng tôi đã cố gắng tìm ra mã / quy trình để hoàn thành nó.
Timothy Williams

Umm tạo ra một vật liệu pha trộn hai kết cấu, sử dụng Graphics.Blit()để kết xuất nó? Tôi chưa bao giờ làm điều này, nhưng nhìn vào hướng dẫn, nó sẽ hoạt động.
Không bao giờ bắt đầu

Vì vậy, tạo một vật liệu mới có thể pha trộn hai kết cấu cho một đầu ra, áp dụng Afar-1 và Bfar-1, sau đó sử dụng kết cấu đi cho biến lightmap?
Timothy Williams

Vâng, một cái gì đó như thế. Tôi sẽ kiểm tra nó, nhưng hiện tại tôi không có quyền truy cập vào phiên bản Pro.
Nevermind

Câu trả lời:


3

Vì vậy, gần đây tôi đã thử điều này và gặp rất nhiều vấn đề tương tự như các bạn có. Các giải pháp kết cấu kết xuất là một chút cá trích đỏ. Tôi đã có thể giải quyết nó bằng cách sử dụng thao tác pixel đa luồng trên một luồng riêng biệt.

https://www.youtube.com/watch?v=T_zpFk1mdCI

Vì vậy, thông thường người ta sẽ sử dụng graphics.blit()và chuyển kết cấu kết xuất đến bất cứ nơi nào nó cần đến, nhưng dữ liệu lightmap không hỗ trợ kết cấu, chúng yêu cầu texture2ds. Bước hợp lý tiếp theo sẽ là sao chép dữ liệu vào texture2d và sau đó đưa dữ liệu đó vào dữ liệu lightmap. Kỹ thuật này phá hỏng tốc độ khung hình vì nó đang cản trở GPU gửi dữ liệu tới CPU, thay vì chỉ tham chiếu đến dữ liệu.

Giải pháp là sau đó không sử dụng GPU.

Quá trình chuyển đổi bản đồ ánh sáng diễn ra trong một khoảng thời gian dài, do đó không nhất thiết phải cập nhật bản đồ ánh sáng mỗi khung hình. Thực tế, người chơi có thể sẽ không chú ý nếu bản đồ ánh sáng chỉ được cập nhật cứ sau 20 - 40 phút trong thời gian trò chơi.

Vì vậy, những gì bạn làm là bạn đưa ra nhiệm vụ cho CPU trên các luồng riêng biệt cho mỗi bản đồ ánh sáng.

Thông thường Unity không hỗ trợ đa luồng. Nhưng không sao, C # thì có. Anh chàng này thực hiện một công việc phi thường giải thích đa luồng trong Unity, vì vậy nếu bạn chưa bao giờ nghe về nó, hoặc chưa bao giờ biết cách đa luồng trong Unity thì đây là video:

https://www.youtube.com/watch?v=ja63QO1Imck

Tất cả những gì bạn cần làm là tạo một lớp luồng công nhân thay đổi các bản sao của dữ liệu pixel ánh sáng trong mảng Màu, sau đó tạo một hàm pha trộn.

Một lerp đơn giản từ màu này sang màu tiếp theo sẽ làm.

Sau đó tạo luồng, khởi động nó và khi tất cả các ánh sáng kết thúc trong các luồng riêng biệt, bạn có thể sao chép dữ liệu pixel trở lại vào data2d của lightmap data2d.

Tôi đã đăng một số mã ví dụ dưới đây. Đây chắc chắn không phải là phiên bản được triển khai đầy đủ, nhưng nó cho bạn thấy các khái niệm chính về việc tạo lớp, tạo luồng và sau đó thiết lập lightdata.

Những việc khác bạn sẽ phải làm là thường xuyên gọi một chức năng để kích hoạt cập nhật các bản đồ ánh sáng. Ngoài ra, bạn phải sao chép tất cả dữ liệu pixel vào lớp worker khi bắt đầu hoặc tại thời điểm biên dịch. Chúc may mắn cho bất cứ ai tìm thấy điều này. Tôi nghĩ rằng op đã tiếp tục cuộc sống của họ, nhưng tôi biết những người khác có vấn đề tương tự có thể vấp phải điều này.

public class work
{
    Color[] fromPixels;
    Color[] toPixels;

    public float LerpValue = 0;
    public bool Finished = false;
    public Color[] mixedPixels;

    public work(Color[] FromPix, Color[] ToPix)
    {
        fromPixels= FromPix;
        toPixels= ToPix;
        Finished = false;
        mixedPixels = new Color[FromPix.Length];
    }
    public void DoWork()
    {
        for (int x = 0; x < fromPixels.Length; x++)
        {
            mixedPixels[x] = Color.Lerp(fromPixels[x], toPixels[x], LerpValue);
        }
        Finished = true;
    }
}

IEnumerator LightMapSet()
{
    Thread workerThread = new Thread(someworker.DoWork);
    someworker.LerpValue = lerpValue;
    workerThread.Start();
    yield return new WaitUntil(() => someworker.Finished);
    mixedMap.SetPixels(someworker.mixedPixels);
    mixedMap.Apply(true);
    LightmapData someLightmapData;
    someLightmapData.lightmapColor = mixedMap;
    lightDatas = { someLightmapData};
    LightmapSettings.lightmaps = lightDatas;
}

1

Có một shader skybox pha trộn giữa hai bộ kết cấu skybox. Hãy suy nghĩ chu kỳ ngày đêm!

Nếu bạn muốn xây dựng hoặc tạo hiệu ứng skybox từ tập lệnh, hãy sử dụng skyboxmaterial.SetFloat("_Blend", yourBlend)để thay đổi sự pha trộn; cũng có thể sử dụng SetTexturecác chức năng vật liệu để thiết lập hoặc thay đổi kết cấu.

Video hướng dẫn về chu kỳ ngày / đêm: http://www.youtube.com/watch?v=FTfv9JhkmIA

Mã ví dụ như sau:

Shader "RenderFX/Skybox Blended" {
Properties {
    _Tint ("Tint Color", Color) = (.5, .5, .5, .5)
    _Blend ("Blend", Range(0.0,1.0)) = 0.5
    _FrontTex ("Front (+Z)", 2D) = "white" {}
    _BackTex ("Back (-Z)", 2D) = "white" {}
    _LeftTex ("Left (+X)", 2D) = "white" {}
    _RightTex ("Right (-X)", 2D) = "white" {}
    _UpTex ("Up (+Y)", 2D) = "white" {}
    _DownTex ("Down (-Y)", 2D) = "white" {}
    _FrontTex2("2 Front (+Z)", 2D) = "white" {}
    _BackTex2("2 Back (-Z)", 2D) = "white" {}
    _LeftTex2("2 Left (+X)", 2D) = "white" {}
    _RightTex2("2 Right (-X)", 2D) = "white" {}
    _UpTex2("2 Up (+Y)", 2D) = "white" {}
    _DownTex2("2 Down (-Y)", 2D) = "white" {}
}

SubShader {
    Tags { "Queue" = "Background" }
    Cull Off
    Fog { Mode Off }
    Lighting Off        
    Color [_Tint]
    Pass {
        SetTexture [_FrontTex] { combine texture }
        SetTexture [_FrontTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_FrontTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_BackTex] { combine texture }
        SetTexture [_BackTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_BackTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_LeftTex] { combine texture }
        SetTexture [_LeftTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_LeftTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_RightTex] { combine texture }
        SetTexture [_RightTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_RightTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_UpTex] { combine texture }
        SetTexture [_UpTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_UpTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_DownTex] { combine texture }
        SetTexture [_DownTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_DownTex2] { combine previous +- primary, previous * primary }
    }
}

Fallback "RenderFX/Skybox", 1
}

2
Câu hỏi hỏi về lightmap, không phải skybox. Cảm ơn về liên kết mặc dù, điều này có vẻ như nó sẽ hữu ích cho tôi.
jhocking

0

Nếu bạn biết cách chuyển đổi, tại sao không tiếp tục với việc tạo một số ánh sáng chuyển tiếp trên luồng nền, sau đó kích hoạt chuyển đổi khi ánh sáng sẵn sàng?

Bạn cũng có thể xem một tài sản thú vị trên AssetStore: https://www.assetstore.unity3d.com/en/#!/content/5674

Tôi đoán nó bao gồm các pha trộn ánh sáng, mặc dù tôi không biết làm thế nào.

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.