forked from gogpu/gogpu
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshader.go
More file actions
185 lines (159 loc) · 5.85 KB
/
Copy pathshader.go
File metadata and controls
185 lines (159 loc) · 5.85 KB
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package gogpu
// coloredTriangleShaderSource is the WGSL shader for a simple red triangle.
// Uses the same pattern as vulkan-triangle example for maximum compatibility.
const coloredTriangleShaderSource = `
@vertex
fn vs_main(@builtin(vertex_index) idx: u32) -> @builtin(position) vec4<f32> {
var positions = array<vec2<f32>, 3>(
vec2<f32>(0.0, 0.5), // Top center
vec2<f32>(-0.5, -0.5), // Bottom left
vec2<f32>(0.5, -0.5) // Bottom right
);
return vec4<f32>(positions[idx], 0.0, 1.0);
}
@fragment
fn fs_main() -> @location(0) vec4<f32> {
return vec4<f32>(1.0, 0.0, 0.0, 1.0); // Red
}
`
// TexturedQuadShader returns the WGSL shader for rendering textured quads.
// Exported for use in examples and advanced rendering scenarios.
func TexturedQuadShader() string {
return texturedQuadShaderSource
}
// SimpleTextureShader returns the WGSL shader for full-screen textured quads.
func SimpleTextureShader() string {
return simpleTextureShaderSource
}
// texturedQuadShaderSource is the WGSL shader for rendering textured quads.
const texturedQuadShaderSource = `
// Uniform buffer for transforms
struct Uniforms {
transform: mat4x4<f32>,
color: vec4<f32>,
}
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
@group(1) @binding(0) var texSampler: sampler;
@group(1) @binding(1) var tex: texture_2d<f32>;
struct VertexInput {
@location(0) position: vec2<f32>,
@location(1) uv: vec2<f32>,
}
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
}
@vertex
fn vs_main(input: VertexInput) -> VertexOutput {
var output: VertexOutput;
output.position = uniforms.transform * vec4<f32>(input.position, 0.0, 1.0);
output.uv = input.uv;
return output;
}
@fragment
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
let texColor = textureSample(tex, texSampler, input.uv);
return texColor * uniforms.color;
}
`
// simpleTextureShaderSource is a simpler WGSL shader for full-screen textured quads
// without transforms (useful for basic image display).
const simpleTextureShaderSource = `
@group(0) @binding(0) var texSampler: sampler;
@group(0) @binding(1) var tex: texture_2d<f32>;
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
}
@vertex
fn vs_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
// Full-screen quad vertices (2 triangles)
var positions = array<vec2<f32>, 6>(
vec2<f32>(-1.0, 1.0), // top-left
vec2<f32>(-1.0, -1.0), // bottom-left
vec2<f32>( 1.0, -1.0), // bottom-right
vec2<f32>(-1.0, 1.0), // top-left
vec2<f32>( 1.0, -1.0), // bottom-right
vec2<f32>( 1.0, 1.0) // top-right
);
var uvs = array<vec2<f32>, 6>(
vec2<f32>(0.0, 0.0), // top-left
vec2<f32>(0.0, 1.0), // bottom-left
vec2<f32>(1.0, 1.0), // bottom-right
vec2<f32>(0.0, 0.0), // top-left
vec2<f32>(1.0, 1.0), // bottom-right
vec2<f32>(1.0, 0.0) // top-right
);
var output: VertexOutput;
output.position = vec4<f32>(positions[vertexIndex], 0.0, 1.0);
output.uv = uvs[vertexIndex];
return output;
}
@fragment
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
return textureSample(tex, texSampler, input.uv);
}
`
// positionedQuadShaderSource is the WGSL shader for positioned textured quads.
// Uses a uniform buffer for position/size and vertex-less rendering.
// Handles both premultiplied and straight alpha via uniform flag.
// All output is premultiplied — uses BlendFactorOne / OneMinusSrcAlpha.
// Bind group 0: uniforms (transform)
// Bind group 1: sampler + texture
const positionedQuadShaderSource = `
// Uniform buffer for quad positioning
// Layout: [x, y, width, height, screenWidth, screenHeight, alpha, premultiplied]
struct QuadUniforms {
rect: vec4<f32>, // x, y, width, height in pixels
screen: vec2<f32>, // screen width, height
alpha: f32, // opacity (0.0 - 1.0)
premultiplied: f32, // >0.5 = premultiplied alpha, <=0.5 = straight alpha
}
@group(0) @binding(0) var<uniform> uniforms: QuadUniforms;
@group(1) @binding(0) var texSampler: sampler;
@group(1) @binding(1) var tex: texture_2d<f32>;
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
}
@vertex
fn vs_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
// Quad corners in normalized [0,1] space
var corners = array<vec2<f32>, 6>(
vec2<f32>(0.0, 0.0), // top-left
vec2<f32>(0.0, 1.0), // bottom-left
vec2<f32>(1.0, 1.0), // bottom-right
vec2<f32>(0.0, 0.0), // top-left
vec2<f32>(1.0, 1.0), // bottom-right
vec2<f32>(1.0, 0.0) // top-right
);
let corner = corners[vertexIndex];
// Calculate pixel position
let pixelX = uniforms.rect.x + corner.x * uniforms.rect.z;
let pixelY = uniforms.rect.y + corner.y * uniforms.rect.w;
// Convert to NDC: [-1, 1]
// X: (pixel / screenWidth) * 2 - 1
// Y: 1 - (pixel / screenHeight) * 2 (Y is flipped)
let ndcX = (pixelX / uniforms.screen.x) * 2.0 - 1.0;
let ndcY = 1.0 - (pixelY / uniforms.screen.y) * 2.0;
var output: VertexOutput;
output.position = vec4<f32>(ndcX, ndcY, 0.0, 1.0);
output.uv = corner;
return output;
}
@fragment
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
let texColor = textureSample(tex, texSampler, input.uv);
if (uniforms.premultiplied > 0.5) {
return texColor * uniforms.alpha;
} else {
let a = texColor.a * uniforms.alpha;
return vec4<f32>(texColor.rgb * a, a);
}
}
`
// PositionedQuadShader returns the WGSL shader for positioned textured quads.
// This shader uses vertex-less rendering with uniforms for position and size.
func PositionedQuadShader() string {
return positionedQuadShaderSource
}