Bagaimana cara saya memadukan 2 lightmaps untuk siklus siang / malam di Unity?

16

Sebelum saya mengatakan hal lain: Saya menggunakan dual lightmaps, artinya saya harus memadukan jarak dekat dan jauh.

Jadi saya sudah mengerjakan ini untuk sementara waktu sekarang, saya memiliki siklus sepanjang hari / malam yang diatur untuk penyaji dan pencahayaan, dan semuanya bekerja dengan baik dan tidak memproses intensif.

Satu-satunya masalah yang saya alami adalah mencari tahu bagaimana saya bisa menggabungkan dua lightmaps bersama, saya telah menemukan cara untuk mengganti lightmaps, tetapi masalahnya adalah yang tampak seperti tiba-tiba dan mengganggu pengalaman.

Saya telah melakukan penelitian selama berjam-jam tentang ini, mencoba semua jenis shader, pixel demi pixel, dan yang lainnya sia-sia. Pencampuran piksel demi piksel dalam C # ternyata merupakan proses yang sedikit intensif sesuai dengan keinginan saya, meskipun saya masih berusaha membersihkannya dan membuatnya berjalan lebih lancar. Shader tampak menjanjikan, tapi aku tidak bisa menemukan shader yang bisa memadukan dua lightmaps dengan benar.

Apakah ada yang punya petunjuk tentang bagaimana saya bisa mencapai ini? Saya hanya perlu semacam transisi yang mulus antara lightmap siang dan malam hari saya. Mungkin saya bisa overlay dua tekstur dan menggunakan saluran alpha? Atau semacam itu?

Timothy Williams
sumber
Jika Anda memiliki Pro, mungkin Anda dapat merender dua tekstur lightmap menjadi yang ketiga, dan kemudian menggunakan tekstur ketiga ini sebagai lightmap? Itu harus seperti pencampuran piksel, tetapi lebih cepat.
Nevermind
Saya punya Pro. Bagaimana cara saya merender dua tekstur lightmap bersama? Ini adalah petunjuk utama saya, tetapi saya sudah mencoba mencari tahu kode / proses untuk mencapainya.
Timothy Williams
Umm buat bahan yang memadukan dua tekstur, gunakan Graphics.Blit()untuk merendernya? Saya belum pernah melakukan ini, tetapi mencari di manual, itu harus bekerja.
Nevermind
Jadi buat bahan baru yang bisa memadukan dua tekstur ke output, terapkan Afar-1 dan Bfar-1, lalu gunakan tekstur keluar untuk variabel lightmap?
Timothy Williams
Ya, sesuatu seperti itu. Saya akan mengujinya, tetapi saya tidak memiliki akses ke versi Pro saat ini.
Nevermind

Jawaban:

3

Jadi saya baru-baru ini mencoba tangan saya di ini dan mengalami banyak masalah yang sama kalian miliki. Solusi tekstur render sedikit herring merah. Saya bisa menyelesaikannya dengan menggunakan manipulasi piksel multithreading pada utas terpisah.

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

Jadi biasanya orang akan menggunakan graphics.blit()dan meneruskan tekstur render ke mana pun ia perlu pergi, tetapi data lightmap tidak mendukung tekstur, mereka membutuhkan tekstur2ds. Langkah logis berikutnya adalah menyalin data ke tekstur2d dan kemudian memasukkannya ke data lightmap. Teknik ini merusak frame rate karena memperlambat GPU untuk mengirim data ke CPU, bukan hanya referensi ke data.

Solusinya adalah dengan tidak menggunakan GPU.

Transisi peta cahaya terjadi dalam periode waktu yang lama sehingga tidak perlu memperbarui peta cahaya setiap frame. Sebagai soal fakta, pemain mungkin tidak akan memperhatikan jika peta cahaya hanya diperbarui setiap 20-40 menit dalam waktu permainan.

Jadi yang Anda lakukan adalah Anda mengeluarkan tugas ke CPU pada utas terpisah untuk setiap peta cahaya.

Biasanya Unity tidak mendukung multithreading. Tapi tidak apa-apa, C # tidak. Orang ini melakukan pekerjaan yang fenomenal menjelaskan multithreading di Unity, jadi jika Anda belum pernah mendengarnya, atau tidak pernah tahu cara multithread di Unity, ini videonya:

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

Yang perlu Anda lakukan adalah membuat kelas utas pekerja yang memvariasikan salinan data piksel peta cahaya dalam larik Warna, lalu membuat fungsi campuran.

Lerp sederhana dari satu warna ke warna berikutnya akan berhasil.

Kemudian buat utas, mulai, dan ketika semua lightmaps selesai di utas terpisah Anda dapat menyalin data piksel kembali ke dalam tekstur data lightmap2d.

Saya memposting beberapa contoh kode di bawah ini. Ini jelas bukan versi yang sepenuhnya diimplementasikan, tetapi ini menunjukkan kepada Anda konsep utama membuat kelas, membuat utas, dan kemudian mengatur lightdata.

Hal-hal lain yang harus Anda lakukan adalah memanggil fungsi sesekali untuk memicu pembaruan lightmaps. Anda juga harus menyalin semua data piksel ke dalam kelas pekerja saat mulai atau pada waktu kompilasi. Semoga beruntung bagi siapa saja yang menemukan ini. Saya pikir op telah pindah dengan kehidupan mereka, tetapi saya tahu orang lain dengan masalah yang sama mungkin menemukan ini.

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;
}
Douglas Potesta
sumber
1

Ada shader skybox yang memadukan antara dua set tekstur skybox. Pikirkan siklus siang dan malam!

Jika Anda ingin membuat atau menghidupkan skybox dari skrip, gunakan skyboxmaterial.SetFloat("_Blend", yourBlend)untuk mengubah blending; juga dapat menggunakan SetTexturefungsi-fungsi material untuk mengatur atau mengubah tekstur.

Video tutorial tentang siklus siang / malam: http://www.youtube.com/watch?v=FTfv9JhkmIA

Contoh kode sebagai berikut:

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
}
JA Corbal
sumber
2
Pertanyaan yang diajukan tentang lightmaps, bukan skybox. Terima kasih atas tautannya, sepertinya ini akan bermanfaat bagi saya.
jhocking
0

Jika Anda tahu cara beralih, mengapa tidak melanjutkan dengan membuat sejumlah lightmaps transisi pada utas latar, dan kemudian mengaktifkan transisi ketika lightmaps siap?

Anda juga dapat melihat aset yang menarik di AssetStore: https://www.assetstore.unity3d.com/en/#!/content/5674

Saya kira itu termasuk lightmaps blending, walaupun saya tidak tahu caranya.

Tomekkie
sumber