You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Metal Compute Shader中输出纹理缩放操作实现疑问

在Metal Compute Shader中实现输出纹理缩放

嘿,看你的代码,现在是直接把输入纹理的每个像素对应到输出纹理的同位置线程,但这没法实现缩放——毕竟缩放时输出和输入纹理的尺寸肯定不一样,线程网格的逻辑得调整下。我给你捋清楚核心逻辑,再改改代码:

核心思路

  • 线程网格的尺寸要和输出纹理的宽高匹配,每个线程负责输出纹理的一个像素
  • 把输出纹理上的线程位置转换成输入纹理的归一化坐标,这样不管是放大还是缩小,都能精准映射到输入的对应区域
  • 用sample方法代替read来采样,还能开启纹理过滤(比如线性插值),让缩放后的画面没那么多锯齿

修改后的完整示例代码

#include <metal_stdlib>
using namespace metal;

kernel void scaledCompute(
    texture2d<half, access::read> inputTexture [[ texture(0) ]],
    texture2d<half, access::write> outputTexture [[ texture(1) ]],
    uint2 gid [[thread_position_in_grid]],
    constant float2& sizeRatio [[ buffer(0) ]] // 传入输入/输出的尺寸比例:(输入宽/输出宽, 输入高/输出高)
) {
    // 先判断当前线程是否在输出纹理范围内,超出就直接返回
    if (gid.x >= outputTexture.get_width() || gid.y >= outputTexture.get_height()) {
        return;
    }
    
    // 1. 把输出线程位置转成归一化坐标(0~1范围,对应输出纹理的整个区域)
    float2 outputUV = float2(gid) / float2(outputTexture.get_width(), outputTexture.get_height());
    
    // 2. 转换为输入纹理的归一化坐标——这里用传入的尺寸比例做映射
    // 比如输出比输入大(放大),比例会小于1,inputUV会覆盖输入的完整区域;缩小则反之
    float2 inputUV = outputUV * sizeRatio;
    
    // 3. 配置采样器:用线性过滤让缩放更平滑,超出边界的部分 clamp 到边缘
    constexpr sampler s(coord::normalized, filter::linear, address::clamp_to_edge);
    half4 inputColor = inputTexture.sample(s, inputUV);
    
    // 4. 写入输出纹理(这里可以加你自己的颜色处理逻辑,比如你之前写的取红通道之类的)
    half4 outputColor = half4(inputColor.rgb, inputColor.a);
    outputTexture.write(outputColor, gid);
}

关键细节要注意

  • 线程网格配置:在CPU端设置Compute Pipeline的线程网格时,一定要传输出纹理的宽高,比如MTLSizeMake(outputWidth, outputHeight, 1),不然线程数量不对,缩放肯定出问题
  • 尺寸比例计算:sizeRatio要在CPU端算好传入,比如输入宽100、输出宽200,那x分量就是100.0/200.0=0.5;如果是等比例缩放,直接用同一个比例就行
  • 采样器选择:如果要硬边缘的像素风格缩放,可以把filter::linear改成filter::nearest,但线性过滤的平滑效果更适合大多数场景
  • 你之前代码里half4 outputColor = half4(inputColor.r, 0.0...没写完,我这里保留了原颜色,你可以根据需求修改,比如只保留红通道的话就写成half4(inputColor.r, 0.0, 0.0, inputColor.a)就行

内容的提问来源于stack exchange,提问作者Deepak Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:35:28