-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathpass_through.ts
142 lines (121 loc) · 4.38 KB
/
pass_through.ts
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
133
134
135
136
137
138
139
140
141
142
export var passThroughshaderCode = `
struct VertexShaderOutput {
@builtin(position) position: vec4f,
@location(0) texcoord: vec2f,
};
@vertex fn vs(
@builtin(vertex_index) vertexIndex : u32
) -> VertexShaderOutput {
let uv = array(
// 1st triangle
vec2f( 0.0, 0.0), // center
vec2f( 1.0, 0.0), // right, center
vec2f( 0.0, 1.0), // center, top
// 2st triangle
vec2f( 0.0, 1.0), // center, top
vec2f( 1.0, 0.0), // right, center
vec2f( 1.0, 1.0), // right, top
);
let pos = array(
// 1st triangle
vec2f( -1.0, -1.0), // center
vec2f( 1.0, -1.0), // right, center
vec2f( -1.0, 1.0), // center, top
// 2st triangle
vec2f( -1.0, 1.0), // center, top
vec2f( 1.0, -1.0), // right, center
vec2f( 1.0, 1.0), // right, top
);
var vsOutput: VertexShaderOutput;
let xy = pos[vertexIndex];
vsOutput.position = vec4f(xy, 0.0, 1.0);
vsOutput.texcoord = uv[vertexIndex];
return vsOutput;
}
@group(0) @binding(0) var ourSampler: sampler;
@group(0) @binding(1) var ourTexture: texture_2d<f32>;
@fragment fn fs(fsInput: VertexShaderOutput) -> @location(0) vec4f {
let color = textureSample(ourTexture, ourSampler, fsInput.texcoord);
return color;
}
`;
export class GraphicsPipeline
{
device: GPUDevice;
pipeline: GPURenderPipeline | undefined;
sampler: GPUSampler | undefined;
pipelineLayout: GPUPipelineLayout | undefined;
inputTexture: GPUTexture | undefined;
bindGroup: GPUBindGroup | undefined;
constructor(device: GPUDevice)
{
this.device = device;
}
createGraphicsPipelineLayout()
{
// Passthrough shader will need an input texture to be displayed on the screen
const bindGroupLayoutDescriptor: GPUBindGroupLayoutDescriptor = {
label: 'pass through pipeline bind group layout',
entries: [
{binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: {}},
{binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: {sampleType: 'float'}},
],
};
const bindGroupLayout = this.device.createBindGroupLayout(bindGroupLayoutDescriptor);
const layout = this.device.createPipelineLayout({bindGroupLayouts: [bindGroupLayout]});
this.pipelineLayout = layout;
}
createPipeline(shaderModule: GPUShaderModule, inputTexture: GPUTexture)
{
this.createGraphicsPipelineLayout();
if(this.pipelineLayout == undefined) throw new Error("Pipeline layout not available")
const pipeline = this.device.createRenderPipeline({
label: 'pass through pipeline',
layout: this.pipelineLayout,
vertex:
{
module: shaderModule
},
fragment:
{
module: shaderModule,
targets: [{format: navigator.gpu.getPreferredCanvasFormat(),}]
},
});
this.pipeline = pipeline;
this.sampler = this.device.createSampler();
this.inputTexture = inputTexture;
this.createBindGroup();
}
createBindGroup()
{
if(this.pipeline == undefined) throw new Error("Pipeline not created yet")
if(this.sampler == undefined) throw new Error("Sampler not created yet")
if(this.inputTexture == undefined) throw new Error("Input texture not created yet")
const bindGroup = this.device.createBindGroup({
label: 'pass through pipeline bind group',
layout: this.pipeline.getBindGroupLayout(0),
entries: [
{ binding: 0, resource: this.sampler },
{ binding: 1, resource: this.inputTexture.createView() },
],
});
this.bindGroup = bindGroup;
}
createRenderPassDesc(view: GPUTextureView): GPURenderPassDescriptor
{
const attachment: GPURenderPassColorAttachment = {
view,
clearValue: [0.3, 0.3, 0.3, 1],
loadOp: 'clear',
storeOp: 'store',
};
const renderPassDescriptor = {
label: 'pass through renderPass',
colorAttachments: [
attachment
],
};
return renderPassDescriptor;
}
};