Three.js: Mengadopsi beberapa fitur ES6

Dibuat pada 16 Apr 2015  ·  74Komentar  ·  Sumber: mrdoob/three.js

ES6 akan datang, dengan browser dan alat sekarang dengan cepat mendapatkan dukungan. Saya pikir THREE.js bisa mendapatkan keuntungan besar dari beberapa fitur baru yang dibawa oleh ES6.

Untuk bersenang-senang dan untuk mendorong perdebatan seputar kemungkinan migrasi proyek, saya telah membuat masalah ini dan membuat beberapa contoh kode.

Fitur yang ditunjukkan dalam contoh di bawah ini:

  • Parameter default
  • Kata kunci let cakupan blok
  • Iterator + For..Of
  • Kelas
  • Fungsi Panah
  • Generator
  • Modul

Contoh Kelas

import Object3D from '../core/Object3D';
import Geometry from '../core/Geometry';
import MeshBasicMaterial from '../materials/MeshBasicMaterial';

class Mesh extends Object3D {
    constructor(
        geometry = new Geometry(),
        material = new MeshBasicMaterial({color: Math.random() * 0xffffff}
    ) {
        super();

        this.geometry = geometry;
        this.material = material;

        this.updateMorphTargets();
    }
}

export default Mesh;

Contoh Generator Traversal

class Object3D {
    constructor() {
        ...
    }

    traverse(callback) {
        callback(this);

        for (let object of this.children) {
            object.traverse(callback);
        }
    },

    *traversalGenerator() {
        this.traverse(object => yield object);
    }

    ...
}

Pembangkit yang digunakan:

for (let object of scene.traversalGenerator()) {
    if (object.name === 'Blah') {
        break;
    }
}

Catatan: Saya belum menguji semua ini

Suggestion

Komentar yang paling membantu

https://github.com/mrdoob/three.js/commit/1017a5432eede4487436d6d34807fda24b506088

Oke, saya pikir kita bisa mulai dengan let dan const di src/ .

@DefinitelyMungkin Apakah ini sesuatu yang ingin Anda bantu?

Semua 74 komentar

Mungkin sedikit lebih awal? Dukungan tidak secara konsisten lintas browser yang bagus: http://kangax.github.io/compat-table/es6/

let tidak diekspos di FF dan tidak dalam 100% situasi di Chrome dan IE.
generators tidak tersedia di IE
class hanya ada di Chrome, pratinjau teknis IE12(Spartan) untuk Win10 dan FF39 yang dua di atas versi saat ini.
import belum tersedia di mana pun
super hanya tersedia di IE12, bukan IE11, Chrome atau FF
arrow functions tidak di IE11 atau Chrome

Juga generator dan for-of adalah pembunuh pengoptimalan untuk Chrome

Imo juga terlalu dini hanya untuk sintaks yang terlihat lebih menarik. Dapat diperdebatkan ketika sesuatu dalam daftar akan memberikan peningkatan kinerja yang nyata atau manfaat keterbacaan kode. Mungkin seseorang yang mengetahui basis kode dan fitur ES6 dapat mengomentarinya.

Saya sedikit terlambat ke pesta ES6. Ini terlihat seperti bahasa yang berbeda bagi saya. Saya secara teratur berkontribusi ke Three.js tetapi jika terlihat seperti cuplikan di atas, saya tidak tahu apakah saya akan melanjutkan. Saya hanya tidak memiliki kesabaran untuk mempelajari versi JavaScript yang tampak berbeda dan berfungsi berbeda, yang pada dasarnya melakukan hal yang sama seperti 'fungsi baru ()' dan 'object.prototype', tetapi mungkin lebih lambat.

Apakah ini yang diminta komunitas web dari komite bahasa ES6? Saya telah mengkode selama 20 tahun dan kata 'kelas' tidak muncul di mana pun di proyek saya (juga tidak akan pernah jika saya mau). Terus terang, JavaScript mulai terlihat seperti JAVA...(script). :-\

Saya bersama @benaadams dan @jonnenauha ; terlalu dini, dan mungkin memperlambat kode jika Chrome dan Firefox tidak terlalu mengoptimalkan versi bahasa baru ini seperti mereka sudah mengoptimalkan JavaScript di bawah tenda (V8, dll...).

:+1:

@erichlof Yah, saya sebenarnya paling menunggu kelas ES6 dan dukungan modul. Saat ini saya menggunakan AMD untuk aplikasi saya. Proyek JS utama yang saya kerjakan adalah ~10k baris dengan ratusan "kelas" dan AMD adalah penyelamat. Baik selama pengembangan maupun dalam memproduksi build. Imo proyek besar atau bahkan lebih kecil perlu memiliki semacam sistem modul dan cara untuk menyatakan apa yang mereka andalkan. Itu terlalu berbulu untuk dikelola begitu Anda memiliki struktur proyek yang kompleks. Seharusnya tidak dibiarkan untuk diprogram untuk mencari tahu dalam urutan apa untuk menempatkan 25x <script> tag. Ini konyol sekali Anda memiliki jumlah file seperti three.js. Sebagian besar proyek menyelesaikan ini dengan membuat satu file js besar (seperti three.js) dan kemudian ada folder ekstra/pembantu acak tempat Anda dapat memasukkan hal-hal lain. Ini agak membatasi dan saya harus menyertakan build ~500kb (diperkecil) untuk mendapatkan ~semuanya di bawah matahari.

Pada satu titik saya pikir tiga menambahkan dukungan AMD, tapi itu hanya blok kode kecil yang mendeteksi jika AMD digunakan dan memanggil fungsi alih-alih mendeklarasikan window secara efektif.TIGA. Saya tidak tahu betapa sulitnya saat ini untuk membuat build khusus yang akan menjatuhkan fungsionalitas yang tidak saya perlukan dan menambahkan hal-hal yang saya inginkan di luar inti dan mengoptimalkannya ke satu file kerja yang memuat semuanya secara berurutan.

Anda mungkin tidak memiliki "kelas" dalam proyek Anda, tetapi jika Anda menggunakan object.prototype (seperti three.js berat), itu secara efektif adalah hal yang sama, apakah Anda setuju? Kami suka menyatukan objek dan memberi mereka tujuan. Kode lain kemudian ingin menggunakan objek tersebut dan cara deklaratif yang bersih untuk mengimpornya.

Semua yang saya katakan kelas dan modul ES6 akan menjadi tambahan yang bagus juga untuk three.js untuk memberikan lebih banyak struktur dan modularitas untuk build. Ini terlalu dini karena afaik tidak ada browser yang mendukung mis. modul belum. Orang lain mungkin mengatakan harus mulai menggunakannya dan menggunakan babel dll. dan menghasilkan build yang sesuai dengan ES5, saya tidak yakin apakah itu ide yang bagus, tapi siapa yang tahu. Ini membuat pengembangan menjadi lebih sulit, Anda harus memulai pembangunan secara otomatis saat Anda menyimpan file, dan proses debug mungkin menjadi lebih rumit juga. Untuk hal-hal ini saja saya cenderung menganggap transpiler ini tidak layak atm.

PS Bukan kata-kata kasar terhadap three.js, hanya mengatakan mungkin ada manfaat di ES6 untuk proyek-proyek seperti three.js begitu dukungan browser ada :) dan sebagian besar gula sintaksisnya lebih banyak daripada menjadikannya bahasa yang sama sekali baru. Itu hanya akan memiliki lebih banyak barang.

Fitur lain yang mungkin bermanfaat untuk three.js adalah WeakMap dan mungkin WeakSet . Saya tidak yakin tentang implikasinya tetapi sepertinya ini dapat digunakan untuk melacak berbagai hal tanpa membuat GC melakukan tugasnya jika "pemilik" tidak lagi memegang referensi. Ada banyak status seperti ini di three.js dan menggunakannya secara internal mungkin membuat perbedaan. Tampaknya bagi saya ini agak mirip dengan ptrs bersama/lemah di C++ untuk mendeklarasikan kepemilikan.

Kandidat yang baik mungkin seperti https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLight.js#L12 di mana ini bisa menjadi ref yang lemah dan akan otomatis dihapus jika targetnya adalah dihapus dari tempat kejadian dan dikumpulkan. Tapi saya kira Anda tidak bisa tetap bergantung pada koleksi, tetapi tetap harus membatalkannya begitu target dihapus dari tempat kejadian.

Siapa tahu, saya akan menunggu para ahli untuk menulis beberapa posting blog bagaimana semua fitur ini dapat bermanfaat bagi aplikasi secara umum :)

Hai @jonnenauha ,

Ya, saya setuju bahwa fitur baru seperti 'impor' dan 'ekspor' akan berguna, terutama dalam hal modularitas. Saya percaya itulah arah yang @cobalast dan @kumavis coba lakukan dengan membuat THREE.js lebih modular dan dapat dikelola untuk pembuatan khusus dan pemeliharaan basis kode. Saya siap untuk modul dan penggunaan kembali objek dan fungsi, terutama ketika kami memiliki format perpustakaan besar seperti THREE.js.

Namun saya tidak berpikir bahwa kita memerlukan tambahan sintaksis gula kelas, super, let, for, of, arrow function, dll. ketika pada dasarnya kita mendapatkan fungsi yang sama di JavaScript sekarang yang telah digunakan selama beberapa dekade dan memiliki sudah banyak traksi. Saya mungkin kuno tetapi saya bersama Douglas Crockford ketika dia mengatakan JavaScript sudah menjadi bahasa berorientasi objek (artinya fungsi = objek = warga kelas satu), tetapi bukan 'klas' - jadi kita tidak perlu khawatir dengan kelas shoehorning ke dalam JavaScript. Itu dirancang dengan pendekatan yang berbeda - sebuah pendekatan yang awalnya membuat saya terkejut (berasal dari pemrograman C/C++ pada tahun 1990-an), tetapi pendekatan yang semakin saya setujui setiap kali saya duduk untuk membuat kode atau mencoba memecahkan arsitektur kode masalah.

Alih-alih perubahan sintaksis ke THREE.js, saya lebih suka melihat migrasi ke fitur seperti antarmuka pemrograman SIMD yang baru. Saya pikir SEMUA kode Matematika TIGA (terutama Vector3 dan Matrix4) bisa sangat diuntungkan dari ini. Berikut ini tautan video (lihat 22:51 dalam kode waktu):
https://youtu.be/CbMXkbqQBcQ?t=1371
Ketika fitur ini mendarat di browser utama, setiap pengguna THREE.js akan melihat peningkatan yang nyata dalam framerate mereka sebagai hasilnya.

Maaf jika posting saya sebelumnya terdengar seperti kata-kata kasar, saya hanya suka THREE.js tampilannya sekarang - saya dapat dengan mudah memilih bagian acak darinya dan tahu apa yang terjadi, dari mana asalnya, dan apa yang digunakannya. :)

@erichlof @jonnenauha Saya merasa terdorong untuk menunjukkan bahwa kelas es6 hanyalah gula dan mereka secara internal menggunakan mekanisme prototipe untuk mengimplementasikan semuanya saat runtime.

Saya cukup optimis bahwa fitur es6 tidak akan memengaruhi kinerja komputasi. Modul es6 mungkin memengaruhi waktu buka saat modul tersebut akhirnya diimplementasikan oleh mesin, karena Anda mengambil banyak file kecil daripada satu file besar. HTTP/2 mungkin menjadikannya bukan masalah. Bagaimanapun, jika kita menggunakan modul es6, kita dapat menggunakan browserify untuk membuat bundel seperti yang selalu kita lakukan.

Saya pribadi menggunakan sintaks es6 dalam basis kode sebanyak mungkin, karena itu akan membuat kode lebih ringkas dan mengurangi kesalahan. Saya pikir banyak orang cenderung menyalahgunakan rantai prototipe dan menggunakannya secara tidak benar. Saya tidak punya contoh yang baik sekalipun.

Saya juga berpikir duduk dan menunggu es6 diimplementasikan di mesin adalah ide yang salah. Transpiler tersedia sekarang yang menghasilkan hasil bagus yang berjalan di browser saat ini. Saya pikir manfaat melakukan ini sangat besar, jadi kita harus tidak sabar dan segera mulai mengerjakannya.

Saya tidak berpikir memindahkan kode secara manual adalah ide yang bagus. Seperti yang dikatakan Doug McIlroy, penemu pipa unix dan umumnya seorang setengah dewa:
"Gunakan alat daripada bantuan tidak terampil untuk meringankan tugas pemrograman, bahkan jika Anda harus memutar untuk membangun alat dan berharap untuk membuang beberapa dari mereka setelah Anda selesai menggunakannya."

Saya akan mendorong siapa pun yang tertarik dengan es6 untuk terjun dan membantu berkontribusi pada repo ini: https://github.com/5to6/5to6

Saya tidak setuju untuk mengonversi seluruh perpustakaan ke subset javascript yang berbeda. Seperti biasa kita harus mendiskusikan apa yang mungkin dan apa pro dan kontranya. Karena kinerja akan berbeda antar versi.

Misalnya, peta lemah adalah sesuatu yang akan menjadi keuntungan besar bagi penyaji untuk menangani status objek. Kerugian terbesarnya adalah polyfill yang lemah dan dukungan browser yang sangat sedikit dan karakteristik kinerja yang tidak diketahui. (Sudah lama sejak saya menyelidiki ini, jadi kemungkinan ini berubah)

Dan kita seharusnya tidak hanya melihat es6. Misalnya, ams.js akan sangat bagus sebagai teknologi yang menjalankan perender perangkat lunak. Untuk info lebih lanjut, http://stackoverflow.com/questions/18427810/three-and-asmjs/18439786#18439786.

Dan kita tidak boleh lupa bahwa sebagian besar kontributor terutama berkontribusi karena javascript sudah familiar dan es6 belum untuk sebagian besar.

@gero3 Itu adalah poin bagus yang tidak saya pikirkan. Jika kita berbicara tentang optimasi mikro maka saya 100% setuju dengan Anda. Saya tidak ingin memanfaatkan fitur tersebut tanpa dukungan browser.

Sebagian besar yang saya bicarakan di atas adalah menggunakan gula sintaksis yang memiliki semantik identik dengan fitur es5 yang ada, sehingga dapat dibangun dengan transpiler tanpa terlalu memengaruhi kinerja.

MEMPERBARUI:
Mungkin tidak ada yang peduli, tapi saya berubah pikiran. Saya percaya kita tidak harus menggunakan kelas. Saya masih berpikir modul es6 adalah ide yang bagus.

Saya benar-benar mendukung kelas. Saya mendapatkan semua hal luar biasa yang dapat dilakukan oleh prototipe objek dalam JavaScript. Namun, di THREE.js (dan banyak proyek OS modern lainnya) kami menggunakan pewarisan prototipe untuk mensimulasikan kelas, jadi mengapa tidak memiliki sintaksis yang bagus untuk mengikutinya, dan menyingkirkan hal-hal peretasan seperti:

THREE.Object3D.call( this );

dan

THREE.Scene.prototype = Object.create( THREE.Object3D.prototype );

Segera setelah kelas didukung di Chrome dan Firefox yang stabil, saya tidak keberatan mempertimbangkan untuk memperbarui kode 😊

Kelas @mrdoob didukung di Chrome 42 yang stabil hari ini dan pengiriman Firefox 39 pada bulan Juni FYI 😊

Safari di iOS tampaknya yang menyeret saat ini...

Kelasnya luar biasa dan begitu juga fitur ES7 lainnya. Kami menggunakannya di salah satu proyek kami, tetapi kami harus memperkenalkan kompiler silang (babel.js) karena kami harus berjalan di semua browser -- Chrome, Firefox, IE, dan Safari.

Ada transformasi browserify untuk menjalankan babel.js (babelify), jadi itu akan bekerja dengan baik dengan upaya saya.

Hanya karena penasaran, apakah beberapa di antaranya sudah mulai dikerjakan? :)

tidak karena kita masih belum tahu implikasinya pada kecepatan ini.

Pemahaman saya adalah ES6 sebagian besar tidak berkinerja baik dan oleh karena itu tidak untuk produksi sampai diterapkan ke browser. Dengan itu, proyek atau modul yang lebih baru harus menyesuaikan kenyamanan ini hari ini tetapi kinerja harus diperhitungkan dalam keputusan ini.

Saya setuju dengan @erichlof imo implementasi yang paling berguna adalah SIMD (https://github.com/tc39/ecmascript_simd), bahkan dengan menggunakan polyfill. Sepertinya pengguna akan mendapat manfaat paling banyak dari itu.

Di mana SIMD cocok di ThreeJS? Saya pikir ThreeJS sudah menurunkan semua perhitungan signifikan ke GPU. Meskipun saya dapat memahami menggunakannya di kelas Vector, hanya ada sedikit matematika yang benar-benar dilakukan di ThreeJS, tetapi sebagian besar vektor tersebut hanya diangkut ke GPU.

Saya berbicara dari pengalaman ketika saya menerapkan ekstensi SSE2/SSE4 sebelumnya dan saya menemukan bahwa manfaatnya cepat berlalu di sebagian besar kasus - satu-satunya kasus nyata adalah manfaatnya adalah ketika saya memiliki array besar di mana saya ingin melakukan hal yang sama operasi.

Hai @bhouston ,
Apakah hal yang sama berlaku untuk operasi Matriks? Ketika saya memikirkan SIMD, saya berpikir bahwa operasi matriks 4 X 4 akan paling diuntungkan. Dan seperti yang kita semua tahu, matriks digunakan setiap bingkai animasi di Three.js di sisi JavaScript/CPU, apa pun kerumitan aplikasinya.

Jika orang-orang Babylon.js tidak keberatan, berikut adalah petunjuk tentang cara memulai semua ini:
https://github.com/BabylonJS/Babylon.js/blob/master/src/Math/babylon.math.js#L2030 -L2093

Saya pikir satu kelipatan matriks jika Anda harus mengonversi formatnya kemungkinan akan kalah. Jika Anda memiliki matriks Anda selalu dalam format SIMD, maka mungkin bermanfaat.

Namun demikian, perkalian Matriks seringkali tidak optimal karena Anda harus mengalikan kolom dengan baris, yang memerlukan operasi pengurutan ulang.

Saya telah menemukan bahwa sebagian besar upaya pengoptimalan SIMD (tidak termasuk array besar dengan operasi homogen) tidak sepadan dengan usaha, tetapi saya setuju dengan orang lain yang melakukan tolok ukur untuk mencari tahu.

Kode yang dihasilkan juga sulit untuk di-debug dan dipelihara.

Salah satu strategi yang dapat berhasil adalah membuat semua vektor dan matriks menggunakan tata letak memori yang kompatibel dengan SIMD sebagai representasi asli mereka -- itulah yang menurut saya Quake 3 di perpustakaan matematikanya. Tetapi kemudian Anda harus menggunakan 4 float untuk tipe vec2 dan vec3 untuk efisiensi, tetapi kemudian menjadi masalah ketika Anda ingin mengunggah ke GPU karena sekarang Anda memiliki float tambahan.

Saya mengerti maksud Anda, terima kasih atas wawasan dan keahlian Anda. Terkesan dengan presentasi SIMD.js beberapa waktu lalu, dan memasukkannya ke dalam three.js dan mempertahankannya adalah dua hal yang berbeda menurut saya. Akan menarik seperti yang Anda katakan untuk melakukan beberapa perbandingan kinerja. Mungkin perpustakaan fisika seperti Cannon.js dan Oimo.js , yang digunakan bersama dengan three.js akan mendapatkan lebih banyak manfaat dari SIMD?

@bhouston Ahh ok itu masuk akal, beberapa tolok ukur akan cukup menarik.

@erichlof jika Anda tertarik, saya sudah memulai cabang, https://github.com/Globegitter/three.js/tree/include-SIMD , di mana saya mulai mengganti Vector3 dengan SIMD. Ini masih merupakan WIP yang berat dan waktu saya terbatas jadi kami akan sejauh mana saya dapatkan. Juga, menggunakan Firefox nightly terbaru Anda dapat menjalankan kode ini tanpa polyfill (di mana implementasi asli tampaknya ~20 kali lebih cepat dibandingkan dengan polyfill: https://blog.mozilla.org/javascript/2015/03/10/state -of-simd-js-performance-in-firefox/).

@erichlof @jonnenauha Saya merasa terdorong untuk menunjukkan bahwa kelas es6 hanyalah gula dan mereka secara internal menggunakan mekanisme prototipe untuk mengimplementasikan semuanya saat runtime.
Saya cukup optimis bahwa fitur es6 tidak akan memengaruhi kinerja komputasi.

Anda mungkin sedikit cepat menyimpulkan bahwa: Memang ada jalur kode yang berbeda untuk ES6 di setiap mesin JS dalam implementasi objek JS (yang cukup kompleks).

Modul es6 mungkin memengaruhi waktu buka saat modul tersebut akhirnya diimplementasikan oleh mesin, karena Anda mengambil banyak file kecil daripada satu file besar. HTTP/2 mungkin menjadikannya bukan masalah.

Klien mungkin masih ingin menggunakan kompresi tingkat JS seluruh aplikasi untuk memotong bandwidth jaringan dan melindungi kekayaan intelektual mereka.

Membuat Kompilator Penutupan memahami Three.js akan memungkinkan untuk mengompilasi ke ES6 dan untuk melihat kapan waktu yang tepat untuk beralih, ditambah banyak manfaat tambahan. Saya pikir ini adalah di mana upaya semacam ini harus pergi untuk saat ini ...

Namun demikian, perkalian matriks [SIMD] seringkali tidak optimal karena Anda harus mengalikan kolom dengan baris, yang memerlukan operasi pengurutan ulang.

Set instruksi SIMD sering memiliki instruksi "kalikan dengan skalar dan tambahkan", untuk mengimplementasikan perkalian matriks seperti ini:

for i : 0..3:
    dst.col[i] = lhs.col[i] * rhs.co[i][0] // multiply vector by scalar
    for j : 1..3:
        dst.col[i] += lhs.col[i] * rhs_col[i][j] // multiply vector by scalar & add

Perkalian matriks sebenarnya hanya menerapkan transformasi ke vektor kolom dari operan sisi kanan. Sekarang, transformasi dapat dilihat sebagai sekumpulan produk titik (cara membingungkan yang biasanya kita gunakan dengan pena dan kertas), atau sebagai kombinasi linier dari vektor sumbu dari ruang tujuan = vektor kolom dari sisi kiri operan.

@Globegitter Wow itu awal yang luar biasa! Saya akan mendapatkan Firefox Nightly sehingga saya dapat bereksperimen dengan cabang baru juga!

@Globegitter Saya suka ketika seseorang terus maju dan melakukan sesuatu ketika mereka mempercayainya. Kode menyelesaikan sudut pandang yang berbeda lebih cepat daripada diskusi.

di mana implementasi asli tampaknya ~20 kali lebih cepat dibandingkan dengan polyfill

Akan tertarik untuk melihat juga seberapa lambat polyfill dibandingkan dengan non-SIMD

Saya akan mendapatkan Firefox Nightly sehingga saya dapat bereksperimen dengan cabang baru juga!

Seharusnya juga dapat mencobanya di Edge dengan mengaktifkan eksperimental dan asm.js di about:flags

@Globegitter Saya pikir editor Anda mengubah spasi putih yang mengarah ke perbedaan yang sangat buruk: https://github.com/Globegitter/three.js/commit/d835ca3a22eed4ed4603534773ae55c29d5a8026

Saya perhatikan Anda menjadikan tipe SIMD sebagai mobil samping:

https://github.com/Globegitter/three.js/commit/8ed9c1d351a3b0587a1f05051922d271d79f642d

Bolehkah saya menyarankan agar Anda mengubah Vector3 x, y, z menjadi pengambil/penyetel dan hanya menyimpan float32x4? Saya pikir pendekatan seperti itu mungkin jauh lebih mudah untuk diterapkan dengan sedikit perubahan.

Saya tidak yakin cara terbaik untuk mendefinisikan properti tetapi mrdoob melakukan sesuatu seperti itu di sini:

https://github.com/mrdoob/three.js/blob/5c7e0df9b100ba40cdcaaf530196290e16c34858/examples/js/wip/proxies/ProxyVector4.js#L18

Memiliki SIMD sebagai jenis penyimpanan utama di belakang jenis matematika kemungkinan yang paling efisien, tidak diperlukan konversi tambahan. Berikut adalah perpustakaan matematika Bullet Physics SSE jika Anda memerlukan panduan untuk operasi vektor/matriks standar:

https://code.google.com/p/bullet/source/browse/trunk/src/vectormath/sse/

@bhouston , terima kasih atas catatan ini. Saya agak langsung masuk ke sana untuk melihat seberapa jauh saya akan mendapatkan dalam beberapa jam tanpa harus bekerja banyak dengan tiga dan SIMD sebelumnya (kami menggunakannya di sebagian besar proyek kami). Jadi umpan balik dari seseorang yang tahu tiga ini sangat dihargai. Dan ya harus mematikannya di editor saya.

@tschw terima kasih atas catatan tentang matematika matriks/vektor! Anda benar itu lebih baik.

@Globegitter Berikut adalah contoh penyetel/pengambil yang lebih baik pada prototipe objek: https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js#L83

Beberapa sen untuk bekerja pada ES2015 (terutama di node)

  • ada tempat mesin Javascript (mis. V8) perlu bermain mengejar ketinggalan mengoptimalkan fitur ES6
  • dari kode pengalaman saya seperti let x = 1, y = 2 akan menonaktifkan v8 meskipun saya berharap v8 akan mendukungnya pada akhirnya
  • kode transpiled ke ES5 dapat dijalankan lebih lambat daripada kode ES6 (itulah sebabnya saya lebih suka menggunakan hanya fitur ES6 yang didukung di> node 4, itu hampir semuanya kecuali sistem ekspor impor)
  • Peta dan Set adalah kemenangan kinerja
  • Kelasnya bagus
  • Menggunakan Babel dapat menyulitkan alur kerja Anda, mungkin tidak sepadan dengan usaha jika menggunakan ES6 murni untuk gula sintaksis

Setengah tahun yang lalu saya mengonversi beberapa fungsi Three.js (penggandaan matriks 4x4, Vector4 dll) ke SIMD dan Anda dapat mencobanya. Pada titik tertentu itu berfungsi sebagai bookmarklet tetapi sekarang mungkin memerlukan penyegaran untuk bekerja dengan Tiga versi terbaru

  • Firefox Nightly mendukung SIMD asli di luar kotak
  • Chrome dengan flag --js-flags="--harmony-simd" mendukung JS polyfill dari SIMD sehingga akan lebih lambat daripada versi non-simd. Setidaknya Anda dapat memeriksa apakah itu berhasil dan bereksperimen!

Peningkatan kinerja 350% adalah KEBOHONGAN :)

Saya juga mem-porting bagian dari Vector3 tetapi dikomentari.

https://github.com/DVLP/three.turbo.js

Sunting: Saya memiliki versi yang lebih mutakhir di suatu tempat di hard drive saya, jadi saya akan segera memperbarui proyek ini

Mengagumkan menonton dan menatap +1 untuk itu.
Apa yang hebat adalah sistem yang memeriksa kinerja dan mengaktifkan atau menonaktifkan fitur tersebut tergantung pada kinerja tersebut.

Apa yang hebat adalah sistem yang memeriksa kinerja dan mengaktifkan atau menonaktifkan fitur tersebut tergantung pada kinerja tersebut.

Saya kira seseorang akan memiliki dua definisi Vector3 dalam modul Vector3 dan Anda akan mengembalikan satu atau yang lain secara kondisional tergantung pada apakah SIMD asli? Saya kira itu akan berhasil, tetapi itu akan meningkatkan sisi unduhan. Mungkin Anda hanya dapat memiliki beberapa fungsi yang beralih tergantung pada apakah SIMD tersedia -- mungkin SIMD paling penting hanya untuk sebagian kecil fungsi matematika. Jika ini kecil dalam hal total kode, mungkin bermanfaat untuk dimasukkan sekarang. Namun perlu opsional agar tidak menjadi lambat saat SIMD tidak tersedia.

Kita bisa mulai dengan melakukan versi SIMD dari Matrix4 's multiplyMatrices() karena saat ini merupakan metode yang paling sering dipanggil dalam adegan kompleks.

https://github.com/mrdoob/three.js/blob/dev/src/math/Matrix4.js#L383 -L419

screen shot 2016-08-30 at 20 46 29

@mrdoob lihat di sini sudah selesai.
https://github.com/DVLP/three.turbo.js/blob/master/src/three.turbo.js

Coba sebagai bookmarklet:
javascript:(function(){var script=document.createElement('script');script.src='//rawgit.com/DVLP/three.turbo.js/master/src/three.turbo.js';document.head.appendChild(script);})()

Sepotong kode bertanggung jawab

THREE.Matrix4.prototype.multiplyMatrices = function(a, b) {
    var ae = a.elements,
      be = b.elements,
      tb = this.elements,
      arr1 = SIMD.Float32x4.load(ae, 0),
      arr3 = SIMD.Float32x4.load(ae, 4),
      arr5 = SIMD.Float32x4.load(ae, 8),
      arr7 = SIMD.Float32x4.load(ae, 12),
      arr2,
      arr4,
      arr6,
      arr8,
      res;
    // calculated version
        for (var i = 0; i < 4; i++) {
            arr2 = SIMD.Float32x4.splat(be[i * 4]);
            arr4 = SIMD.Float32x4.splat(be[i * 4 + 1]);
            arr6 = SIMD.Float32x4.splat(be[i * 4 + 2]);
            arr8 = SIMD.Float32x4.splat(be[i * 4 + 3]);
            res = SIMD.Float32x4.add(SIMD.Float32x4.add(SIMD.Float32x4.mul(arr1, arr2), SIMD.Float32x4.mul(arr3, arr4)), SIMD.Float32x4.add(SIMD.Float32x4.mul(arr5, arr6), SIMD.Float32x4.mul(arr7, arr8)));
            SIMD.Float32x4.store(tb, i * 4, res);
          }
}

Ketika saya menguji ini setengah tahun yang lalu, saya perhatikan bahwa versi dengan loop "untuk" yang dibuka sedikit lebih cepat. Itu sebabnya di perpustakaan kecil saya, loop dikomentari dan versi hardcoded hadir.

Ada lebih banyak fungsi di cabang "terbalik"
https://github.com/DVLP/three.turbo.js/blob/inverse/src/three.turbo.js

Apa perbedaan kinerja?

https://jsfiddle.net/tk6zx5dm/6/

Tergantung. Di Nightly ketika jumlah perhitungan kecil (<1000) maka hasilnya 3 kali lebih lambat. Ketika jumlah perhitungan lebih tinggi dari 10.000 maka kecepatannya ~ 40% lebih cepat

Di Chrome dengan flag --js-flags="--harmony-simd" diaktifkan, tidak ada SIMD asli, tetapi polyfill JavaScript jadi jelas kecepatannya berkali-kali lebih lambat untuk saat ini.

Tempat yang baik untuk menguji adalah proyek Crosswalk (berdasarkan Chromium). Mereka memiliki SIMD nyata untuk Android sehingga bisa menjadi eksperimen yang menarik untuk membangun proyek dengan kode dari JSFiddle ini untuk melihat seperti apa hasilnya.

Anda mungkin tidak ingin memasukkan polyfill simd pada halaman contoh Anda. Hanya sedikit lebih nyaman bagi orang untuk mencobanya. Catat baris di konsol atau letakkan beberapa teks di layar saat tidak ada native yang tersedia (polyfill mungkin meninggalkan beberapa petunjuk bahwa ini diaktifkan).

Saya tidak dapat membayangkan mengapa Chrome hanya memuat polyfill js simd dengan --js-flags="--harmony-simd" , itu tidak masuk akal ketika itu sudah bisa dilakukan di lahan pengguna?! Apa manfaat dari ini. Mungkin mereka akan mulai memasukkan barang secara bertahap. Di mana Anda membaca ini adalah apa yang sebenarnya terjadi dengan bendera, ada tautan bagus? Tampaknya "dalam pengembangan" di sini https://www.chromestatus.com/features/5757910432874496

Sunting: Untuk topik yang sebenarnya: Saya membayangkan sangat sulit untuk menempatkan barang-barang ini di three.js jika perf ada di semua tempat dari beberapa objek ke banyak objek. Jika semua implementasi dapat memberikan peningkatan kinerja dengan objek 1 hingga N, fitur tersebut harus dideteksi dan digunakan di tempat yang masuk akal. Jika impls asli tidak konsisten, saya tidak melihat semuanya berjalan ke mana-mana jadi mengapa repot-repot mengerjakannya, habiskan jam dev untuk sesuatu yang lebih produktif.

tiga dapat melompati ini ketika matang, atau apakah dukungan three.js dapat mendorong implementasi browser menjadi lebih baik? Saya akan berpikir mesin yang tidak nyata dan kasus penggunaan simulasi/matematika lainnya akan menjadi kekuatan pendorong bagi vendor browser, tidak terutama berapa banyak lib yang ingin menggunakan fitur tersebut. Tapi siapa yang tahu.

tidak dapat membayangkan mengapa Chrome hanya memuat polyfill js simd dengan --js-flags="--harmony-simd"

Saya pikir itu adalah praktik yang agak umum bahwa browser melakukannya dengan cara ini, sehingga pengguna dapat mulai menguji berbagai hal. Sebagai contoh, jika saya memahaminya dengan benar, WASM akan diperkenalkan di browser pada awalnya.

Semua argumen yang mendukung keniscayaan bahwa seorang perwira diperlukan. Pemantauan kinerja waktu nyata yang dapat mengaktifkan atau menonaktifkan fitur dan menentukan kinerja yang optimal. Jadi bahkan kepadatan peta bayangan harus berubah berdasarkan jarak kamera dll. Bagaimanapun saya tahu konsensus telah memutuskan ini akan menjadi alat pihak ketiga dan tidak diperlukan. Tetap saja saya hanya ingin menyimpan poin itu di alam sadar jika bukan pikiran bawah sadar.
Mungkin Anda hanya memeriksa pollyfill dan menonaktifkan SIMD tetapi sekali lagi FPS memberi tahu semuanya. Prioritas apa yang akan diaktifkan atau dinonaktifkan kemungkinan paling baik sebagai preferensi khusus pengguna/aplikasi. Terima kasih untuk mendengarkan! Saya menantikan GL yang lebih cepat dan lebih baik dalam waktu dekat. Mari kita bersiap untuk mengungguli yang lain.

Tampaknya proses memuat data ke SIMD mungkin menimbulkan overhead yang bertentangan dengan manfaat menggunakan SIMD di Nightly. Saya sangat ingin tahu tentang kinerja di Chrome tetapi Chromium terbaru dengan SIMD asli ada di sini http://peterjensen.github.io/idf2014-simd/
Ini sudah tua.

Memperbarui:
sekarang SIMD juga berfungsi di Edge. Anda dapat mengaktifkannya dengan membuka about:flags dan mencentang "Aktifkan fitur JavaScript eksperimental" (mulai ulang Edge)
Tidak yakin apakah ini SIMD asli atau polyfill. Tes ini membuat SIMD ~ 40% lebih lambat di mesin saya :/ https://jsfiddle.net/tk6zx5dm/6/

variasi tes dengan objek SIMD yang di-cache di objek Matrix4, tidak yakin apakah ini akan berguna
https://jsfiddle.net/tk6zx5dm/15/
Yang menarik adalah bahwa kode dengan objek SIMD yang di-cache _kadang-kadang_ lebih cepat bahkan di Chrome yang menggunakan polyfill SIMD(...? aneh)

THREE.Matrix4.prototype.multiplyMatrices = function(a, b) {
  var i = 4;
  while(i--) {
    SIMD.Float32x4.store(this.elements, i * 4, 
      SIMD.Float32x4.add(
        SIMD.Float32x4.add(
          SIMD.Float32x4.mul(
            a.cacheSIMDRow1,
            b.cacheSIMDSplat[i * 4]
          ),
          SIMD.Float32x4.mul(
            a.cacheSIMDRow2,
            b.cacheSIMDSplat[i * 4 + 1]
          )
        ),
        SIMD.Float32x4.add(
          SIMD.Float32x4.mul(
            a.cacheSIMDRow3,
            b.cacheSIMDSplat[i * 4 + 2]
          ), 
          SIMD.Float32x4.mul(
            a.cacheSIMDRow4,
            b.cacheSIMDSplat[i * 4 + 3]
          )
        )
      )
    );
  }
}

Caching - mungkin harus dijalankan pada setiap updateMatrix() yang pada akhirnya dapat membuat seluruh solusi lebih lambat

THREE.Matrix4.prototype.updateSIMDCache = function() {
  this.cacheSIMDRow1 = SIMD.Float32x4.load(this.elements, 0);
  this.cacheSIMDRow2 = SIMD.Float32x4.load(this.elements, 4);
  this.cacheSIMDRow3 = SIMD.Float32x4.load(this.elements, 8);
  this.cacheSIMDRow4 = SIMD.Float32x4.load(this.elements, 12);

  if(!this.cacheSIMDSplat) {
    this.cacheSIMDSplat = [];
  }
  for(var i = 0; i < 16; i++) {
    this.cacheSIMDSplat.push(SIMD.Float32x4.splat(this.elements[i]));
  }
};

Saya ingin tahu apakah gaya ES6 telah ditinjau kembali? Seluruh kode tidak dapat digunakan secara langsung sekarang tanpa menjalankan concatenator jadi mengapa tidak menjalankan babel dan mulai menggunakan hal-hal ES6 jika perlu?

Seluruh kode tidak dapat digunakan secara langsung sekarang tanpa menjalankan concatenator jadi mengapa tidak menjalankan babel dan mulai menggunakan hal-hal ES6 jika perlu?

Terutama karena kurangnya tes pada dampak kinerja kode yang dihasilkan babel. Juga, saya mendengar V8 menghasilkan kode yang lebih cepat saat menggunakan var daripada let/const.

FYI: Saya baru-baru ini mulai mencoba bublé yang "membatasi fitur ES yang dapat dikompilasi menjadi ES5 yang ringkas dan berkinerja tinggi".

Bagian bawah tautan ini membantu menjelaskan loop var vs let in
http://stackoverflow.com/questions/21467642/is-there-a-performance-difference-between-let-and-var
Secara pribadi saya sedang menunggu solusi none transpiler untuk masuk ke browser. seperti untuk 'menunggu' lebih cepat lebih baik, tetapi untuk saat ini mungkin harus ditulis seperti itu dan dijalankan melalui (dirusak oleh) transpiler, tetapi jika itu berfungsi di Chrome?! jadi pengujian untuk browser lain? Saya katakan 'Biarkan mereka makan kue... atau gunakan Chrome.' (ekspresi favorit saya).
Saya pikir 'biarkan' harus digunakan jika dalam situasi di mana lebih baik dibuktikan melalui tes lebih baik untuk melakukannya.
Saya kira itu seperti 'var' diangkat untuk menghindari pelingkupan tetapi Anda mungkin menginginkannya dan kemudian 'biarkan' adalah yang terbaik. Saya pikir/berharap 'biarkan' harus menjaga jejak memori Anda lebih kecil dalam situasi tertentu juga.

Kode yang ditranspilasikan tidak akan pernah secepat yang dioptimalkan dengan tangan. Sayang sekali JSPerf sedang down. Saya dulu lebih sering mengunjunginya daripada Google.
Sunting: JSPerf.com tidak turun! Saya hanya berasumsi itu mati selamanya setelah tidak berfungsi selama setahun
let 3x lebih lambat dari var di Chrome Canary saya: https://jsperf.com/let-vs-var-performance/14
di Firefox dan Edge tidak ada perbedaan kecepatan tetapi Chrome adalah yang paling penting.
Bisakah seseorang menguji di Safari?

Kelas tampak hebat dan modern! ada yang tau ini udah masuk jadwal?

@ Rubinhuang9239 Saya belum melihat siapa pun yang mencobanya.

biarkan 3x lebih lambat dari var di Chrome Canary saya: https://jsperf.com/let-vs-var-performance/14

Untuk apa nilainya, let dan const sekarang sedikit lebih cepat daripada var untuk saya di Chrome 66, Firefox 59 dan Edge 42, menggunakan tes itu.

Beralih kelas harus sangat lurus ke depan menurut saya - sebagian besar pekerjaan adalah adopsi rollup yang dilakukan beberapa waktu lalu. Saya tidak akan terkejut bahwa seorang pahlawan dapat mengimplementasikan kelas di ThreeJS dalam beberapa jam.

Yah ada banyak kelas, jadi mungkin akan memakan waktu sekitar 8 jam jika Anda melakukannya secara manual.

Mungkin mulai dari yang kecil dan ubah kelas matematika terlebih dahulu dan lakukan PR. Jika itu berhasil, maka lanjutkan ke yang lain.

@looeee sudah lebih dari setahun jadi tidak mengherankan ES6 berhasil mengejar kinerja

2019 adalah tahun untuk akhirnya mulai mengadopsi beberapa kode ES6 dalam contoh/dokumen, kan @mrdoob? 😄

ES6 telah menjadi standar untuk beberapa waktu sekarang, pengembang baru mempelajari ES6. Kami juga dapat berhenti mendukung IE11 dalam contoh seperti yang Anda diskusikan di #16220, pengembang mana yang melihat contoh three.js menggunakan IE11? 😅

Saya pikir fitur yang paling dibutuhkan untuk menyederhanakan kode untuk pendatang baru adalah kelas dan string template, sementara tidak melupakan const/let default sekarang.

Saya dapat berkontribusi jika kita memutuskan untuk memulai.

Selangkah demi selangkah. Mari kita mulai dengan memperbarui contoh untuk menggunakan three.module.js untuk saat ini.

Selangkah demi selangkah. Mari kita mulai dengan memperbarui contoh untuk menggunakan three.module.js untuk saat ini.

Langkah ini telah selesai untuk sementara waktu sekarang. Mungkin sudah waktunya untuk secara resmi melanjutkan ke langkah berikutnya?

Dua kandidat:

  1. const/biarkan
  2. kelas

Karena kelas telah digunakan dalam geometri kotak untuk sementara waktu sekarang, saya memilih untuk melakukannya terlebih dahulu. Atau kita bisa melakukan keduanya sekaligus.

Terkait: #11552, #18863

Jika saya mengerti benar, masalahnya adalah kita tidak dapat mengonversi apa pun ke kelas ES6 jika diperluas dengan contoh, sampai contoh juga dikonversi. Dan itu mungkin berarti menunggu sampai examples/js hilang? Kecuali kami dapat mengonfirmasi bahwa skrip modularize akan mendukung kelas, untuk mengonversi file examples/js pada saat yang sama dengan kelas induknya.

Seperti yang saya pahami, examples/js adalah jenis dari semua kelebihan fitur yang tidak kalah kerennya, tetapi jika kita semua digabungkan ke dalam src/... akan membuatnya tidak proporsional. Melekat adalah jawaban dari pertanyaan 'Apakah kami memberikan contoh/skrip dari x, y, z yang biasa dibuat?'. Saya menebak bahwa jawaban three.js sebagian besar ya tetapi sebagai materi pendidikan di dalam situs web. Menghapus examples/js tampaknya tidak mungkin dilakukan pada saat itu. Meskipun mungkin saya salah memahami bagaimana examples/js dirujuk/digunakan beri tahu saya.

Membiarkan examples/js hanya sebagai situs web/pendidikan yang melewatkan bagian dari maksud folder itu yaitu skrip komunitas/konten/proyek/lainnya yang ingin dibagikan orang tetapi saya tidak mengetahui di suatu tempat yang berlipat ganda itu.

saya ngelantur.

sampai contoh dikonversi juga.

Saya suka suara ini sebagai langkah sementara terbaik kami berikutnya.

@DefinitelyMungkin kami tidak menghapus fungsionalitas di examples/js , ada dua direktori yang perlu diperhatikan:

  • examples/js/*
  • examples/jsm/*

Yang pertama berisi file lama, yang terakhir berisi modul ES yang dihasilkan dari file tersebut, dengan fungsi yang sama. Kami akhirnya akan menghapus yang pertama. Skrip yang melakukan konversi tidak mendukung kelas ES saat ini. Jadi sampai itu dihapus, file di examples/js tidak dapat dikonversi ke kelas ES. Beberapa dari mereka memperluas file dalam src/ , dan Anda tidak dapat memperluas kelas ES tanpa menggunakan kelas ES, jadi ini adalah ketergantungan pemblokiran.

ah, bingung dengan komentar sebelumnya

Dan itu mungkin berarti menunggu sampai contoh/js hilang?

masuk akal sekarang.

modularize.js mengingatkan saya pada proyek awal saya yang membawa saya ke sini. Konverter . Saya melihat komentar di sini tentang pindah ke kelas ES6 jadi saya pikir saya akan melompat ke sini saja.

Jadi jika examples/js meluas src dalam beberapa cara keduanya perlu dikonversi ke kelas ES6 secara bersamaan
atau...
bekerja pada modularisasi hingga menghasilkan kelas/es6?

kami tidak dapat mengonversi apa pun ke kelas ES6 jika diperluas dengan contoh

Masih banyak hal di inti yang tidak diperluas dalam contoh, mengapa kita tidak mulai dengan itu?

Kedengarannya bagus untuk saya.

@ Mugen87 apakah ada hal lain yang menghalangi perubahan kelas ES, atau hanya itu?

Masih banyak hal di inti yang tidak diperluas dalam contoh, mengapa kita tidak mulai dengan itu?

Daftar skrip tidak diperpanjang dengan contoh .

edit: daftar telah diperbarui!

Blocker adalah bagian seperti ini:

https://github.com/mrdoob/three.js/blob/6865b8e6367d0ce07acbacfae6663c4cce3ac21e/examples/js/loaders/ColladaLoader.js#L6 -L12

https://github.com/mrdoob/three.js/blob/6865b8e6367d0ce07acbacfae6663c4cce3ac21e/examples/js/cameras/CinematicCamera.js#L38 -L39

https://github.com/mrdoob/three.js/blob/6865b8e6367d0ce07acbacfae6663c4cce3ac21e/examples/js/controls/OrbitControls.js#L1149 -L1150

Penggunaan THREE.<class>.call dan Object.create( THREE.<class> akan menjadi pola yang paling mungkin. Yang berarti bahwa Loader, EventDispatcher, dan PerspectiveCamera (di antara mungkin banyak lainnya) belum dapat dikonversi ke kelas.

https://github.com/mrdoob/three.js/commit/1017a5432eede4487436d6d34807fda24b506088

Oke, saya pikir kita bisa mulai dengan let dan const di src/ .

@DefinitelyMungkin Apakah ini sesuatu yang ingin Anda bantu?

ya!

Saya hanya ingin menyampaikan kekhawatiran bahwa jika Anda memuat kode panas, ketakutan saya adalah const akan menimbulkan masalah. Jika benar di semua JavaScript bahwa objek benar-benar menimpa const maka tidak ada masalah. Sayangnya jika tidak, semua const tidak boleh digunakan. Saya hanya menggabungkan struktur objek dengan fungsi kode yang ditetapkan ke kunci pohon objek tersebut (seperti struktur), jadi saya menghindari penggunaan let atau const untuk sebagian besar.
Bagaimanapun itu adalah sesuatu untuk dipikirkan dan pada dasarnya saya percaya const tidak boleh digunakan dan benar-benar tidak perlu. Terutama untuk masalah saya dengan pemuatan kode panas.
Tetap saja saya pikir mereka tidak konstan seperti yang Anda pikirkan, jadi mungkin seseorang yang lebih mengerti dapat menjelaskan bahwa itu adalah masalah yang tidak berarti dengan pemuatan ulang impor atau apa pun. Terima kasih atas pertimbangan dan masukannya.
Biarkan ada 'biarkan'! Akhirnya.

Crockford mengatakan var adalah kesalahan besar tetapi tidak dapat diubah sehingga 'biarkan' dibuat tetapi var dianggap cacat dan kode 'biarkan' seharusnya menjadi perbaikan untuk var, tetapi itu akan merusak beberapa kasus tepi berkode buruk yang tersisa bersembunyi di alam liar. Mode ketat dan pengangkatan adalah masalah seputar topik ini.

@MasterJames sama sekali tidak ada masalah dengan hot reload saat menggunakan const.

Saya bekerja di lingkungan Bereaksi dan memuat ulang panas adalah norma di sana, serta const dan let, yang merupakan standar saat ini.

Saya setuju, ini tidak akan mengganggu hot reload. Mungkin Anda salah mengira const karena membuat objek tidak dapat diubah dengan Object.freeze ? Kami tidak berencana melakukan itu.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat