-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
132 lines (113 loc) · 4.52 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import {GPULoadOp, GPUPrimitiveTopology, GPUStoreOp,} from "../libs/webgpu/GPUEnum.js";
async function init() {
// アダプターを取得
const adapter = await navigator.gpu?.requestAdapter();
// アダプターからデバイスを取得
const device = await adapter?.requestDevice({});
// キャンバスのセットアップ
const canvas = document.getElementById('myCanvas');
canvas.width = canvas.style.width = innerWidth;
canvas.height = canvas.style.height = innerHeight;
// キャンバスから描画コンテキストを取得
const context = canvas.getContext('webgpu');
if (!adapter || !device || !context) {
notSupportedDescription.style.display = "block";
canvas.style.display = "none";
return;
}
notSupportedDescription.style.display = "none";
canvas.style.display = "inline";
// 適切なスワップチェーンフォーマットを取得
const swapChainFormat = navigator.gpu.getPreferredCanvasFormat();
// コンテキストにデバイスとスワップチェーンフォーマットを設定
const swapChain = context.configure({
device: device,
format: swapChainFormat
});
// language=WGSL
const vertexShaderWGSL = `
// 頂点シェーダのWGSLコード
@vertex
fn main(
@builtin(vertex_index) VertexIndex : u32
) -> @builtin(position) vec4<f32> {
var pos = array<vec2<f32>, 3>(
vec2(0.0, 0.5),
vec2(-0.5, -0.5),
vec2(0.5, -0.5)
);
return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
}
`;
// 頂点シェーダーのコンパイル
const gpuVertexState = {
module: device.createShaderModule({code: vertexShaderWGSL}),
entryPoint: "main"
}
if (gpuVertexState.module.compilationInfo) {
// シェーダーコンパイルのエラーチェック
console.log(await gpuVertexState.module.compilationInfo());
}
// language=WGSL
const fragmentShaderWGSL = `
// フラグメントシェーダのWGSLコード
@fragment
fn main() -> @location(0) vec4<f32> {
return vec4(1.0, 0.0, 0.0, 1.0);
}
`;
// フラグメントシェーダーのコンパイル
const gpuFragmentState = {
module: device.createShaderModule({code: fragmentShaderWGSL}),
entryPoint: "main"
}
if (gpuVertexState.module.compilationInfo) {
// シェーダーコンパイルのエラーチェック
console.log(await gpuFragmentState.module.compilationInfo());
}
// レンダリング用パイプラインの設定ディスクリプタ(記述子)をオブジェクト形式で定義
const gpuRenderPipelineDescriptor = {
// 定数のレイアウトを指定。今回のシェーダーでは定数はなし。"auto"を指定するとシェーダーから適切なバインドグループレイアウトを自動で作成してくれる。
layout: "auto",
// 頂点シェーダーステージの設定
vertex: gpuVertexState,
// フラグメントシェーダーステージの設定
fragment: Object.assign(gpuFragmentState, {
// 描画対象のフォーマット
targets: [{
format: swapChainFormat
}]
}),
// 描画するプリミティブ(点や三角形)の設定
primitive: {
topology: GPUPrimitiveTopology.triangle_list
}
};
// ディスクリプタからパイプラインを作成。
const pipeline = device.createRenderPipeline(gpuRenderPipelineDescriptor);
// レンダリング設定のディスクリプタをオブジェクト形式で定義
const renderPassDescriptor = {
colorAttachments: [{
clearValue: {r: 0.3, g: 0.6, b: 0.8, a: 1.0},
loadOp: GPULoadOp.clear,
storeOp: GPUStoreOp.store,
view: undefined,
}]
};
// 三角形をレンダリング
// GPUコマンド列を作成
const commandEncoder = device.createCommandEncoder({});
// レンダリング設定のディスクリプタに、描画対象キャンバスのテクスチャビューを設定。これはレンダリングのたびに実行する必要がある。
renderPassDescriptor.colorAttachments[0].view = context.getCurrentTexture().createView();
// レンダリングコマンドを作成
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
// 使用するパイプラインを指定
passEncoder.setPipeline(pipeline);
// ドローコール。3頂点を1インスタンス。
passEncoder.draw(3, 1, 0, 0);
// レンダリングコマンドを終了
passEncoder.end();
// コマンドをGPUキューに追加
device.queue.submit([commandEncoder.finish()]);
}
window.addEventListener('DOMContentLoaded', init);