Three.js: いくつかのES6機能を採用する

作成日 2015年04月16日  ·  74コメント  ·  ソース: mrdoob/three.js

ES6が登場し、ブラウザとツールが急速にサポートされるようになりました。 THREE.jsは、ES6によってもたらされたいくつかの新機能から多大な恩恵を受けることができると思います。

楽しみのために、そしてプロジェクトの移行の可能性をめぐる議論を奨励するために、私はこの問題を作成し、いくつかのコード例を作成しました。

以下の例に示されている機能:

  • デフォルトパラメータ
  • ブロックスコープのletキーワード
  • イテレータ+ For..Of
  • クラス
  • 矢印関数
  • 発電機
  • モジュール

クラスの例

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;

トラバーサルジェネレータの例

class Object3D {
    constructor() {
        ...
    }

    traverse(callback) {
        callback(this);

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

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

    ...
}

使用中の発電機:

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

注:私はこれをテストしていません

Suggestion

最も参考になるコメント

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

さて、私たちはで始めることができると思うletconstsrc/

@DefinitelyMaybeこれはあなたが手伝いたいことですか?

全てのコメント74件

おそらく少し早いですか? サポートは一貫して優れたクロスブラウザではありません: http

letはFFで公開されておらず、ChromeとIEの状況の100%では公開されていません。
generatorsはIEでは利用できません
classは、Chrome、Win10およびFF39のIE12(Spartan)テクニカルプレビューでのみ使用されます。これは、現在のバージョンより2つ上です。
importはまだどこでも利用できません
superはIE12でのみ使用でき、IE11、Chrome、FFでは使用できません
arrow functionsはIE11またはChromeにはありません

また、ジェネレーターとfor-ofはどちらもChromeの最適化キラーです

Imoも早すぎて、見栄えのする構文にはなりません。 リストにある何かが顕著なパフォーマンスの向上またはコードの可読性の利点をもたらす場合は議論の余地があります。 たぶん、コードベースとES6の機能を知っている人がそれについてコメントすることができます。

ES6パーティーに少し遅れています。 これは私には別の言語のように見えます。 私は定期的にThree.jsに貢献していますが、上記のスニペットのように見える場合は、続行するかどうかわかりません。 見た目も機能も異なるバージョンのJavaScriptを学ぶ忍耐力がありません。これは、基本的に「new function()」や「object.prototype」と同じことを行いますが、速度が遅くなる可能性があります。

これは、WebコミュニティがES6言語委員会に要求していることですか? 私は20年間コーディングを行ってきましたが、「クラス」という単語はプロジェクトのどこにも表示されません(自分のやり方があれば、これも表示されません)。 率直に言って、JavaScriptはJAVA ...(スクリプト)のように見え始めています。 :-\

私は@benaadams一緒です; 早すぎます。ChromeとFirefoxが、内部でJavaScriptをすでに最適化しているように、この新しいバージョンの言語を大幅に最適化しないと、コードが遅くなる可能性があります(V8など)。

:+1:

@erichlofええと、私は実際にES6クラスとモジュールのサポートが最も多いのを待っています。 現在、アプリにAMDを使用しています。 私が取り組んでいる主なJSプロジェクトは、数百の「クラス」を含む最大10,000行であり、AMDは命の恩人です。 開発中とビルドの作成中の両方。 Imoの大規模または小規模なプロジェクトには、ある種のモジュールシステムと、それらが依存しているものを宣言する方法が必要です。 複雑なプロジェクト構造になると、管理が困難になります。 プログラムされた人が25x <script>タグをどの順序で配置するかを理解することを任せるべきではありません。 three.jsのようにファイルの量が増えたら、これはばかげています。 ほとんどのプロジェクトは、1つの大きなjsファイル(three.jsなど)を作成することでこれを解決します。その後、他のものを含めることができるランダムなエクストラ/ヘルパーフォルダーがあります。 これはやや制限があり、すべてを太陽の下で取得するには、500kb(縮小)ビルドを含める必要があります。

ある時点で、3つのAMDサポートが追加されたと思いますが、それはAMDが使用されているかどうかを検出し、window.THREEを効果的に宣言する代わりに関数を呼び出す小さなコードブロックです。 不要な機能を削除し、コアの外部に必要なものを追加して、順番にロードする単一の作業ファイルに最適化するカスタムビルドを作成することが現在どれほど難しいかはわかりません。

プロジェクトに「クラス」がない場合もありますが、object.prototypeを使用する場合(three.jsが頻繁に使用するように)、事実上同じことですが、同意しますか? オブジェクトを組み合わせて目的を与えるのが好きです。 次に、他のコードは、上記のオブジェクトとそれらをインポートするためのクリーンな宣言型の方法を使用したいと考えています。

私が言っているのは、ES6のクラスとモジュールがthree.jsに追加されて、ビルドの構造とモジュール性が向上することです。 たとえば、ブラウザがサポートしていないため、早すぎます。 まだモジュール。 他の人は、それらを使い始めて、babelなどを使用し、ES5準拠のビルドを出力する必要があると言うかもしれません。それが良い考えかどうかはわかりませんが、誰が知っていますか。 これにより、開発が難しくなり、ファイルを保存するときにビルドを自動開始する必要があり、デバッグもより複雑になる可能性があります。 これらのことだけでも、私はこれらのトランスパイラーはそれだけの価値がないと思う傾向があります。

PSはthree.jsに対する怒りではありませんでした。ブラウザのサポートがあれば、three.jsのようなプロジェクトにはES6にメリットがあるかもしれないと言っただけです:)そしてほとんどの場合、まったく新しい言語にするよりも構文上の糖衣構文です。 それはただもっと多くのものを持っているでしょう。

three.jsにとって有益かもしれないもう1つの機能は、 WeakMapとおそらくWeakSetです。 影響についてはよくわかりませんが、「所有者」が参照を保持しなくなった場合、GCがその仕事を続けることなく、これを使用して物事を追跡できるようです。 three.jsにはこのような状態がたくさんあり、内部で使用すると違いが生じる可能性があります。 これは、所有権を宣言するという点で、C ++の共有/弱いptrに少し似ているように思われます。

良い候補はhttps://github.com/mrdoob/three.js/blob/master/src/lights/SpotLight.js#L12のようなもので、これは弱い参照である可能性があり、ターゲットがシーンから削除され、収集されました。 しかし、とにかくコレクションに依存することはできなかったと思いますが、ターゲットがシーンから削除されたら、とにかくそれを無効にする必要があります。

誰が知っているか、私は専門家がこれらすべての機能が一般的にアプリにどのように役立つかについていくつかのブログ投稿を書くのを待ちます:)

こんにちは@jonnenauha

はい、特にモジュール性が関係する場合、「インポート」や「エクスポート」などの新機能が役立つことに同意します。 これが、 @ coballast@kumavisが、THREE.jsをよりモジュール化して、カスタムビルドとコードベースの保守性を管理しやすくするための方向性だと

ただし、JavaScriptで基本的に同じ機能を取得するときに、クラス、super、let、for、of、arrow関数などの追加のシンタックスシュガーは必要ないと思います。すでに多くの牽引力。 私は時代遅れかもしれませんが、JavaScriptはすでにオブジェクト指向言語(関数=オブジェクト=第一級市民を意味します)であるが、「古典的な」言語ではないと彼が言ったとき、私はダグラス・クロックフォードと一緒です-したがって、私たちは心配する必要はありませんクラスをJavaScriptにシューホーニングします。 それは別のアプローチで設計されました-私が最初に驚いたアプローチ(1990年代のC / C ++プログラミングから来ました)、しかし私がコードに座ったりコードアーキテクチャを解決しようとするたびに私はますます同意します問題。

THREE.jsの構文を変更する代わりに、新しいSIMDプログラミングインターフェイスなどの機能への移行を望んでいます。 THREEのすべての数学コード(特にVector3とMatrix4)は、これから大きな恩恵を受けることができると思います。 ここにビデオリンクがあります(タイムコードの22:51をチェックしてください):
https://youtu.be/CbMXkbqQBcQ?t=1371
この機能が主要なブラウザーに導入されると、すべてのTHREE.jsユーザーは、結果としてフレームレートの顕著なスピードアップを目にするでしょう。

以前の投稿が暴言のように聞こえた場合は申し訳ありませんが、今のTHREE.jsが好きです。ランダムな部分を簡単に選択して、何が起こっているのか、どこから来たのか、何を使用しているのかを知ることができます。 :)

@erichlof @jonnenauha es6クラスは単なる砂糖であり、実行時にすべてを実装するために内部的にプロトタイプメカニズムを使用していることを指摘しなければならないと感じています。

es6の機能が計算パフォーマンスに影響を与えないことはかなり楽観的です。 es6モジュールは、1つの大きなファイルではなく、多数の小さなファイルをフェッチするため、最終的にエンジンによって実装されるときにロード時間に影響を与える可能性があります。 HTTP / 2はそれを問題にしないかもしれません。 いずれにせよ、es6モジュールを使用する場合は、browserifyを使用して、いつものようにバンドルを構築できます。

私は個人的に、コードベースでes6構文を可能な限り使用することを望んでいます。これにより、コードがより簡潔になり、エラーが減少するからです。 多くの人がプロトタイプチェーンを悪用して誤って使用する傾向があると思います。 しかし、良い例はありません。

また、es6がエンジンに実装されるのを待って待つのは間違った考えだと思います。 トランスパイラーは現在利用可能であり、現在ブラウザーで実行される良好な結果を生成します。 これを行うことのメリットは非常に大きいと思うので、焦ってすぐに作業を開始する必要があります。

コードを手動で移動するのは良い考えではないと思います。 ユニックスパイプの発明者であり、一般的に半神であるダグマキルロイは次のように述べています。
「ツールを構築するために迂回する必要があり、ツールの使用を終了した後にそれらの一部を破棄することを期待している場合でも、熟練していないヘルプよりもツールを使用してプログラミングタスクを軽減します。」

es6に興味のある人は誰でも参加して、このリポジトリに貢献することをお勧めします//github.com/5to6/5to6

ライブラリ全体をjavascriptの別のサブセットに変換することに同意しません。 いつものように、私たちは何が可能で、何が賛否両論であるかについて話し合うべきです。 パフォーマンスはバージョン間で異なるためです。

たとえば、weakmapsは、オブジェクトの状態を処理するためにレンダラーで大きなメリットとなるものです。 最大の欠点は、ポリフィルが弱く、ブラウザのサポートがほとんどなく、パフォーマンス特性が不明であったことです。 (調査してからしばらく経ちますので、変更される可能性があります)

そして、es6だけを見るべきではありません。 たとえば、ams.jsは、ソフトウェアレンダラーを実行するテクノロジーとして最適です。 詳細については、 http://stackoverflow.com/questions/18427810/three-and-asmjs/18439786#18439786をご覧ください。

また、javascriptはよく知られており、es6はまだほとんど使用されていないため、ほとんどの寄稿者が主に寄稿していることを忘れてはなりません。

@ gero3それは私が思いもよらなかった良い点です。 私たちがマイクロ最適化について話しているなら、私はあなたに100%同意します。 ブラウザのサポートなしでこれらの機能を利用したくありません。

私が上で話していたのは、主に既存のes5機能と同じセマンティクスを持つシンタックスシュガーを使用していたため、パフォーマンスにあまり影響を与えることなくトランスパイラーで構築できました。

アップデート:
誰も気にしないかもしれませんが、気が変わりました。 クラスは使わない方がいいと思います。 私はまだes6モジュールが良い考えだと思います。

私は完全にクラスに賛成です。 JavaScriptのオブジェクトプロトタイプでできる素晴らしいことをすべて手に入れました。 ただし、THREE.js(および他の多くの最新のOSプロジェクト)では、プロトタイプの継承を使用してクラスをシミュレートしているので、それに合わせて次のようなハッキーなものを取り除くための優れた構文を使用してみませんか。

THREE.Object3D.call( this );

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

安定したChromeとFirefoxでクラスがサポートされるとすぐに、コードの更新を検討してもかまいません😊

@mrdoobクラスは、現在安定したChrome 42でサポートされており、Firefox39は6月に出荷されますFYI😊

iOS上のSafariは、最近ドラッグしているようです...😣

クラスは素晴らしく、他のES7機能も素晴らしかったです。 プロジェクトの1つでそれらを使用していますが、Chrome、Firefox、IE、Safariのすべてのブラウザーで実行する必要があるため、クロスコンパイラー(babel.js)を導入する必要がありました。

babel.js(babelify)を実行するためのbrowserifyトランスフォームがあるので、私の努力でうまく機能します。

好奇心から、これらのいくつかの作業が開始されましたか? :)

これらの速度への影響がまだわからないため、いいえ。

私の理解では、トランスパイルされたES6はほとんどパフォーマンスが高くないため、ブラウザーに組み込まれるまで本番環境には使用されません。 そうは言っても、新しいプロジェクトやモジュールは今日これらの便利さを適応させる必要がありますが、この決定にはパフォーマンスを考慮に入れる必要があります。

@erichlof imoに同意します。ポリフィルを使用した場合でも、最も有用な実装はSIMD(https://github.com/tc39/ecmascript_simd)です。 ユーザーはそれから最も恩恵を受けるようです。

SIMDはThreeJSのどこに適合しますか? ThreeJSはすでにすべての重要な計算をGPUにオフロードしていると思います。 Vectorクラスでそれを使用することはある程度理解できますが、ThreeJSで実際に行われる計算はほとんどなく、ほとんどの場合、これらのベクトルはGPUに転送されるだけです。

以前にSSE2 / SSE4拡張機能を実装したときの経験から話をしますが、ほとんどの場合、メリットは一瞬でした。実際のケースは、同じことをしたい大きなアレイがあった場合だけでした。手術。

こんにちは@bhouston
同じことがマトリックス操作にも当てはまりますか? SIMDを考えていたとき、4 X4の行列演算が最も有益だと思っていました。 そして、ご存知のとおり、マトリックスは、アプリの複雑さに関係なく、JavaScript / CPU側のThree.jsのすべてのアニメーションフレームで使用されます。

Babylon.jsの人たちが気にしないのであれば、これをすべて始める方法のヒントを次に示します。
https://github.com/BabylonJS/Babylon.js/blob/master/src/Math/babylon.math.js#L2030 -L2093

フォーマットを変換する必要がある場合、単一の行列の倍数はおそらく敗者だと思います。 マトリックスが常にSIMD形式である場合は、それがメリットになる可能性があります。

ただし、それでも、列と行を乗算する必要があり、並べ替え操作が必要になるため、行列の乗算は最適ではないことがよくあります。

SIMD最適化でのほとんどの努力(同種の操作を伴う大きな配列を除く)は努力する価値がないことがわかりましたが、他の人がベンチマークを行って調べても大丈夫です。

結果のコードもデバッグと保守が困難です。

有効な戦略の1つは、すべてのベクトルと行列にSIMD互換のメモリレイアウトをネイティブ表現として使用させることです。これは、Quake3が数学ライブラリで信じていたものです。 ただし、効率を上げるには、vec2タイプとvec3タイプに4つのフロートを使用する必要がありますが、GPUにアップロードする場合は、フロートが余分にあるため、問題が発生します。

私はあなたが何を意味するのかわかります、あなたの洞察と専門知識に感謝します。 しばらく前にSIMD.jsのプレゼンテーションに感銘を受け、それをthree.jsに貼り付けて維持することは、私が思う2つの異なることです。 あなたがいくつかのパフォーマンス比較を行ったと言ったように、それは興味深いでしょう。 たぶん、Three.jsと組み合わせて使用​​されるCannon.jsやOimo.jsのような物理ライブラリはSIMDからより多くの利益を得るでしょうか?

@bhoustonああ、それは理にかなっていますが、いくつかのベンチマークは非常に興味深いでしょう。

@erichlof興味があれば、 https://github.com/Globegitter/three.js/tree/include-SIMDというブランチを開始しました。ここでVector3をSIMDに置き換え始めました。 それはまだ重い仕掛品であり、私の時間は限られているので、私はどこまで到達するかを説明します。 また、最新のFirefoxを毎晩使用すると、ポリフィルなしでこのコードを実行できます(ネイティブ実装は、ポリフィルと比較して明らかに最大20倍高速です:https://blog.mozilla.org/javascript/2015/03/10/state -of-simd-js-performance-in-firefox /)。

@erichlof @jonnenauha es6クラスは単なる砂糖であり、実行時にすべてを実装するために内部的にプロトタイプメカニズムを使用していることを指摘しなければならないと感じています。
es6の機能が計算パフォーマンスに影響を与えないことはかなり楽観的です。

次のように結論付けるのは少し速いかもしれません。JSオブジェクトの(かなり複雑な)実装では、すべてのJSエンジンにES6のコードパスが実際に異なります。

es6モジュールは、1つの大きなファイルではなく、多数の小さなファイルをフェッチするため、最終的にエンジンによって実装されるときにロード時間に影響を与える可能性があります。 HTTP / 2はそれを問題にしないかもしれません。

クライアントは、アプリ全体のJSレベルの圧縮を使用して、ネットワーク帯域幅を削減し、知的財産を保護したい場合があります。

クロージャコンパイラにThree.jsを理解させると、ES6にコンパイルして、いつ切り替えるのが適切かを確認できるほか、多くの利点があります。 これが今のところこの種の努力が行われるべきところだと思います...

ただし、それでも、[SIMD]行列の乗算は、列と行を乗算する必要があり、並べ替え操作が必要になるため、最適ではないことがよくあります。

SIMD命令セットには、次のような行列乗算を実装するために、「スカラーによる乗算と加算」命令が含まれていることがよくあります。

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

行列の乗算は、実際には右側のオペランドの列ベクトルに変換を適用するだけです。 現在、変換は、ドット積の束(通常、ペンと紙で使用する紛らわしい方法)として、または宛先スペースの軸ベクトル=左側の列ベクトルの線形結合として見ることができます。オペランド。

@Globegitterうわー、それは素晴らしいスタートです! Firefox Nightlyを入手して、新しいブランチも試すことができます。

@Globegitter誰かが先に進んで、それを信じて何かをするとき、私は大好きです。 コードは、議論よりも早く発散した視点を解決します。

ここで、ネイティブ実装は、ポリフィルと比較して明らかに約20倍高速です。

ポリフィルが非SIMDと比較してどれだけ遅いかについても知りたいと思います

Firefox Nightlyを入手して、新しいブランチも試すことができます。

about:flagsexperimentalとasm.jsをオンにすることで、Edgeで試すこともできるはずです。

@Globegitterエディターが空白を変更して、非常に厄介な差分をhttps

サイドカーとしてSIMDタイプを作っていることに気づきました。

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

Vector3 x、y、zをgetter / setterに変更し、float32x4のみを保存することをお勧めしますか? このようなアプローチは、少ない変更で実装する方がはるかに簡単かもしれないと思います。

プロパティを定義する最良の方法はわかりませんが、mrdoobはここでそのようなことを行います。

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

数学タイプの背後にあるメインストレージタイプとしてSIMDを使用するのがおそらく最も効率的であり、追加の変換は必要ありません。 標準のベクトル/行列演算のガイドが必要な場合は、Bullet PhysicsSSE数学ライブラリを次に示します。

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

@bhouston 、これらのメモに感謝します。 以前に3つとSIMDをあまり使用していなかったので、数時間でどれだけ遠くまで到達できるかを確認するために、そこにまっすぐ入っていました(ほとんどのプロジェクトで使用しています)。 したがって、3つを知っている誰かからのこのフィードバックは本当にありがたいです。 そして、ええ、私のエディターでそれをオフにする必要があります。

@tschw行列/ベクトルの数学に関するメモに感謝します! あなたは正しいです。

@Globegitterオブジェクトのプロトタイプでのsetter / getterのより良い例を次に示します: https

ES2015(主にノード内)での作業に数セント

  • Javascriptエンジン(V8など)がES6機能の最適化に追いつくためにプレイする必要がある場所があります
  • 私の経験から、 let x = 1, y = 2ようなコードはv8を最適化しないでしょうが、v8は最終的にそれをサポートすると予想します
  • ES5にトランスパイルされたコードはES6コードよりも実行速度が遅くなる可能性があります(そのため、>ノード4でサポートされているES6機能のみを使用することを好みます。これは、インポート/エクスポートシステムを除くほとんどすべてです)
  • マップとセットはパフォーマンスの向上です
  • クラスはいいです
  • Babelを使用することはワークフローに負担をかける可能性があり、ES6を純粋にシンタックスシュガーに使用する場合はおそらく努力する価値がありません。

半年前、私はいくつかのThree.js関数(4x4行列乗算、Vector4など)をSIMDに変換し、それらを試すことができます。 ある時点でブックマークレットとして機能しましたが、最新の3つのバージョンで機能するには更新が必要になる場合があります

  • Firefox Nightlyは、箱から出してネイティブSIMDをサポートします
  • フラグが付いたChrome--js-flags = "-harmony-simd"はSIMDのJSポリフィルをサポートしているため、SIMD以外のバージョンよりも遅くなります。 少なくとも、それが機能するかどうかを確認して実験することができます!

350%のパフォーマンス向上は嘘です:)

Vector3の一部も移植しましたが、コメントされています。

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

編集:ハードドライブのどこかに最新バージョンがあるので、このプロジェクトをすぐに更新します

素晴らしい見つめ、それに+1を凝視します。
素晴らしいのは、パフォーマンスをチェックし、そのパフォーマンスに応じてそのような機能を有効または無効にするシステムです。

素晴らしいのは、パフォーマンスをチェックし、そのパフォーマンスに応じてそのような機能を有効または無効にするシステムです。

Vector3モジュール内に2つのVector3定義があり、SIMDがネイティブであるかどうかに応じて、条件付きでどちらか一方を返すと思いますか? それはうまくいくと思いますが、ダウンロード側が増えるでしょう。 たぶん、SIMDが利用可能かどうかに応じて切り替わるいくつかの関数を持つことができます-おそらくSIMDは数学関数の小さなサブセットに対してのみ最も重要です。 これがコード全体の点で小さかった場合は、今すぐ入力する価値があるかもしれません。 ただし、SIMDが利用できないときに遅くならないように、オプションである必要があります。

Matrix4multiplyMatrices() SIMDバージョンを実行することから始めることができます。これは、現在、複雑なシーンで最も呼び出されるメソッドです。

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

screen shot 2016-08-30 at 20 46 29

@mrdoobここを見てください。
https://github.com/DVLP/three.turbo.js/blob/master/src/three.turbo.js

ブックマークレットとしてお試しください:
javascript:(function(){var script=document.createElement('script');script.src='//rawgit.com/DVLP/three.turbo.js/master/src/three.turbo.js';document.head.appendChild(script);})()

責任のあるコード

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);
          }
}

この半年前にテストしていたとき、「for」ループが展開されたバージョンの方が最小限高速であることに気付きました。 そのため、私の小さなライブラリにはループがコメント化されており、ハードコードされたバージョンが存在します。

「逆」ブランチにはさらに多くの関数があります
https://github.com/DVLP/three.turbo.js/blob/inverse/src/three.turbo.js

パフォーマンスの違いは何ですか?

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

場合によります。 Nightlyでは、計算の数が少ない(<1000)場合、結果は3倍遅くなります。 計算数が10000を超えると、速度は約40%速くなります。

--js-flags="--harmony-simd"フラグが有効になっているChromeでは、実際のSIMDはありませんが、JavaScriptポリフィルがあるため、現時点では明らかに速度が何倍も遅くなっています。

テストするのに適した場所は、Crosswalkプロジェクト(Chromiumに基づく)です。 彼らはAndroid用の実際のSIMDを持っているので、このJSFiddleからのコードを使用してプロジェクトを構築し、結果がどうなるかを確認することは興味深い実験になる可能性があります。

とにかくサンプルページにsimdポリフィルを含めたくないかもしれません。 人々がそれらを試すのにもう少し便利です。 ネイティブが利用できない場合は、コンソールに行を記録するか、画面にテキストを表示します(ポリフィルは、おそらく有効になっているというヒントをいくつか残します)。

Chromeがjssimdポリフィルに--js-flags="--harmony-simd"ロードする理由が想像できません。これは、ユーザーランドで既に実行できる場合は意味がありません。 これの利点は何ですか。 たぶん彼らは徐々に物を入れ始めるでしょう。 これは旗で実際に何が起こっているのか、良いリンクはどこで読んだのですか? ここで「開発中」のようですhttps://www.chromestatus.com/features/5757910432874496

編集:実際のトピックへ:パフォーマンスがいくつかのオブジェクトから多くのオブジェクトまでいたるところにある場合、このようなものをthree.jsに入れるのは非常に難しいと思います。 すべての実装で1〜N個のオブジェクトでパフォーマンスが向上する場合は、機能を検出して、意味のある場所で使用する必要があります。 ネイティブの実装に一貫性がない場合は、すべてがどこにも行かないので、わざわざ作業するのはなぜですか。開発時間をより生産的なものに費やしてください。

3つは成熟したときにこれに飛びつくことができますか、それともthree.jsのサポートがブラウザーの実装をより良くするように駆り立てることができるのでしょうか? アンリアルエンジンやその他のシミュレーション/数学のユースケースは、ブラウザベンダーの原動力であり、特にこの機能を使用したいライブラリの数ではないと思います。 しかし、誰が知っています。

Chromeが-js-flags = "-harmony-simd"を使用してjssimdポリフィルをロードする理由を想像することはできません

ユーザーがテストを開始できるように、ブラウザーがこのように行うのはかなり一般的な方法だと思います。 たとえば、私が正しく理解していれば、これがWASMが最初にブラウザに導入される方法です。

百人隊長が必要とされる必然性を支持するすべての議論。 機能を有効または無効にし、最適なパフォーマンスを決定できるパフォーマンスのリアルタイム監視。 したがって、シャドウマップの密度でさえ、カメラの距離などに基づいて変更する必要があります。とにかく、これはサードパーティのツールであり、不要であるとコンセンサスが判断したことを私は知っています。 それでも私は、潜在意識ではないにしても、その点を意識の中に保ちたいと思っています。
たぶん、ポリフィルをチェックしてSIMDを無効にするだけですが、FPSがすべてを教えてくれます。 何を有効または無効にするかの優先順位は、ユーザー/アプリ固有の設定として最適である可能性があります。 聞いてくれてありがとう! 近い将来、より高速なGLを楽しみにしています。 残りを凌駕する準備をしましょう。

SIMDにデータをロードするプロセスは、NightlyでSIMDを使用する利点に反するオーバーヘッドを作成しているようです。 Chromeでのパフォーマンスに非常に興味がありますが、実際のSIMDを備えた最新のChromiumはここにありますhttp://peterjensen.github.io/idf2014-simd/
古いです。

アップデート:
現在、SIMDはEdgeでも機能します。 about:flagsに移動し、[実験的なJavaScript機能を有効にする]をオンにすることで有効にできます(Edgeを再起動します)
ただし、これが実際のSIMDなのかポリフィルなのかはわかりません。 このテストでは、私のマシンでSIMDが最大40%遅くなります:/ https://jsfiddle.net/tk6zx5dm/6/

Matrix4オブジェクトにキャッシュされたSIMDオブジェクトを使用したテストのバリエーション。これが役立つかどうかはわかりません。
https://jsfiddle.net/tk6zx5dm/15/
興味深いのは、SIMDオブジェクトがキャッシュされたコードは、ポリフィルSIMDを使用しているChromeでも_時々_高速であるということです(...?奇妙な)

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]
          )
        )
      )
    );
  }
}

キャッシング-おそらくすべてのupdateMatrix()で実行する必要があり、最終的にソリューション全体が遅くなる可能性があります

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]));
  }
};

ES6スタイルが再検討されたのか興味がありますか? 現在、コード全体はコンカテネーターを実行せずにライブで使用できないので、babelも実行して、必要に応じてES6のものを使い始めてみませんか?

現在、コード全体はコンカテネーターを実行せずにライブで使用できないので、babelも実行して、必要に応じてES6のものを使い始めてみませんか?

主に、babelで生成されたコードのパフォーマンスへの影響に関するテストが不足しているためです。 また、let / constの代わりにvarを使用すると、V8がより高速なコードを生成すると聞きました。

参考:私は最近、「コンパクトでパフォーマンスの高いES5にコンパイルできるES機能に限定する」

このリンクの下部は、varとletinループの説明に役立ちます
http://stackoverflow.com/questions/21467642/is-there-a-performance-difference-between-let-and-var
個人的には、トランスパイラーなしのソリューションがブラウザーにヒットするのを待っています。 「await」のように早くする方が良いですが、今のところ、そのように記述してトランスパイラーを実行する必要があります(ひどく傷つけられています)が、Chromeで機能する場合は?! では、他のブラウザをテストしますか? 私は「彼らにケーキを食べさせて...またはChromeを使用させてください」と言います。 (私の好きな表現)。
テストでより良いことが証明されることが望ましい状況にある場合は、「let」を使用する必要があると思います。
スコープを避けるために「var」が持ち上げられているようなものだと思いますが、それが必要な場合は「let」が最適です。 特定の状況でも、メモリフットプリントを小さく保つ必要があると思います。

トランスパイルされたコードは、手作業で最適化されるほど高速になることはありません。 JSPerfがダウンしているのは残念です。 私はグーグルより頻繁にそれを訪問しました。
編集:JSPerf.comはダウンしていません! それが1年間機能していなかった後、私はそれが永遠に死んでいると思っていました
let Chrome Canaryのvarより3倍遅い: https
FirefoxとEdgeでは速度に違いはありませんが、Chromeが最も重要です。
誰かがSafariでテストできますか?

クラスは素晴らしくてモダンに見えます! これがすでにスケジュールどおりかどうか誰かが知っていますか?

@ Rubinhuang9239私は誰もそれをやってみるのを見たことがありません。

Chrome Canaryのvarよりも3倍遅くします: https

その価値については、Chrome 66、Firefox 59、およびEdge 42で、そのテストを使用すると、 letconstvarよりもわずかに高速になりました。

クラスの切り替えは非常に簡単なはずです。作業の大部分は、かなり前に行われたロールアップの採用でした。 ヒーローが数時間でThreeJSにクラスを実装できるのは驚くことではありません。

授業はたくさんあるので、手動でやったら8時間くらいかかるかもしれません。

たぶん、小さく始めて、最初に数学のクラスを変換して、PRをします。 それがうまくいく場合は、他の人に移ります。

@looeee 1年以上当然のことです。

2019年は、examples / docsでES6コードの採用をようやく開始する年ですよね@mrdoob? 😄

ES6はかなり前から標準であり、新しい開発者はES6を学びます。 また、#16220で説明したように、例でIE11のサポートを停止することもできます。どの開発者がIE11を使用してthree.jsの例を見ていますか? 😅

新規参入者向けのコードを単純化するために最も必要な機能は、現在のデフォルトのconst / letを忘れずに、クラスとテンプレート文字列だと思います。

始めようと決心したら貢献できます。

ステップバイステップ。 今のところthree.module.jsを使用するように例を更新することから始めましょう。

ステップバイステップ。 今のところthree.module.jsを使用するように例を更新することから始めましょう。

このステップはしばらくの間完了しています。 たぶん、正式に次のステップに進む時が来たのでしょうか?

2つの候補者:

  1. const / let
  2. クラス

クラスはすでにしばらくの間ボックスジオメトリで使用されているので、私は最初にそれを行うことに投票します。 または、両方を同時に行うこともできます。

関連:#11552、#18863

私が正しく理解していれば、問題は、例によって拡張された場合、例も変換されるまで、ES6クラスに何も変換できないということです。 そしてそれはexamples/jsがなくなるまで待つことを意味するかもしれませんか? modularizeスクリプトがクラスをサポートすることを確認できない限り、 examples/jsファイルを親クラスと同時に変換します。

私が理解しているように、 examples/jsは、それでもかっこいいすべての余分な機能の一種ですが、すべてをメインのsrc/...組み合わせると、バランスが崩れてしまいます。 本質的に、「一般的に作成されるx、y、zの例/スクリプトを提供しますか?」という質問への回答です。 three.jsの答えはほとんどイエスですが、ウェブサイト内の教育資料であると推測するのは危険です。 examples/js削除することは、その時点では問題外のようです。 examples/jsがどのように参照/使用されているかを誤解しているかもしれませんが🤔教えてください。

examples/jsをウェブサイト/教育機関だけとして残すと、そのフォルダが何であるか、つまりコミュニティスクリプト/コンテンツ/プロジェクト/その他の人々が共有したいポイントの一部が失われますが、どこかで倍増していることに気づいていませんそれ。

私は逸脱します。

例も変換されるまで。

次善の暫定ステップとして、この音が好きです。

@DefinitelyMaybeexamples/jsの機能を削除していませんが、注目に値する2つのディレクトリがあります。

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

前者にはレガシーファイルが含まれ、後者には同じ機能を持つそれらのファイルから生成されたESモジュールが含まれます。 最終的に最初のものを削除します。 変換を行うスクリプトは、現在ESクラスをサポートしていません。 したがって、それが削除されるまで、 examples/js内のファイルをESクラスに変換することはできません。 それらのいくつかはsrc/でファイルを拡張し、ESクラスを使用せずにESクラスを拡張することはできないため、これはブロッキングの依存関係です。

ああ、前のコメントで混乱しました

そしてそれはexamples / jsがなくなるまで待つことを意味するかもしれませんか?

今は理にかなっています。

moduleize.jsは、私をここに連れてきた最初のプロジェクトを思い出させます。 コンバーター。 ES6クラスへの移行についてのコメントをここで見たので、代わりにここに飛び込むと思いました。

したがって、 examples/jsが何らかの方法でsrcを拡張する場合は、両方を同時にES6クラスに変換する必要があります。
また...
クラス/ es6を生成するまでモジュール化に取り組んでいますか?

例によって拡張された場合、ES6クラスに何も変換できません

コアにはまだ例で拡張されていないものがたくさんありますが、それから始めてみませんか?

それは私には問題ないように聞こえます。

@ Mugen87 ESクラスの変更をブロックするものは他にありましたか、それともそれだけですか?

コアにはまだ例で拡張されていないものがたくさんありますが、それから始めてみませんか?

例によって拡張されていないスクリプトのリスト

編集:リストが更新されました!

ブロッカーは次のようなセクションです。

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

THREE.<class>.callObject.create( THREE.<class>が最も可能性の高いパターンです。 つまり、Loader、EventDispatcher、およびPerspectiveCamera(おそらく他の多くのものの中でも)はまだクラスに変換できません。

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

さて、私たちはで始めることができると思うletconstsrc/

@DefinitelyMaybeこれはあなたが手伝いたいことですか?

🎉💯hellzyea!

あなたがホットコードをロードしているなら、私の恐れはconstが問題を引き起こすだろうという懸念を提起したかっただけです。 オブジェクトがconstを完全に上書きすることがすべてのJavaScriptに当てはまる場合は、問題ありません。 残念ながら、そうでない場合は、すべてのconstを使用しないでください。 オブジェクト構造をそれらのオブジェクトツリーのキーに割り当てられたコード関数(構造など)とマージするだけなので、ほとんどの場合、letまたはconstを使用する必要はありません。
とにかくそれは考えるべきことであり、私は基本的にconstは決して使用されるべきではなく、本当に怖くないと信じています。 主に、ホットコードの読み込みに関する私の懸念のためです。
それでも、それらはあなたが思っているほど一定ではないと思うので、もっと多くのことが説明できることを理解している人は、インポートのリロードなどに無意味な懸念があるかもしれません。 検討とご意見をありがとうございます。
'let'がありますように! ついに。

Crockfordは、varは大きな間違いでしたが、変更できなかったため、「let」が作成されましたが、varは欠陥があると見なされ、「let」のコードはvarの修正であるはずでしたが、コーディングが不十分なエッジケースがいくつか残っていたと述べました。野生に潜んでいます。 厳密モードと巻き上げは、このトピックに関する問題です。

@MasterJames constを使用する場合、ホットリロードに問題はまったくありません。

私はReact環境で作業しており、ホットリロードが標準であり、constとletも今日の標準です。

私は同意します、これはホットリロードを妨げません。 おそらく、 constObject.freezeオブジェクトを不変にすることと間違えたのではないでしょうか。 私たちはそれをするつもりはありません。

このページは役に立ちましたか?
0 / 5 - 0 評価