Apa cara terbaik untuk menggambar banyak pohon

8

Saya sedang menulis aplikasi yang membuat pulau acak ditanami pohon. Pohon-pohon saat ini adalah dua paha depan, bersilangan dan digambar dengan tekstur. Saya berencana untuk memiliki jerat yang lebih kompleks yang membentuk berbagai jenis tanaman, misalnya pohon palem, ek, rumput dll.

Pulau sampel

Masalah yang saya hadapi adalah karena teksturnya transparan saya harus menggambarnya dari belakang ke depan. Plan-b adalah panggilan menggunakan discard di frag shader, tetapi z-order memberikan hasil yang lebih baik:

uniform float uTreeAlpha;
uniform sampler2D uTexture;

varying vec2 vTexCoordOut;

void main (void)
{
  vec4 colour = texture2D(uTexture, vTexCoordOut);
  if (colour.a < 0.1) {
    discard;
  }
  gl_FragColor = vec4(colour.rgb, colour.a * uTreeAlpha);   
}

Masalah kedua adalah karena perubahan urutan tergantung pada kamera & lookat Saya tidak tahu cara yang efisien untuk menggambar mereka di OpenGL dalam satu panggilan.

Saat ini kode rendering saya terlihat seperti pseudocode ini:

if cameraChangedFromLastTime() then
  sortTreesBackToFront();
end
for i = 0 to trees.size() -1
  drawTree()
end

Di mana setiap drawTree () menetapkan beberapa seragam, mengatur tekstur, dan kemudian memanggil glDrawArrays (). Saya memiliki beberapa optimisasi untuk melewati pengaturan tekstur atau memperbarui tekstur coords jika pohon terakhir dan arus adalah sama, dan pengaturan beberapa seragam umum di luar loop, dan melewatkan pohon yang terlalu jauh tetapi pada dasarnya jika saya memiliki 3000 pohon saya pergi 3000 kali di loop.

Menggambar setiap pohon secara individu adalah pembunuh kinerja. Jika saya bisa menggambar mereka dalam satu panggilan, atau batch (sambil mempertahankan Z-order) saya mungkin akan melakukannya dalam 1/10 kali.

Jadi bagaimana saya melakukannya. Ingatlah bahwa pohon saya adalah penampung dan akhirnya saya akan memiliki:

  • Jerat yang berbeda untuk pohon yang berbeda
  • Skala dan sudut yang berbeda untuk pohon memberikan variasi yang lebih banyak
  • Tekstur yang berbeda untuk pohon yang berbeda, kemungkinan banyak tekstur diterapkan pada mesh (mis. Meninggalkan satu tekstur, trunk yang lain)
  • Semua pohon dicampur jadi tidak ada cara sederhana untuk menggambar satu jenis dan satu lagi
  • Beberapa bentuk animasi siklus sederhana (cabang-cabang terombang-ambing oleh angin)
  • Semua tekstur akan berada dalam satu atlas tunggal

Jadi apa pendekatan terbaik di sini? Apakah layak untuk membuat dalam satu pass? Jika saya menggunakan glDrawElements, membangun kembali indeks tetapi bukan simpul, dapatkah saya mencapai ini?

Locka
sumber
vterrain.org , lihat kolom kanan di bawah bagian tanaman untuk rendering tanaman, masing-masing kolom kiri, bagian rendering untuk tingkat detail / speedup rendering umum. Berhati-hatilah: sumber lebih banyak daftar makalah penelitian daripada tutorial
Exilyth
Saya tidak tahu banyak tentang hal ini. Tetapi periksa perangkat lunak VUE. Ini digunakan untuk membuat lanskap dengan pohon, gunung, atmosfer, dan banyak lagi, dalam 3d. Tapi saya tidak yakin apakah itu akan membantu dalam situasi Anda
user1981248

Jawaban:

3

Yang Anda inginkan adalah pemasangan perangkat keras . Catatan: Saya sudah melakukan ini di XNA (yaitu DirectX), tapi saya tidak tahu banyak tentang OpenGL. Saya yakin ada fitur yang sebanding. Pada dasarnya apa artinya mengikat bersama simpul dari model pohon Anda dengan aliran simpul lain yang membawa koordinat dunia untuk setiap contoh.

DrHeinous
sumber
1
Setara OpenGL akan menjadi ekstensi opengl.org/registry/specs/EXT/draw_instanced.txt . Tetapi, sebagai permulaan, tampilkan Daftar di OpenGL dan Vertex Array Objects lama / Objek Penyangga Vertex di OpenGL modern mungkin dilakukan. Dalam kedua kasus, sebuah objek / jala disimpan dalam Daftar / VAO / VBO, maka setiap instance digambar dengan transformasi yang berbeda. Menggunakan jerat statis, data dapat diunggah satu kali dan kemudian digunakan kembali. sol.gfxile.net/instancing.html memberikan gambaran singkat tentang berbagai metode.
Exilyth
Terima kasih, instancing adalah ide yang menarik. Namun saya tidak dapat menggunakan ekstensi draw_instanced karena saya menggunakan OpenGL ES 2.0 dan saya sedang mengerjakan sesuatu yang berfungsi pada semuanya. Saya berpikir mungkin bahwa saya dapat memuat berbagai jala pohon ke dalam VBO (berpotensi dengan model yang lebih jauh lebih jauh), urutkan, lalu menggambarnya dalam batch dari buffer indeks yang akan saya buat untuk setiap batch. Saya mungkin bisa menggambar 30 atau 40 sekaligus.
locka
2

Transparansi hanya perlu dipesan jika menggunakan blending non-aditif. Untuk satu ton papan iklan yang jauh, pencampuran itu tidak perlu (Anda tidak bisa melihatnya). Jadikan setidaknya yang lebih lanjut dengan transparansi cutout (alfa hanya 1 atau 0) dan Anda tidak perlu mengurutkannya.

Anda dapat menggunakan semacam sprite untuk membuat berbagai jenis pohon, dengan animasi yang dipanggang. Gambarlah jerat untuk pohon yang lebih dekat yang dapat Anda hidupkan dengan kesetiaan lebih berdasarkan angin atau apa pun yang Anda inginkan.

Sean Middleditch
sumber
Saya telah bereksperimen dengan menggunakan discard dan no sorting, tetapi hasilnya terlihat agak duff - pohon cenderung banyak tumpang tindih jadi jika tidak ada urutan yang konsisten, saya mendapatkan banyak pop di mana satu pohon berjalan di depan yang lain dan " memenangkan "pixel. Saya telah meninggalkan discard karena masih ada tabrakan sesekali (misalnya 2 pohon dengan jarak yang sama persis dari kamera) tetapi ini adalah fallback. Saya juga bereksperimen dengan papan iklan dan efeknya terlalu palsu terutama untuk flyover.
locka
Gunakan papan iklan yang lebih baik. Idealnya, miliki model pohon. Buat sprite papan reklame untuk sudut tampilan, dan gunakan sprite itu di tempat yang sudutnya cocok. Untuk guntingan, mereka bekerja paling baik di kejauhan, di mana Anda tidak dapat melihat perbedaannya. Saat Anda mendekat, Anda perlu menggunakan lebih banyak model yang dipadukan (mungkin beberapa paha depan per pohon), atau Anda dapat beralih ke transparansi layar-pintu.
Sean Middleditch
Pada titik tertentu, Anda perlu mengetahui keseimbangan penerimaan antara kualitas dan kecepatan. Anda tidak akan mendapatkan "sangat cepat" dan "sempurna" untuk adegan paling kompleks pada perangkat keras komoditas.
Sean Middleditch