Unity'de gündüz / gece döngüsü için 2 ışık haritasını nasıl harmanlayabilirim?


16

Başka bir şey söylemeden önce: Çift ışık haritalarını kullanıyorum, yani hem yakın hem de uzak bir karışımı karıştırmam gerekiyor.

Bu yüzden bir süredir üzerinde çalışıyorum, renderers ve aydınlatma için ayarlanmış bir gündüz / gece döngüm var ve her şey iyi çalışıyor ve yoğun işlem görmüyor.

Yaşadığım tek sorun, iki ışık haritasını birlikte nasıl harmanlayabileceğimi bulmaktır, ışık haritalarını nasıl değiştireceğimizi anladım, ancak sorun biraz ani ve deneyimi kesintiye uğratıyor.

Bu konuda saatlerce araştırma yaptım, her türlü gölgelendiriciyi, piksel karışımlı pikselleri ve diğer her şeyi denedim. C # 'da piksel karışımlı piksel harmanlama, beğenmem için biraz işlem yoğun olduğu ortaya çıktı, ancak hala temizlemeye ve daha sorunsuz çalışmasına çalışıyorum. Gölgelendiriciler umut vericiydi, ancak iki ışık haritasını düzgün bir şekilde harmanlayabilecek bir gölgelendirici bulamadım.

Herkes bunu nasıl başarabilirim herhangi bir ipucu var mı? Sadece gündüz ve gece ışık haritam arasında bir tür yumuşak geçişe ihtiyacım var. Belki iki dokuyu kaplayabilir ve alfa kanalı kullanabilir miyim? Ya da böyle bir şey?


Pro'nuz varsa, belki iki ışık haritası dokusunu üçte bir hale getirebilir ve daha sonra bu üçüncü dokuyu ışık haritası olarak kullanabilirsiniz? Bu, piksel karıştırma gibi olmalı, ancak çok daha hızlı olmalıdır.
Nevermind

Pro'm var. İki ışık haritası dokusunu bir araya getirmeye nasıl devam edebilirim? Bu benim ana öncüydü ama bunu başarmak için kodu / süreci anlamaya çalışıyorum.
Timothy Williams

Umm, iki dokuyu harmanlayan bir malzeme yaratıyor, Graphics.Blit()onu oluşturmak için mi kullanıyorsunuz ? Bunu hiç yapmadım, ancak kılavuza baktığımda işe yarayacak.
Nevermind

Çıktıya iki dokuyu karıştırabilecek yeni bir malzeme oluşturun, Afar-1 ve Bfar-1'i uygulayın, ardından ışık haritası değişkeni için giden dokuyu kullanın?
Timothy Williams

Evet, böyle bir şey. Test ederdim, ama şu anda Pro sürümüne erişimim yok.
Nevermind

Yanıtlar:


3

Bu yüzden son zamanlarda elimi bu konuda denedim ve sahip olduğunuz birçok sorunla karşılaştım. Render doku çözümü biraz kırmızı ringa balığıdır. Ayrı bir iş parçacığındaki multithreading piksel manipülasyon kullanarak çözmeyi başardı.

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

Bu nedenle, normalde graphics.blit()render dokusunu gitmesi gereken her yere kullanır ve geçirir, ancak ışık haritası verileri dokuları desteklemez, texture2ds gerektirir. Bir sonraki mantıksal adım, verilerin bir texture2d dosyasına kopyalanması ve ardından ışık haritası verilerine beslenmesi olacaktır. Bu teknik kare hızlarını bozar, çünkü GPU'yu yalnızca verilere referans olmaktan ziyade CPU'ya veri göndermek için durdurur.

Çözüm GPU'yu kullanmamaktır.

Işık haritası geçişleri uzun bir süre boyunca gerçekleşir, bu nedenle ışık haritasını her karede güncellemek önemli değildir. Aslında, oyuncular ışık haritalarının oyun süresinde sadece 20-40 dakikada bir güncellenip güncellenmediğini fark etmeyeceklerdir.

Yaptığınız şey, görevi her ışık haritası için ayrı iş parçacıkları üzerinde CPU'ya vermektir.

Normalde Unity, çoklu iş parçacığı kullanımını desteklemez. Ama sorun değil, C #. Bu adam Unity'de çoklu iş parçacığını açıklayan olağanüstü bir iş yapar, bu yüzden daha önce hiç duymadıysanız veya Unity'de çok iş parçacığının nasıl kullanılacağını hiç bilmiyorsanız bu video:

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

Tek yapmanız gereken Renk dizilerindeki ışık haritası piksel verilerinin kopyalarını değiştiren bir işçi iş parçacığı sınıfı yapmak ve ardından bir karışım işlevi oluşturmaktır.

Bir renkten diğerine basit bir lerp yapacaktır.

Ardından iş parçacığını oluşturun, başlatın ve tüm ışık eşlemeleri ayrı iş parçacıklarında tamamlandığında piksel verilerini tekrar ışık haritası veri texture2d'sine kopyalayabilirsiniz.

Aşağıda bazı örnek kodlar yayınladım. Kesinlikle tam olarak uygulanmış sürüm değildir, ancak sınıfın yapılması, iş parçacığının oluşturulması ve ardından ışık verilerinin ayarlanmasıyla ilgili temel kavramları gösterir.

Yapmanız gereken diğer şeyler, ışık haritalarının güncellenmesini tetiklemek için sık sık bir işlev çağırmaktır. Ayrıca, tüm piksel verilerini başlangıçta veya derleme zamanında işçi sınıfına kopyalamanız gerekir. Bunu bulan herkese iyi şanslar. Operasyonun hayatları boyunca ilerlediğini düşünüyorum, ancak benzer sorunları olan diğer insanların bununla karşılaşabileceğini biliyorum.

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

İki set skybox dokusu arasında karışan bir skybox gölgelendirici var. Gündüz ve gece döngüsünü düşünün!

Skybox'ı komut dosyasından oluşturmak veya canlandırmak istiyorsanız skyboxmaterial.SetFloat("_Blend", yourBlend), karıştırmayı değiştirmek için kullanın ; ayrıca SetTexturedokuları ayarlamak veya değiştirmek için malzeme işlevlerini kullanabilir .

Gündüz / gece döngüsü hakkında video eğitimi: http://www.youtube.com/watch?v=FTfv9JhkmIA

Örnek kod aşağıdaki gibidir:

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
Soru, skybox değil, ışık haritaları hakkında sordu. Bağlantı için teşekkürler, bu benim için yararlı olacak gibi görünüyor.
jhocking

0

Nasıl geçiş yapacağınızı biliyorsanız, neden arka plan iş parçacığında bir dizi geçiş ışık haritası oluşturmaya devam etmiyorsunuz ve ardından ışık haritaları hazır olduğunda geçişleri etkinleştirmiyorsunuz?

AssetStore'da ilginç bir öğeye de bakabilirsiniz: https://www.assetstore.unity3d.com/en/#!/content/5674

Sanırım nasıl olduğunu bilmesem de ışık haritalarının harmanlanmasını içeriyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.