ng texture to triangle firstly then adopt the transform. output.texcoords = (texcoord[VertexIndex] * vec2(1.0, -1.0) + vec2(0.0, 1.0)) * uniforms.scale + uniforms.offset; } return output; } @binding(1) @group(0) var mySampler: sampler; @binding(2) @group(0) var myTexture: texture_2d; @fragment fn fs_main( @location(0) texcoord : vec2 ) -> @location(0) vec4 { // Clamp the texcoord and discard the out-of-bound pixels. var clampedTexcoord = clamp(texcoord, vec2(0.0, 0.0), vec2(1.0, 1.0)); // 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. var color = textureSample(myTexture, mySampler, texcoord); if (!all(clampedTexcoord == texcoord)) { discard; } let kUnpremultiplyStep = 0x01u; let kDecodeToLinearStep = 0x02u; let kConvertToDstGamutStep = 0x04u; let kEncodeToGammaStep = 0x08u; let kPremultiplyStep = 0x10u; let kDecodeForSrgbDstFormat = 0x20u; let kClearSrcAlphaToOne = 0x40u; // Unpremultiply step. Appling color space conversion op on premultiplied source texture // also needs to unpremultiply first. // This step is exclusive with clear src alpha to one step. if (bool(uniforms.steps_mask & kUnpremultiplyStep)) { if (color.a != 0.0) { color = vec4(color.rgb / color.a, color.a); } } // Linearize the source color using the source color space’s // transfer function if it is non-linear. if (bool(uniforms.steps_mask & kDecodeToLinearStep)) { color = vec4(gamma_conversion(color.r, uniforms.gamma_decoding_params), gamma_conversion(color.g, uniforms.gamma_decoding_params), gamma_conversion(color.b, uniforms.gamma_decoding_params), color.a); } // Convert unpremultiplied, linear source colors to the destination gamut by // multiplying by a 3x3 matrix. Calculate transformFromXYZD50 * transformToXYZD50 // in CPU side and upload the final result in uniforms. if (bool(uniforms.steps_mask & kConvertToDstGamutStep)) { color = vec4(uniforms.conversion_matrix * color.rgb, color.a); } // Encode that color using the inverse of the destination color // space’s transfer function if it is non-linear. if (bool(uniforms.steps_mask & kEncodeToGammaStep)) { color = vec4(gamma_conversion(color.r, uniforms.gamma_encoding_params), gamma_conversion(color.g, uniforms.gamma_encoding_params), gamma_conversion(color.b, uniforms.gamma_encoding_params), color.a); } // Premultiply step. // This step is exclusive with clear src alpha to one step. if (bool(uniforms.steps_mask & kPremultiplyStep)) { color = vec4(color.rgb * color.a, color.a); } // Decode for copying from non-srgb formats to srgb formats if (bool(uniforms.steps_mask & kDecodeForSrgbDstFormat)) { color = vec4(gamma_conversion(color.r, uniforms.gamma_decoding_for_dst_srgb_params), gamma_conversion(color.g, uniforms.gamma_decoding_for_dst_srgb_params), gamma_conversion(color.b, uniforms.gamma_decoding_for_dst_srgb_params), color.a); } // Clear alpha to one step. // This step is exclusive with premultiply/unpremultiply step. if (bool(uniforms.steps_mask & kClearSrcAlphaToOne)) { color.a = 1.0; } return color; }