このシリーズでは、WebGPU とコンピューター グラフィックス全般を紹介します。
まず、何を構築するかを見てみましょう。
人生ゲーム
3D レンダリング
3D レンダリング、ただし照明あり
3D モデルのレンダリング
JS の基本的な知識を除き、事前知識は必要ありません。
チュートリアルはソース コードとともに私の github ですでに完成しています。
WebGPU は、GPU 用の比較的新しい API です。 WebGPU という名前が付けられていますが、実際には Vulkan、DirectX 12、Metal、OpenGL、WebGL の上にあるレイヤーと考えることができます。これは低レベル API として設計されており、ゲームやシミュレーションなどの高パフォーマンス アプリケーションでの使用を目的としています。
この章では、画面上に何かを描画します。最初の部分では、Google Codelabs チュートリアルについて説明します。画面上にライフゲームを作成していきます。
出発点
TypeScript を有効にして、vite に空のバニラ JS プロジェクトを作成します。次に、余分なコードをすべて削除し、main.ts.
だけを残します。
const main = async () => { console.log('Hello, world!') } main()
実際にコーディングする前に、ブラウザで WebGPU が有効になっているかどうかを確認してください。 WebGPU サンプルで確認できます。
Chrome はデフォルトで有効になりました。 Safari では、開発者設定に移動し、フラグ設定を行って、WebGPU を有効にする必要があります。
WebGPU の 3 つのタイプを有効にし、@webgpu/types をインストールし、tsc コンパイラ オプションに "types": ["@webgpu/types"] を追加する必要もあります。
さらに、
三角形を描く
WebGPU には多くの定型コードがあります。以下にそのコードを示します。
要求元のデバイス
まず、GPU にアクセスする必要があります。 WebGPU では、GPU とブラウザーの間のブリッジであるアダプターの概念によってこれが行われます。
const adapter = await navigator.gpu.requestAdapter();
次に、アダプターからデバイスをリクエストする必要があります。
const device = await adapter.requestDevice(); console.log(device);
キャンバスを構成する
キャンバス上に三角形を描きます。 Canvas 要素を取得して構成する必要があります。
const canvas = document.getElementById('app') as HTMLCanvasElement; const context = canvas.getContext("webgpu")!; const canvasFormat = navigator.gpu.getPreferredCanvasFormat(); context.configure({ device: device, format: canvasFormat, });
ここでは、getContext を使用してキャンバスに関する相対情報を取得します。 webgpu を指定することで、WebGPU でのレンダリングを担当するコンテキストを取得します。
CanvasFormat は実際にはカラー モード (srgb など) です。通常は、優先される形式のみを使用します。
最後に、デバイスとフォーマットのコンテキストを設定します。
GPU レンダリング パイプラインについて
エンジニアリングの詳細に入る前に、まず GPU がレンダリングをどのように処理するかを理解する必要があります。
GPU レンダリング パイプラインは、GPU が画像をレンダリングするために実行する一連のステップです。
GPU 上で実行されるアプリケーションはシェーダーと呼ばれます。シェーダはGPU上で動作するプログラムです。シェーダーには特別なプログラミング言語があります。これについては後で説明します。
レンダー パイプラインには次の手順があります。
- CPU はデータを GPU にロードします。 CPU は、GPU リソースを節約するために、いくつかの非表示オブジェクトを削除する場合があります。
- CPU は、GPU がシーンをレンダリングするために必要なすべての色、テクスチャ、およびその他のデータを設定します。
- CPU は GPU への描画呼び出しをトリガーします。
- GPU は CPU からデータを取得し、シーンのレンダリングを開始します。
- GPU は、シーンの頂点を処理するジオメトリ プロセスに実行されます。
- ジオメトリ プロセスの最初のステップは、シーンの頂点を処理する頂点シェーダーです。頂点を変換したり、頂点の色を変更したり、頂点に対して他の操作を行ったりすることがあります。
- 次のステップは、シーンの頂点を処理するテッセレーション シェーダーです。頂点の再分割を実行します。その目的は、シーンの詳細を高めることです。手順もたくさんありますが、複雑すぎてここでは説明できません。
- 次のステップは、シーンの頂点を処理するジオメトリ シェーダーです。開発者が 1 つの頂点の変換方法のみを定義できる頂点シェーダーとは対照的に、ジオメトリ シェーダーは複数の頂点の変換方法を定義できます。また、新しい頂点を作成し、それを使用して新しいジオメトリを作成することもできます。
- ジオメトリ プロセスの最後のステップには、画面を超える不必要な部分を削除するクリッピングと、カメラに表示されない非表示の部分を削除するカリングが含まれます。
- 次のステップはラスター化プロセスで、頂点をフラグメントに変換します。フラグメントは、画面上にレンダリングされるピクセルです。
- 次のステップは三角形の反復であり、シーンの三角形を反復します。
- 次のステップは、シーンのフラグメントを処理するフラグメント シェーダーです。フラグメントの色を変更したり、フラグメントのテクスチャを変更したり、フラグメントに対して他の処理を行ったりする場合があります。この部分では、深さテストとステンシルテストも実行されます。深度テストとは、各フラグメントに深度値を与えることを意味し、深度値が最も小さいフラグメントがレンダリングされます。ステンシルテストとは各フラグメントにステンシル値を与えることを意味し、ステンシルテストに合格したフラグメントがレンダリングされます。ステンシル値は開発者によって決定されます。
- 次のステップは、シーンの断片をブレンドするブレンド プロセスです。たとえば、2 つのフラグメントが重なっている場合、ブレンド プロセスでは 2 つのフラグメントが一緒にブレンドされます。
- 最後のステップは出力プロセスで、フラグメントをスワップ チェーンに出力します。スワップ チェーンは、シーンのレンダリングに使用されるイメージのチェーンです。より簡単に言うと、画面に表示される画像を保持するバッファです。
GPU がレンダリングできる最小単位であるプリミティブに応じて、パイプラインのステップが異なる場合があります。通常、三角形を使用します。これは、頂点の 3 つのグループごとに三角形として扱うように GPU に信号を送ります。
レンダーパスの作成
レンダー パスは、完全な GPU レンダリングのステップです。レンダー パスが作成されると、GPU はシーンのレンダリングを開始し、終了するとその逆になります。
レンダー パスを作成するには、レンダー パスを GPU コードにコンパイルするエンコーダーを作成する必要があります。
const main = async () => { console.log('Hello, world!') } main()
次に、レンダー パスを作成します。
const adapter = await navigator.gpu.requestAdapter();
ここでは、カラーアタッチメントを含むレンダーパスを作成します。アタッチメントは、レンダリングされる画像を表す GPU の概念です。画像には GPU が処理する必要がある多くの側面があり、それらはそれぞれ添付ファイルです。
ここではアタッチメントが 1 つだけあり、それがカラーアタッチメントです。ビューは GPU がレンダリングするパネルであり、ここではキャンバスのテクスチャに設定します。
loadOp は、GPU がレンダー パスの前に実行する操作です。clear は、GPU が最初に最後のフレームから以前のデータをすべてクリアすることを意味します。storeOp は、GPU がレンダー パスの後に実行する操作です。store は GPU を意味します。データをテクスチャに保存します。
loadOp は、最後のフレームからのデータを保存するload、または最後のフレームからデータをクリアするclearにすることができます。 storeOp は、データをテクスチャに保存する store、またはデータを破棄する Discard にできます。
ここで、 pass.end() を呼び出してレンダー パスを終了します。これで、コマンドが GPU のコマンド バッファーに保存されました。
コンパイルされたコマンドを取得するには、次のコードを使用します。
const device = await adapter.requestDevice(); console.log(device);
そして最後に、コマンドを GPU のレンダー キューに送信します。
const canvas = document.getElementById('app') as HTMLCanvasElement; const context = canvas.getContext("webgpu")!; const canvasFormat = navigator.gpu.getPreferredCanvasFormat(); context.configure({ device: device, format: canvasFormat, });
これで、醜い黒いキャンバスが表示されるはずです。
3D に関する固定概念に基づくと、何もない空間は青色であると予想されます。これは、クリアカラーを設定することで実現できます。
const encoder = device.createCommandEncoder();
シェーダーを使用して三角形を描画する
次に、キャンバス上に三角形を描きます。これを行うにはシェーダーを使用します。シェーダー言語は wgsl (WebGPU Shading Language) になります。
ここで、次の座標で三角形を描画するとします。
const pass = encoder.beginRenderPass({ colorAttachments: [{ view: context.getCurrentTexture().createView(), loadOp: "clear", storeOp: "store", }] });
前に述べたように、レンダー パイプラインを完成するには、頂点シェーダーとフラグメント シェーダーが必要です。
頂点シェーダー
次のコードを使用してシェーダー モジュールを作成します。
const commandBuffer = encoder.finish();ここでの
label は単なる名前であり、デバッグ用です。 code は実際のシェーダー コードです。
頂点シェーダーは、任意のパラメータを受け取り、頂点の位置を返す関数です。ただし、予想に反して、頂点シェーダーは 3 次元ベクトルではなく 4 次元ベクトルを返します。 4 番目の次元は w 次元で、視点の分割に使用されます。それについては後で説明します。
これで、4 次元ベクトル (x、y、z、w) を単純に 3 次元ベクトル (x / w、y / w、z / w) とみなすことができます。
しかし、別の問題があります。データをシェーダーに渡す方法と、データをシェーダーから取り出す方法です。
シェーダーにデータを渡すには、頂点のデータを含むバッファーである vertexBuffer を使用します。次のコードでバッファを作成できます
const main = async () => { console.log('Hello, world!') } main()
ここでは、頂点のサイズである 24 バイト、6 浮動小数点のサイズのバッファーを作成します。
usage はバッファーの使用法であり、頂点データの場合は VERTEX です。 GPUBufferUsage.COPY_DST は、このバッファがコピー先として有効であることを意味します。 CPU によってデータが書き込まれるすべてのバッファに対して、このフラグを設定する必要があります。
ここでのマップは、バッファを CPU にマップすることを意味します。つまり、CPU がバッファを読み書きできることを意味します。アンマップとは、バッファーのマップを解除することを意味します。これは、CPU がバッファーの読み取りと書き込みを行うことができなくなり、GPU でコンテンツを使用できるようになることを意味します。
これで、データをバッファに書き込むことができます。
const adapter = await navigator.gpu.requestAdapter();
ここでは、バッファを CPU にマッピングし、データをバッファに書き込みます。次に、バッファーのマップを解除します。
vertexBuffer.getMappedRange() は、CPU にマップされているバッファーの範囲を返します。これを使用してデータをバッファに書き込むことができます。
ただし、これらは単なる生データであり、GPU はそれらを解釈する方法を知りません。バッファのレイアウトを定義する必要があります。
const device = await adapter.requestDevice(); console.log(device);
ここで、arrayStride は、GPU が次の入力を探すときにバッファ内で前方にスキップする必要があるバイト数です。たとえば、arrayStride が 8 の場合、GPU は次の入力を取得するために 8 バイトをスキップします。
ここでは float32x2 を使用しているため、ストライドは 8 バイト、各 float に 4 バイト、各頂点に 2 float です。
これで頂点シェーダーを作成できます。
const canvas = document.getElementById('app') as HTMLCanvasElement; const context = canvas.getContext("webgpu")!; const canvasFormat = navigator.gpu.getPreferredCanvasFormat(); context.configure({ device: device, format: canvasFormat, });
ここで、@vertex は、これが頂点シェーダーであることを意味します。 @location(0) は属性の場所を意味し、以前に定義したように 0 です。シェーダー言語ではバッファーのレイアウトを扱うため、値を渡すときは常に、フィールドに @location が定義されている構造体、または @location を持つ値のみを渡す必要があることに注意してください。
vec2f は 2 次元 float ベクトル、vec4f は 4 次元 float ベクトルです。頂点シェーダーは vec4f 位置を返す必要があるため、 @builtin(position) でアノテーションを付ける必要があります。
フラグメントシェーダ
フラグメント シェーダも同様に、補間された頂点出力を受け取り、アタッチメント (この場合はカラー) を出力するものです。補間とは、頂点上の特定のピクセルのみが決定値を持っていますが、他のピクセルごとに、値が線形、平均、またはその他の手段で補間されることを意味します。フラグメントの色は 4 次元ベクトルで、フラグメントの色、それぞれ赤、緑、青、アルファです。
色の範囲は 0 ~ 255 ではなく、0 ~ 1 であることに注意してください。さらに、フラグメント シェーダーは三角形の色ではなく、すべての頂点の色を定義します。三角形の色は、補間によって頂点の色によって決定されます。
現時点ではフラグメントの色を制御する必要がないため、単純に定数の色を返すことができます。
const main = async () => { console.log('Hello, world!') } main()
レンダリングパイプライン
次に、頂点シェーダーとフラグメント シェーダーを置き換えることによって、カスタマイズされたレンダー パイプラインを定義します。
const adapter = await navigator.gpu.requestAdapter();
フラグメント シェーダーでは、キャンバスの形式であるターゲットの形式を指定する必要があることに注意してください。
ドローコール
レンダーパスが終了する前に、描画呼び出しを追加します。
const device = await adapter.requestDevice(); console.log(device);
ここで、setVertexBuffer の最初のパラメータはパイプライン定義フィールド バッファ内のバッファのインデックスであり、2 番目のパラメータはバッファ自体です。
draw を呼び出す場合、パラメータは描画する頂点の数です。頂点が 3 つあるので、3 つ描画します。
これで、キャンバス上に黄色の三角形が表示されるはずです。
ライフゲームのセルを描く
ここでコードを少し調整します。ライフ ゲームを構築したいので、三角形の代わりに正方形を描く必要があります。
正方形は実際には 2 つの三角形なので、6 つの頂点を描く必要があります。ここでの変更は簡単なので詳細な説明は必要ありません。
const canvas = document.getElementById('app') as HTMLCanvasElement; const context = canvas.getContext("webgpu")!; const canvasFormat = navigator.gpu.getPreferredCanvasFormat(); context.configure({ device: device, format: canvasFormat, });
これで、キャンバス上に黄色の四角形が表示されるはずです。
座標系
GPU の座標系については議論しませんでした。まあ、かなりシンプルです。 GPU の実際の座標系は右手座標系です。これは、X 軸が右を指し、Y 軸が上を指し、Z 軸が画面の外を指すことを意味します。
座標系の範囲は-1から1です。原点は画面の中心です。 z 軸は 0 から 1 で、0 は近い平面、1 は遠い平面です。ただし、z 軸は深さを表します。 3D レンダリングを行う場合、Z 軸を使用してオブジェクトの位置を決定するだけではなく、透視分割を使用する必要があります。これは NDC (正規化されたデバイス座標) と呼ばれます。
たとえば、画面の左上隅に正方形を描画したい場合、頂点は (-1, 1)、(-1, 0)、(0, 1)、(0, 0) になります。ただし、描画するには 2 つの三角形を使用する必要があります。
以上がWeb 上の三角形が何かを描くの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

PythonまたはJavaScriptの選択は、キャリア開発、学習曲線、エコシステムに基づいている必要があります。1)キャリア開発:Pythonはデータサイエンスとバックエンド開発に適していますが、JavaScriptはフロントエンドおよびフルスタック開発に適しています。 2)学習曲線:Python構文は簡潔で初心者に適しています。 JavaScriptの構文は柔軟です。 3)エコシステム:Pythonには豊富な科学コンピューティングライブラリがあり、JavaScriptには強力なフロントエンドフレームワークがあります。

JavaScriptフレームワークのパワーは、開発を簡素化し、ユーザーエクスペリエンスとアプリケーションのパフォーマンスを向上させることにあります。フレームワークを選択するときは、次のことを検討してください。1。プロジェクトのサイズと複雑さ、2。チームエクスペリエンス、3。エコシステムとコミュニティサポート。

はじめに私はあなたがそれを奇妙に思うかもしれないことを知っています、JavaScript、C、およびブラウザは正確に何をしなければなりませんか?彼らは無関係であるように見えますが、実際、彼らは現代のウェブ開発において非常に重要な役割を果たしています。今日は、これら3つの間の密接なつながりについて説明します。この記事を通して、JavaScriptがブラウザでどのように実行されるか、ブラウザエンジンでのCの役割、およびそれらが協力してWebページのレンダリングと相互作用を駆動する方法を学びます。私たちは皆、JavaScriptとブラウザの関係を知っています。 JavaScriptは、フロントエンド開発のコア言語です。ブラウザで直接実行され、Webページが鮮明で興味深いものになります。なぜJavascrを疑問に思ったことがありますか

node.jsは、主にストリームのおかげで、効率的なI/Oで優れています。 ストリームはデータを段階的に処理し、メモリの過負荷を回避します。大きなファイル、ネットワークタスク、リアルタイムアプリケーションの場合。ストリームとTypeScriptのタイプの安全性を組み合わせることで、パワーが作成されます

PythonとJavaScriptのパフォーマンスと効率の違いは、主に以下に反映されています。1)解釈された言語として、Pythonはゆっくりと実行されますが、開発効率が高く、迅速なプロトタイプ開発に適しています。 2)JavaScriptはブラウザ内の単一のスレッドに限定されていますが、マルチスレッドおよび非同期I/Oを使用してnode.jsのパフォーマンスを改善でき、両方とも実際のプロジェクトで利点があります。

JavaScriptは1995年に発信され、Brandon Ikeによって作成され、言語をCに実現しました。 2。JavaScriptのメモリ管理とパフォーマンスの最適化は、C言語に依存しています。 3. C言語のクロスプラットフォーム機能は、さまざまなオペレーティングシステムでJavaScriptを効率的に実行するのに役立ちます。

JavaScriptはブラウザとnode.js環境で実行され、JavaScriptエンジンに依存してコードを解析および実行します。 1)解析段階で抽象的構文ツリー(AST)を生成します。 2)ASTをコンパイル段階のバイトコードまたはマシンコードに変換します。 3)実行段階でコンパイルされたコードを実行します。

PythonとJavaScriptの将来の傾向には、1。Pythonが科学コンピューティングの分野での位置を統合し、AI、2。JavaScriptはWebテクノロジーの開発を促進します。どちらもそれぞれのフィールドでアプリケーションシナリオを拡大し続け、パフォーマンスをより多くのブレークスルーを行います。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。
