简体   繁体   中英

Metal Compute kernel scale image

I am slightly confused how to apply scaling operation in output texture when using compute shader. For instance,

   kernel void testCompute   (texture2d<half, access::read>  inputTexture  [[ texture(0) ]],
                   texture2d<half, access::write> outputTexture [[ texture(1) ]],
                   uint2 gid [[thread_position_in_grid]])
 {
    if ((gid.x >= inputTexture.get_width()) || (gid.y >= inputTexture.get_height())) {
    return;
}

   half4 inputColor = inputTexture.read(gid);

    half4 outputColor = half4(inputColor.r, 0.0, inputColor.b, 1.0);

    outputTexture.write(outputColor, gid);  
}

Does the compute shader above assumes equal size of input and output texture? If I use a vertex and fragment shader, I can configure a sampler with filter::linear and the output texture comes out scaled according to it's size. How do we achieve the same thing with Compute shader?

The compute shader does not make any assumptions about the textures.

Your app code determines the size of the grid over which the compute shader operates when it dispatches it. The grid is an abstract notion. It does not necessarily relate to anything else. It's up to you how you interpret / give meaning to the grid.

Your shader is invoked once per position within the grid and the position can be provided to the shader function, as you've arranged with your gid parameter.

Your shader is, due to the way you've coded it, interpreting the position as both a coordinate within the input texture (because you're passing it to the read() function) and a coordinate within the output texture (because you're passing it to the write() function). Therefore, as it's currently written, your shader does not scale the image. It assumes the output texture is at least as large as the input and it just copies the input to the upper-left portion of the output.

If you want to perform scaling, you would generally make the grid the size of the output texture, so you compute something for each texel within it. Then, you have to explicitly scale the position to read from the corresponding position within the input texture. Actually, if you want filtering, you would need to sample the input texture, not just read.

To perform that scaling of the position, you can use the sizes of the two textures.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM