2021-12-09 15:45:03 +00:00
|
|
|
struct Uniforms {
|
2022-03-28 14:31:22 +00:00
|
|
|
u_scale : vec2<f32>,
|
|
|
|
u_offset : vec2<f32>,
|
2021-06-21 19:27:26 +00:00
|
|
|
};
|
2022-01-19 22:46:57 +00:00
|
|
|
@binding(0) @group(0) var<uniform> uniforms : Uniforms;
|
2021-06-21 19:27:26 +00:00
|
|
|
|
|
|
|
struct VertexOutputs {
|
2022-03-28 14:31:22 +00:00
|
|
|
@location(0) texcoords : vec2<f32>,
|
|
|
|
@builtin(position) position : vec4<f32>,
|
2021-06-21 19:27:26 +00:00
|
|
|
};
|
|
|
|
|
2022-01-19 22:46:57 +00:00
|
|
|
@stage(vertex) fn vs_main(
|
|
|
|
@builtin(vertex_index) VertexIndex : u32
|
2021-06-21 19:27:26 +00:00
|
|
|
) -> VertexOutputs {
|
|
|
|
var texcoord = array<vec2<f32>, 3>(
|
|
|
|
vec2<f32>(-0.5, 0.0),
|
|
|
|
vec2<f32>( 1.5, 0.0),
|
|
|
|
vec2<f32>( 0.5, 2.0));
|
|
|
|
|
|
|
|
var output : VertexOutputs;
|
|
|
|
output.position = vec4<f32>((texcoord[VertexIndex] * 2.0 - vec2<f32>(1.0, 1.0)), 0.0, 1.0);
|
|
|
|
|
|
|
|
// Y component of scale is calculated by the copySizeHeight / textureHeight. Only
|
|
|
|
// flipY case can get negative number.
|
|
|
|
var flipY = uniforms.u_scale.y < 0.0;
|
|
|
|
|
|
|
|
// Texture coordinate takes top-left as origin point. We need to map the
|
|
|
|
// texture to triangle carefully.
|
|
|
|
if (flipY) {
|
|
|
|
// We need to get the mirror positions(mirrored based on y = 0.5) on flip cases.
|
|
|
|
// Adopt transform to src texture and then mapping it to triangle coord which
|
|
|
|
// do a +1 shift on Y dimension will help us got that mirror position perfectly.
|
|
|
|
output.texcoords = (texcoord[VertexIndex] * uniforms.u_scale + uniforms.u_offset) *
|
|
|
|
vec2<f32>(1.0, -1.0) + vec2<f32>(0.0, 1.0);
|
|
|
|
} else {
|
|
|
|
// For the normal case, we need to get the exact position.
|
|
|
|
// So mapping texture to triangle firstly then adopt the transform.
|
|
|
|
output.texcoords = (texcoord[VertexIndex] *
|
|
|
|
vec2<f32>(1.0, -1.0) + vec2<f32>(0.0, 1.0)) *
|
|
|
|
uniforms.u_scale + uniforms.u_offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2022-01-19 22:46:57 +00:00
|
|
|
@binding(1) @group(0) var mySampler: sampler;
|
|
|
|
@binding(2) @group(0) var myTexture: texture_2d<f32>;
|
2021-06-21 19:27:26 +00:00
|
|
|
|
2022-01-19 22:46:57 +00:00
|
|
|
@stage(fragment) fn fs_main(
|
|
|
|
@location(0) texcoord : vec2<f32>
|
|
|
|
) -> @location(0) vec4<f32> {
|
2021-06-21 19:27:26 +00:00
|
|
|
// Clamp the texcoord and discard the out-of-bound pixels.
|
|
|
|
var clampedTexcoord =
|
|
|
|
clamp(texcoord, vec2<f32>(0.0, 0.0), vec2<f32>(1.0, 1.0));
|
|
|
|
if (!all(clampedTexcoord == texcoord)) {
|
|
|
|
discard;
|
|
|
|
}
|
|
|
|
|
|
|
|
var srcColor = textureSample(myTexture, mySampler, texcoord);
|
|
|
|
// Swizzling of texture formats when sampling / rendering is handled by the
|
|
|
|
// hardware so we don't need special logic in this shader. This is covered by tests.
|
|
|
|
return srcColor;
|
|
|
|
}
|