1+ // Include half-precision type aliases (resolves to f16 when supported, f32 otherwise)
2+ #include "halfTypesCS "
3+
14@group (0 ) @binding (0 ) var inputTexture : texture_2d <f32 >;
25@group (0 ) @binding (1 ) var inputTexture_sampler : sampler ;
36@group (0 ) @binding (2 ) var outputTexture : texture_storage_2d <rgba8unorm , write >;
@@ -14,43 +17,43 @@ fn main(@builtin(global_invocation_id) global_id : vec3u) {
1417
1518 // Sample the center pixel
1619 let uvFloat = (vec2f (uv ) + vec2f (0 .5 )) / vec2f (texSize );
17- var color = textureSampleLevel (inputTexture , inputTexture_sampler , uvFloat , 0 .0 );
20+ var color = half4 ( textureSampleLevel (inputTexture , inputTexture_sampler , uvFloat , 0 .0 ) );
1821
1922 // Sobel edge detection using 3x3 kernel
2023 let texelSize = 1 .0 / vec2f (texSize );
2124
22- // Sample 3x3 neighborhood and convert to grayscale
23- var samples : array <f32 , 9 >;
25+ // Sample 3x3 neighborhood and convert to grayscale (using half precision)
26+ var samples : array <half , 9 >;
2427 var idx = 0 ;
2528 for (var y = - 1 ; y <= 1 ; y ++ ) {
2629 for (var x = - 1 ; x <= 1 ; x ++ ) {
2730 let offset = vec2f (f32 (x ), f32 (y )) * texelSize ;
2831 let sampleUV = uvFloat + offset ;
29- let sampleColor = textureSampleLevel (inputTexture , inputTexture_sampler , sampleUV , 0 .0 );
32+ let sampleColor = half3 ( textureSampleLevel (inputTexture , inputTexture_sampler , sampleUV , 0 .0 ) . rgb );
3033 // Convert to grayscale using standard luminance weights
31- samples [idx ] = dot (sampleColor . rgb , vec3f (0 .299 , 0 .587 , 0 .114 ));
34+ samples [idx ] = dot (sampleColor , half3 (0 .299 , 0 .587 , 0 .114 ));
3235 idx ++ ;
3336 }
3437 }
3538
3639 // Sobel horizontal and vertical kernels
3740 // Horizontal: [-1, 0, 1; -2, 0, 2; -1, 0, 1]
38- let gx = - samples [0 ] + samples [2 ] - 2 .0 * samples [3 ] + 2 .0 * samples [5 ] - samples [6 ] + samples [8 ];
41+ let gx : half = - samples [0 ] + samples [2 ] - half ( 2 .0 ) * samples [3 ] + half ( 2 .0 ) * samples [5 ] - samples [6 ] + samples [8 ];
3942
4043 // Vertical: [-1, -2, -1; 0, 0, 0; 1, 2, 1]
41- let gy = - samples [0 ] - 2 .0 * samples [1 ] - samples [2 ] + samples [6 ] + 2 .0 * samples [7 ] + samples [8 ];
44+ let gy : half = - samples [0 ] - half ( 2 .0 ) * samples [1 ] - samples [2 ] + samples [6 ] + half ( 2 .0 ) * samples [7 ] + samples [8 ];
4245
4346 // Calculate edge magnitude
44- let edgeStrength = sqrt (gx * gx + gy * gy );
47+ let edgeStrength : half = sqrt (gx * gx + gy * gy );
4548
4649 // Make edges red: stronger edges = more red
47- let edgeAmount = clamp (edgeStrength * 3 .0 , 0 .0 , 1 .0 );
48- let edgeColor = vec3f (1 .0 , 0 .0 , 0 .0 ); // Red
50+ let edgeAmount : half = clamp (edgeStrength * half ( 3 .0 ), half ( 0 .0 ), half ( 1 .0 ) );
51+ let edgeColor = half3 (1 .0 , 0 .0 , 0 .0 ); // Red
4952
5053 // Blend original color with red edges
51- var finalColor = mix (color . rgb , edgeColor , edgeAmount );
54+ var finalColor : half3 = mix (color . rgb , edgeColor , edgeAmount );
5255
53- // Write to output storage texture (no channel swap - keep edges red )
54- textureStore (outputTexture , vec2i (uv ), vec4f (finalColor , color . a ));
56+ // Write to output storage texture (convert half back to f32 for storage )
57+ textureStore (outputTexture , vec2i (uv ), vec4f (vec3f ( finalColor ), f32 ( color . a ) ));
5558}
5659
0 commit comments