Adakah yang punya algoritma untuk membuat prosedur sphere dengan la
jumlah garis lintang, lo
jumlah garis bujur, dan jari-jari r
? Saya membutuhkannya untuk bekerja dengan Unity, jadi posisi vertex perlu didefinisikan dan kemudian, segitiga didefinisikan melalui indeks ( info lebih lanjut ).
EDIT
Saya berhasil membuat kode bekerja dalam kesatuan. Tapi saya pikir saya mungkin telah melakukan sesuatu yang salah. Ketika saya mengaktifkannya detailLevel
, Yang perlu dilakukan adalah menambahkan lebih banyak simpul dan poligon tanpa memindahkannya. Apakah saya lupa sesuatu?
EDIT 2
Saya mencoba menskalakan mesh di sepanjang normalnya. Ini yang saya dapat. Saya pikir saya kehilangan sesuatu. Apakah saya seharusnya hanya skala normals tertentu?
unity
procedural-generation
3d-meshes
Daniel Pendergast
sumber
sumber
vertices[i] = normalize(vertices[i])
. Kebetulan, ini juga memberi Anda yang baru, normals yang benar, sehingga Anda harus melakukannyanormals[i] = vertices[i]
sesudahnya.Jawaban:
Untuk mendapatkan sesuatu seperti ini:
Buat icosahedron (solid 20-sisi biasa) dan bagi wajah-wajah untuk mendapatkan bola (lihat kode di bawah).
Idenya pada dasarnya:
Bagi setiap wajah menjadi empat wajah berukuran sama. Setiap kali Anda melakukan ini, itu akan melipatgandakan jumlah wajah dalam model.
i0
,,i1
dani2
merupakan simpul dari segitiga asli. (Sebenarnya, indeks ke buffer vertex, tapi itu topik lain).m01
adalah titik tengah dari tepi(i0,i1)
, m12 adalah titik tengah dari tepi(i1,12)
, danm02
, jelas, adalah titik tengah dari tepi(i0,i2)
.Setiap kali Anda membagi wajah, pastikan Anda tidak membuat simpul rangkap. Setiap titik tengah akan dibagikan oleh satu sumber wajah lainnya (karena ujungnya dibagi di antara wajah). Kode di bawah ini menjelaskan hal itu dengan memelihara kamus titik tengah bernama yang telah dibuat, dan mengembalikan indeks titik tengah yang sebelumnya dibuat saat tersedia daripada membuat yang baru.
Ulangi sampai Anda mencapai jumlah wajah yang diinginkan untuk kubus Anda.
Setelah selesai, normalkan semua simpul untuk menghaluskan permukaan. Jika Anda tidak melakukan ini, Anda hanya akan mendapatkan icosahedron beresolusi tinggi daripada bola.
Voila! Kamu sudah selesai. Ubah vektor dan indeks buffer yang dihasilkan menjadi
VertexBuffer
danIndexBuffer
, dan menggambar denganDevice.DrawIndexedPrimitives()
.Inilah yang akan Anda gunakan di kelas "Sphere" Anda untuk membuat model (tipe data XNA dan C #, tetapi harus cukup jelas):
Dan
GeometryProvider
kelasnyasumber
int
array? Dan apa fungsinya.Select(i => i + vertices.Count)
?.Select(i => i + vertices.Count)
sekali tidak bekerja untuk saya. Apakah ini fitur XNA saja?Mari kita perhatikan definisi parametrik dari bola:
di mana theta dan phi adalah dua sudut yang bertambah, yang akan kita sebut sebagai
var t
danvar u
dan Rx, Ry dan Rz adalah jari-jari independen (jari-jari) di ketiga arah kartesius, yang, dalam kasus bola, akan didefinisikan sebagai satu tunggal jari-jarivar rad
.Mari kita perhatikan fakta bahwa
...
simbol menunjukkan iterasi yang mengisyaratkan penggunaan loop. Konsepstacks
danrows
adalah "berapa kali Anda akan mengulanginya". Karena setiap iterasi menambahkan nilai t atau u, semakin banyak iterasi, semakin kecil nilainya, oleh karena itu semakin tepat kelengkungan bola.The 'lingkup menggambar' prasyarat fungsi adalah untuk memiliki parameter yang diberikan sebagai berikut:
int latitudes, int longitudes, float radius
. Kondisi posting (output) adalah untuk kembali, atau menerapkan simpul yang dihitung. Bergantung pada bagaimana Anda ingin menggunakan ini, fungsi tersebut dapat mengembalikan arrayvector3
(vektor tiga dimensi) atau, jika Anda menggunakan semacam OpenGL sederhana, sebelum versi 2.0, Anda mungkin ingin menerapkan simpul ke konteks secara langsung.NB Menerapkan simpul dalam openGL memanggil fungsi berikut
glVertex3f(x, y, z)
. Dalam kasus di mana kami akan menyimpan simpul, kami akan menambahkan yang baruvector3(x, y, z)
untuk penyimpanan mudah.Juga, cara Anda meminta sistem garis lintang dan bujur untuk bekerja membutuhkan penyesuaian pada definisi bola (pada dasarnya beralih z dan y), tetapi ini hanya menunjukkan bahwa definisi tersebut sangat mudah ditempa, dan bahwa Anda bebas untuk beralih di sekitar x, y dan z parameter untuk mengubah arah di mana bola ditarik (di mana lintang dan bujur).
Sekarang mari kita lihat bagaimana kita akan melakukan garis lintang dan bujur. Lintang diwakili oleh variabel
u
, mereka beralih dari 0 hingga 2 to radian (360 derajat). Karena itu kami dapat mengkode iterasinya seperti:Sekarang bujur diwakili oleh variabel
t
dan beralih dari 0 ke π (180 derajat). oleh karena itu kode berikut terlihat mirip dengan yang sebelumnya:(Perhatikan bahwa loop termasuk dalam kondisi terminal, karena interval untuk integrasi parametrik adalah dari 0 hingga 2π Termasuk . Anda akan mendapatkan bola parsial jika kondisi Anda tidak inklusif.)
Sekarang, mengikuti definisi sederhana dari sphere kita dapat memperoleh definisi variabel sebagai berikut (asumsikan
float rad = radius;
):Satu lagi peringatan penting! Dalam kebanyakan kasus Anda akan menggunakan beberapa bentuk OpenGL, dan bahkan jika tidak, Anda mungkin masih perlu melakukan ini. Objek dalam tiga dimensi perlu beberapa simpul untuk didefinisikan. Ini umumnya dicapai dengan menyediakan simpul berikutnya yang dapat dihitung.
Hanya seperti pada gambar di atas koordinat yang berbeda
x+∂
dany+∂
, kita dapat dengan mudah menghasilkan tiga simpul lainnya untuk penggunaan yang diinginkan. Verteks lainnya adalah (menganggapfloat rad = radius;
):Akhirnya, di sini adalah fungsi kerja penuh yang akan mengembalikan semua simpul bola, dan yang kedua menunjukkan implementasi OpenGL yang berfungsi dari kode (ini adalah sintaks gaya-C dan bukan JavaScript, ini harus bekerja dengan semua bahasa gaya-C, termasuk C # saat menggunakan Unity).
Kode OpenGL:
PS Anda mungkin telah memperhatikan pernyataan ini
rad = radius;
. Ini memungkinkan jari-jari untuk dimodifikasi dalam loop, berdasarkan lokasi atau sudut. Ini berarti Anda dapat menerapkan noise ke bola untuk mengeraskannya, membuatnya terlihat lebih alami jika efek yang diinginkan adalah seperti planet. Misalnyafloat rad = radius * noise[x][y][z];
Claude-Henry.
sumber
rad
. Sekarang Anda membuat satu kaki segitiga, dan menyiratkan bahwa sisi miring dari segitiga tersebut jugarad
. Ini secara efektif memberi Anda jari-jarirad * sqrt(2)
.Saya membuat sesuatu seperti ini beberapa waktu lalu untuk membuat bulatan kubus, untuk kesenangan dan sains. Itu tidak terlalu sulit. Pada dasarnya, Anda mengambil fungsi yang membuat lingkaran simpul, kemudian melangkah melalui kenaikan tinggi yang ingin Anda buat lingkaran pada setiap ketinggian pada radius yang diperlukan untuk membuat bola. Di sini saya telah memodifikasi kodenya menjadi bukan untuk kubus:
Sekarang kode ini hanya akan membuat titik untuk garis lintang. Namun, Anda hampir dapat menggunakan kode yang sama untuk membuat garis bujur. Kecuali Anda harus memutar di antara setiap iterasi dan membuat lingkaran penuh di setiap iterasi
degreeStep
.Maaf ini bukan jawaban lengkap atau khusus untuk Unity, tapi semoga ini akan membantu Anda memulai.
sumber
Tidak bisakah Anda memulai dengan bentuk sederhana, bisa berupa kotak dengan jarak r dari pusat ke sudut. Untuk membuat bola yang lebih detail, bagi semua poligon dan pindahkan simpul ke jarak dari pusat, buat vektor melewati posisinya saat ini.
Terus ulangi sampai cukup bulat untuk selera Anda.
sumber
Apakah Anda benar-benar membutuhkan geometri 3D atau hanya bentuknya?
Anda bisa membuat bola 'palsu' menggunakan quad tunggal. Letakkan lingkaran di atasnya dan beri warna dengan benar. Ini memiliki keuntungan bahwa resolusi yang dibutuhkan akan tepat terlepas dari jarak ke kamera atau resolusi.
Ada tutorial di sini .
sumber
di sini adalah beberapa kode untuk sejumlah titik yang sama spasi dari bola, seperti kulit jeruk yang melilitkan garis titik-titik di sekitar bola dalam spiral. setelah itu, bagaimana Anda bergabung dengan simpul terserah Anda. Anda dapat menggunakan titik-titik tetangga dalam lingkaran sebagai 2 dari setiap segitiga dan kemudian menemukan yang ketiga akan menjadi satu putaran proporsional di sekitar bola lebih tinggi atau lebih rendah ke bawah ... Anda juga dapat melakukan segitiga dengan loop dan tetangga terdekat di atasnya, apakah seseorang tahu cara yang lebih baik?
};
sumber
Meskipun David benar-benar benar dalam jawabannya, saya ingin menawarkan perspektif yang berbeda.
Untuk tugas saya untuk menghasilkan konten prosedural, saya melihat (antara lain) icosahedron versus lebih banyak bidang yang dibagi secara tradisional. Lihatlah bola-bola yang dihasilkan secara prosedural ini:
Keduanya terlihat seperti bola yang benar-benar valid, bukan? Baiklah, mari kita lihat wireframes mereka:
Wow, apa yang terjadi di sana? Versi gambar rangka dari bola kedua sangat padat sehingga terlihat bertekstur! Saya akan memberitahu Anda rahasia: versi kedua adalah icosahedron. Itu adalah bola yang hampir sempurna, tetapi harganya mahal.
Sphere 1 menggunakan 31 subdivisi pada sumbu x dan 31 subdivisi pada sumbu z, dengan total 3.844 permukaan.
Sphere 2 menggunakan 5 subdivisi rekursif, dengan total 109.220 wajah.
Tapi oke, itu tidak terlalu adil. Mari turunkan kualitasnya secara signifikan:
Sphere 1 menggunakan 5 subdivisi pada sumbu x dan 5 subdivisi pada sumbu z, dengan total 100 wajah.
Sphere 2 menggunakan 0 subdivisi rekursif, dengan total 100 wajah.
Mereka menggunakan jumlah wajah yang sama, tetapi menurut saya, bola di sebelah kiri terlihat lebih baik. Itu terlihat kurang kental dan lebih bulat. Mari kita lihat berapa banyak wajah yang kita hasilkan dengan kedua metode ini.
Icosahedron:
Lingkungan terbagi:
Seperti yang Anda lihat, icosahedron meningkat di wajah pada tingkat eksponensial, ke kekuatan ketiga! Itu karena untuk setiap segitiga, kita harus membaginya menjadi tiga segitiga baru.
Yang benar adalah: Anda tidak perlu presisi icosahedron akan memberi Anda. Karena mereka berdua menyembunyikan masalah yang jauh lebih sulit: tekstur pesawat 2D pada bola 3D. Seperti apa bentuk puncaknya:
Di kiri atas, Anda dapat melihat tekstur yang digunakan. Secara kebetulan, ini juga dihasilkan secara prosedural. (Hei, itu kursus generasi prosedural, kan?)
Terlihat mengerikan, bukan? Nah, ini sama baiknya dengan yang akan didapat. Saya mendapat nilai tertinggi untuk pemetaan tekstur saya, karena kebanyakan orang bahkan tidak melakukannya dengan benar.
Jadi tolong, pertimbangkan untuk menggunakan cosinus dan sinus untuk menghasilkan bola. Ini menghasilkan wajah yang jauh lebih sedikit untuk jumlah detail yang sama.
sumber
N
komponen akan memberi AndaN*N
segitiga baru, yang kuadratik, persis seperti apa yang Anda lakukan dengan bola-UV.Script di bawah ini akan membuat Icosahedron dengan n Poligon ... basis 12. Ini juga akan membagi poligon menjadi jerat yang terpisah, dan menghitung total duplikat-duplikat dan poligon.
Saya tidak dapat menemukan yang serupa sehingga saya membuat ini. Cukup lampirkan skrip ke GameObject, dan atur subdivisi di Editor. Bekerja pada modifikasi noise selanjutnya.
sumber