63 lines
1.8 KiB
WebGPU Shading Language
63 lines
1.8 KiB
WebGPU Shading Language
struct VertexShaderInput {
|
|
// Per Vertex
|
|
@builtin(vertex_index) vertex_index: u32,
|
|
|
|
@location(0) pos: vec3<f32>,
|
|
|
|
// Per Instance
|
|
@location(1) pos_size: vec4<f32>,
|
|
@location(2) uv0uv1: vec4<f32>,
|
|
@location(3) uv2uv3: vec4<f32>,
|
|
};
|
|
|
|
struct VertexShaderOutput {
|
|
@builtin(position) pos: vec4<f32>,
|
|
|
|
@location(0) uv: vec2<f32>,
|
|
};
|
|
|
|
struct FragmentShaderOutput {
|
|
@location(0) color: vec4<f32>,
|
|
};
|
|
|
|
@group(0) @binding(0) var<uniform> view_projection_matrix: mat4x4<f32>;
|
|
|
|
@vertex fn main_vertex(input: VertexShaderInput) -> VertexShaderOutput {
|
|
var output: VertexShaderOutput;
|
|
|
|
output.pos = vec4<f32>(input.pos_size.xy + input.pos.xy, 0, 1) * view_projection_matrix;
|
|
|
|
switch (input.vertex_index) {
|
|
case 0: { output.uv = input.uv0uv1.xy; }
|
|
case 1: { output.uv = input.uv2uv3.zw; }
|
|
case 2: { output.uv = input.uv2uv3.xy; }
|
|
case 3: { output.uv = input.uv0uv1.zw; }
|
|
default: {}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
@group(1) @binding(0) var texture1: texture_2d<f32>;
|
|
@group(1) @binding(1) var sampler1: sampler;
|
|
|
|
@group(1) @binding(2) var<uniform> tint: vec3<f32>;
|
|
|
|
@fragment fn main_fragment(input: VertexShaderOutput) -> FragmentShaderOutput {
|
|
var output: FragmentShaderOutput;
|
|
|
|
output.color = pixel_art_sample(texture1, sampler1, input.uv);
|
|
output.color = vec4<f32>(output.color.rgb * tint.rgb, output.color.a);
|
|
|
|
return output;
|
|
}
|
|
|
|
fn pixel_art_sample(input_texture: texture_2d<f32>, input_sampler: sampler, input_uv: vec2<f32>) -> vec4<f32> {
|
|
let dimensions = vec2<f32>(textureDimensions(input_texture));
|
|
|
|
let texture_uv = input_uv * dimensions.xy;
|
|
let sample_uv = (floor(texture_uv) + min(fract(texture_uv) / fwidth(texture_uv), vec2<f32>(1.0, 1.0)) - 0.5) / dimensions.xy;
|
|
|
|
return textureSample(input_texture, input_sampler, sample_uv);
|
|
}
|