Menggunakan Unity3D di aplikasi asli iOS / Android untuk memodelkan pencahayaan ruang terbuka

gambar

Unity3D adalah platform pengembangan game 3D dan 2D yang terkenal yang telah mendapatkan popularitas di seluruh dunia. Pada saat yang sama, kemampuannya tidak terbatas pada pengembangan hanya aplikasi game, tetapi cocok untuk digunakan di area lain yang membutuhkan pembuatan aplikasi lintas platform untuk bekerja dengan grafik. Pada artikel ini kita akan berbicara tentang pengalaman menggunakan Unity3D untuk mengembangkan sistem untuk menghitung pencahayaan ruang terbuka.

Perusahaan tempat kami bekerja sama adalah perusahaan pencahayaan internasional BOOS LIGHTING GROUP . Untuk memperluas daya tarik produk mereka dan menyederhanakan interaksi dengan pelanggan, perlu untuk mengembangkan aplikasi yang memungkinkan Anda untuk mensimulasikan secara visual lokasi perangkat pencahayaan, serta melakukan perhitungan pencahayaan dan menampilkan informasi teknis yang diperlukan dalam laporan. Diasumsikan bahwa aplikasi diluncurkan pada iPad atau tablet Android oleh klien potensial atau perwakilan penjualan dan memungkinkan klien untuk segera mendapatkan ide tentang kemungkinan instalasi pencahayaan.

Pekerjaan tersebut dilakukan secara bertahap berdasarkan spesifikasi yang dikembangkan dari persyaratan dan konsultasi dari perusahaan BOOS LIGHTING GROUP mengenai masalah proyek.

Secara umum, aplikasi ini adalah editor yang memungkinkan Anda untuk menambah dan mengedit elemen pencahayaan, jalan, elemen dekoratif, melakukan perhitungan rekayasa pencahayaan adegan, menampilkan laporan dalam pdf. Setiap elemen memiliki set parameter sendiri untuk mengedit dan subtipe yang memengaruhi tampilan dan perhitungannya.

  • Ada beberapa jenis tiang lampu, dengan berbagai jenis perlengkapan fixture, sudut kemiringan lampu dan panjang ekstensi. Untuk jenis luminer tertentu, penyesuaian individual dimungkinkan dengan arah pencahayaan.

    gambar
  • Jalan dapat berupa bagian linier, elemen busur, area, cincin. Untuk setiap elemen, dimensi, posisi, tipe tata letak, lapisan dapat disesuaikan.

    gambar
  • Elemen dekoratif - mobil, pohon, semak-semak, rambu-rambu jalan

Semua elemen adegan dapat diputar dan dipindahkan. Tindakan standar untuk mengembalikan atau mencoba kembali juga didukung. Pengaturan umum proyek memungkinkan Anda untuk mengatur tekstur dorg, permukaan bumi, menampilkan parameter tambahan. Adegan ditampilkan dalam mode 2D / 3D. Dan saat menghitung iluminasi di permukaan, peta iluminasi permukaan dalam warna fiktif ditampilkan.

gambar


Jika memungkinkan, seluruh UI harus dilakukan dengan alat iOS / Android asli.
Persyaratan teknis utama untuk aplikasi ini adalah untuk dapat menghitung pencahayaan panggung sesuai dengan spesifikasi teknis perlengkapan. Yang juga diperlukan adalah kemampuan setiap fixture untuk menampilkan dan melihat pola radiasi (kurva intensitas cahaya) dalam mode 3D / 2D.

Pemilihan platform


Untuk mengimplementasikan proyek, kami memilih Unity karena lebih nyaman bagi kami untuk mengimplementasikan fungsionalitas yang diperlukan. Secara umum, perusahaan kami memiliki pengalaman bekerja dengan mesin dan platform 3D lainnya (OpenSceneGraph, Ogre3D, LibGdx) dan secara teknis mereka semua dapat mengatasi tugas yang diperlukan, tetapi kali ini pilihannya jatuh pada Unity, yang membuatnya lebih mudah untuk mengelola adegan selama pengembangan dan debug. dalam proses kerja.

Kesulitan utama


Kami tidak akan membahas seluk-beluk pengembangan seluruh aplikasi, karena secara teknis fungsi untuk menampilkan dan mengedit adegan cukup standar. Secara alami, ada kesulitan dengan mekanisme pengeditan objek tertentu, menambah dan menghapusnya, serta menyimpan rantai perintah untuk kemungkinan pengulangan dan pembatalan tindakan.
Kami hanya ingin memikirkan fitur-fitur sistem yang terkait dengan bekerja dengan UI asli, menghasilkan laporan pdf dan bekerja dengan fotometri dan perhitungan pencahayaan.

Bekerja dengan UI asli


Dalam kebanyakan kasus, Unity berinteraksi dengan fungsi asli sistem menggunakan sistem plug-in, yang memungkinkan Anda untuk menanamkan fungsionalitas yang diinginkan dalam aplikasi. Namun, dalam kasus kami situasinya agak berlawanan. Kami harus memiliki UI lengkap yang ditampilkan di atas jendela Unity.

gambar


Untungnya, Unity dapat mengekspor proyek yang dapat digunakan sebagai dasar untuk aplikasi asli. Kesulitan utama dalam kasus ini adalah bagaimana mengintegrasikan UI tambahan ke dalam proyek yang dihasilkan. Juga, sama pentingnya bahwa ketika merakit proyek Unity, format dan lokasi file-nya dibentuk oleh Unity dan ditulis ulang sebagian, yang membatasi kemungkinan memodifikasi proyek.

Saat mengembangkan aplikasi iOS, kami menggunakan mekanisme yang diusulkan dalam artikel . Selama pengembangan, Unity 5.5 digunakan dan saat ini, apa yang ditunjukkan di dalamnya mungkin kehilangan relevansi. Saat merakit proyek android, tidak ada masalah tambahan, dengan pengecualian bahwa Unity menimpa file manifes dan file sumber daya setiap kali.
Masalah tambahan adalah bahwa Unity hanya dapat bekerja dalam satu jendela. Pada saat yang sama, kami perlu memastikan Unity untuk menampilkan seluruh adegan, dan ketika membuka jendela pengaturan, model 3D dari tubuh fotometrik lampu harus ditampilkan. Untuk mencapai ini, saya harus menggunakan "retas" dan menggunakan objek UIView yang sama di jendela yang berbeda.

Untuk mengirim pesan, kami menggunakan fungsionalitas standar yang ditawarkan oleh Unity. Artinya, semua pesan dalam format json dan ditransmisikan dalam garis sederhana. Ini tidak memberlakukan batasan pada kinerja karena ukuran pesan mencapai maksimum 100 karakter, dan frekuensi mereka ditentukan oleh kecepatan bekerja dengan program. Pada saat yang sama, dalam aplikasi yang lebih menuntut, masuk akal untuk membuat penangan pesan Anda sendiri seperti yang disajikan pada Haber di sini dan di sini .

Perhitungan pencahayaan


Semua sumber cahaya yang digunakan dalam aplikasi dikirimkan dalam format IES standar, yang menjelaskan distribusi cahaya dalam arah yang berbeda ( spesifikasi ). Format ini banyak digunakan dalam sistem CAD profesional dan editor 3D. Ini adalah file teks yang menunjukkan intensitas cahaya di berbagai arah dan informasi meta tambahan yang menunjukkan jenis, intensitas total sumber, sumbu dan bidang simetri. Mengingat simetri perlengkapan, file ies bisa sangat kecil. Misalnya, dalam kasus simetri aksial, cukup untuk menunjukkan pelacakan cahaya hanya dalam satu bidang.

Contoh file IES sederhana
IESNA91[TEST] Simple demo intensity distribution [MANUFAC] Lightscape Technologies, Inc. TILT=NONE 1 -1 1 8 1 1 2 0.0 0.0 0.0 1.0 1.0 0.0 0.0 5.0 10.0 20.0 30.0 45.0 65.0 90.0 0.0 1000.0 1100.0 1300.0 1150.0 930.0 650.0 350.0 0.0 


Untuk menampilkan pola radiasi, dua jenis tampilan digunakan:

  • Kurva intensitas cahaya (KSS) adalah grafik dua dimensi yang menunjukkan intensitas cahaya di salah satu bidang utama tergantung pada arah. Untuk kenyamanan, grafik ini dapat direpresentasikan dalam sistem koordinat kutub dan Cartesian.

    gambar
  • Tubuh fotometrik - gambar tiga dimensi intensitas cahaya dalam arah yang berbeda

    gambar

Modul perhitungan


Untuk menghitung pencahayaan, pelanggan memiliki modul C ++ sendiri yang digunakan dalam produk-produk lain dari perusahaan, dan oleh karena itu diperlukan untuk mengintegrasikannya ke dalam proyek Unity. Urutan koneksi modul berbeda dari platform yang digunakan.

  • Pada platform iOS, Unitu dapat langsung memanggil fungsi C, jadi cukup salin kode sumber modul langsung ke proyek dan tambahkan kelas untuk interaksinya dengan Unity. Kelas dapat disimpan baik secara langsung di proyek iOS, dan di folder plugins, yang secara otomatis disalin ketika proyek diekspor ke Xcode. Contoh memanggil fungsi C ++ adalah sebagai berikut:

     [DllImport("__Internal")] public static extern void calculateLight([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Light[] lights, int size, ref CalculationResult result); 
  • Pada platform Android, modul C ++ harus dikompilasi ke pustaka yang terpisah. Ini dapat dilakukan secara langsung dengan menambahkan sumber C ++ ke proyek dan menyiapkan gradle untuk membuatnya di perpustakaan.
  • Juga, untuk debugging dan menguji bagian Unity, pengembangan dilakukan pada mesin windows, jadi itu perlu untuk menghubungkan kode sumber modul di Windows juga. Ini dilakukan mirip dengan proyek android, hanya dalam kasus ini file yang diunduh dikumpulkan di perpustakaan dll dan terhubung ke proyek.

Tampilan Peta Cahaya


Atas permintaan pelanggan, hasil perhitungan pencahayaan harus ditampilkan di permukaan tempat kejadian. Di permukaan jalan, perlu menggunakan warna fiktif dengan tampilan skala untuk mencocokkan warna dan intensitas cahaya, dan pada permukaan lainnya, hanya menampilkan kecerahannya sudah cukup.

gambar


Seperti disebutkan sebelumnya, seluruh perhitungan dilakukan oleh plug-in C ++ dimana data tentang sumber warna ditransmisikan. Hasil perhitungannya adalah susunan intensitas cahaya dua dimensi di seluruh permukaan adegan dengan detail yang diberikan.

Peta penyinaran yang dihasilkan dianalisis untuk nilai minimum dan maksimum yang digunakan tekstur gradien satu dimensi (GradientRamp). Menggunakan tekstur ini, intensitas cahaya dikonversi ke warna fiktif langsung di shader fragmen. Pada saat yang sama, shader yang sama digunakan untuk permukaan jalan dan permukaan bumi yang berbeda, dan mengganti mode pencahayaan disediakan menggunakan shader " multi-kompilasi ".

Pembuatan file pdf


Sesuai dengan persyaratan teknis, laporan harus dibuat untuk pengguna yang berisi informasi tentang pemandangan umum (dimensi, gambar, parameter pencahayaan) dan informasi tentang setiap jenis luminer yang digunakan, yang menunjukkan posisi, arah karakteristik, serta diagram KCC dan tampilan badan fotometrik.
Karena laporan itu akan ditampilkan di iOS dan Android, itu perlu untuk menghasilkan laporannya langsung di modul Unity, dan kemudian menampilkannya menggunakan alat asli standar.

gambar

Untuk membangun pdf, pustaka iTextSharp dipilih yang memenuhi persyaratan kami. Membuat laporan di dalamnya tidak terlalu sulit dan terdiri dari membuat blok teks, tabel, gambar langsung dari kode. Namun, selama pengembangan, kami dihadapkan dengan banyak nuansa, solusi yang kadang-kadang membutuhkan upaya yang cukup besar. Masalah utamanya adalah peluncuran pembuatan laporan di utas latar belakang.

Jika saat pengujian pada mesin desktop, pembuatan pdf berada di urutan beberapa detik, maka saat pengujian pada iPad mini 3 kali ini dengan mudah mencapai 1-3 menit. Secara alami, pembuatan laporan perlu ditransfer ke utas terpisah, untuk menghindari masalah dengan penangguhan antarmuka. Dalam kasus umum, ini bukan masalah, tetapi ini bukan kasus ketika menggunakan Unity, di mana ia secara eksplisit dilarang untuk menggunakan Unity API dari luar utas utama. Pada saat yang sama, untuk laporan kami membutuhkan, paling tidak, untuk membuat CSS dan gambar pemandangan, yang harus dilakukan hanya dari aliran utama.

Jadi, untuk membangun laporan, kita perlu menjalankan tugas dalam urutan tertentu, dan pada saat yang sama, beberapa dari mereka dapat bekerja di utas latar belakang, dan sebagian harus diluncurkan di yang utama.

Sekilas, untuk mengatasi masalah ini, Anda dapat mencoba menggunakan mekanisme standar dan menjalankan setiap operasi dalam coroutine terpisah. Namun, ini tidak menyelamatkan kita dari masalah pengereman antarmuka. Seperti yang Anda ketahui, coroutine bekerja di utas utama dan tidak cocok untuk operasi yang lambat. Pada saat yang sama, ketika membuat laporan, banyak operasi memerlukan waktu yang signifikan, dan karena itu coroutine tidak dapat membantu menyelesaikan masalah kita.

UniRx


Solusi lain adalah dengan membagi kode menjadi bagian yang perlu bekerja di utas utama dan bagian yang dapat dijalankan di utas terpisah. Dalam hal ini, misalnya, gambar dapat dibangun menggunakan mekanisme coroutine, dan kemudian mereka dapat tertanam dalam laporan dalam aliran yang terpisah. Namun, dalam hal ini, perlu untuk menyimpan hasil antara di suatu tempat, yang memberlakukan batasan tambahan pada jumlah memori yang digunakan atau ruang kosong pada perangkat.

Dalam aplikasi kami, kami lebih memilih untuk langsung dan menjalankan tugas secara berurutan di utas utama atau di utas latar. Satu-satunya masalah adalah bagaimana mengatur peluncuran tugas-tugas tersebut agar tidak terjebak dalam kekacauan ini dan menyinkronkan operasi dengan benar.
Bantuan signifikan dalam memecahkan masalah ini dibawa oleh penggunaan Rx, perwujudannya sebagai aset UniRx gratis, yang sudah dijelaskan secara rinci di sini dan di sini di hub .

Penggunaannya telah sangat menyederhanakan interaksi antara utas dan contoh di bawah ini menunjukkan Anda dapat menjalankan beberapa metode dalam urutan yang ketat, tetapi dalam utas berbeda

Contoh kode
 var initializer = Observable.FromCoroutine(initMethod); var heavyMethod1 = Observable.Start(() => doHardWork()); var mainThread1 = Observable.FromCoroutine(renderImage); var heavyMethod2 = Observable.Start(() => doHardWork2()); initializer.SelectMany(heavyMethod1) .SelectMany(mainThread1) .SelectMany(heavyMethod2) .ObserveOnMainThread() .Subscribe((x) => done()) .AddTo(this); 

Dalam contoh ini, metode doHardWork () akan dijalankan secara berurutan di utas latar belakang. Setelah selesai, renderImage () akan diluncurkan di utas utama, dan setelah itu doHardWork2 () akan dieksekusi lagi di utas latar belakang.

Perlu juga dicatat bahwa selama analisis pembuatan laporan untuk kinerja ditemukan bahwa bagian paling lambat adalah implementasi gambar dalam laporan. Pencarian di Internet menunjukkan bahwa kami bukan satu-satunya yang menghadapi masalah ini, tetapi tidak ada solusi yang cocok untuk kami. Kami harus sedikit mengurangi kualitas gambar ke tingkat yang dapat diterima, yang memberikan peningkatan kecepatan sebesar 20-40%.

Jadi, dalam aplikasi yang kami buat, adalah mungkin untuk berhasil memperkenalkan mesin grafis Unity ke dalam aplikasi iOS / Android asli. Ini berbeda dari pendekatan tradisional ketika Unity adalah bagian utama dari aplikasi dan membahas sifat spesifik sistem melalui sistem plug-in. Pada saat yang sama, pendekatan kami dapat berguna jika Anda perlu mengembangkan antarmuka asli yang rumit di mana Anda ingin menanamkan grafik 3D non-sepele.

Source: https://habr.com/ru/post/id417779/


All Articles