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

Unity3D中Shader与SetPixel制作网格孔洞的坐标适配问题

解决Unity裁剪Shader孔洞坐标适配的错位问题

嘿,我刚好碰到过类似的情况,你这个问题核心就是UV坐标转像素索引时的精度丢失——直接把float类型的UV强转成int会截断小数部分,导致绘制的黑色矩形和射线命中的精确点错位,就出现了你说的和粉色射线点对不上的情况。下面给你几个针对性的解决方案:

1. 用精确的像素映射替代直接强转

别直接(int)uv.x * textureWidth,这种强转会把UV的小数部分直接砍掉,比如0.6*1024=614.4,强转成int就是614,但实际应该映射到614或615像素(取决于纹理的采样方式)。正确的做法是用Mathf.RoundToInt来取最近的像素:

// 假设你的目标纹理是texture2D,射线命中的UV是hitUV
int texWidth = texture2D.width;
int texHeight = texture2D.height;

// 计算精确的像素位置,用RoundToInt对齐到最近像素
int pixelX = Mathf.RoundToInt(hitUV.x * texWidth);
int pixelY = Mathf.RoundToInt(hitUV.y * texHeight);

这样能最大程度减小UV到像素的转换误差,让你的黑色矩形边缘更贴近射线命中点。

2. 对齐Shader裁剪逻辑和纹理绘制范围

你的Shader里的SliceAmount是范围值,要确保它和纹理上的黑色区域严格匹配。比如如果Shader是通过纹理灰度值裁剪(黑色区域被裁掉),那SliceAmount要设置成刚好低于黑色的灰度值(比如黑色是0,就把SliceAmount设为0.1),这样Shader才能准确识别出你绘制的黑色区域作为孔洞:

// Shader片段着色器的裁剪逻辑示例
fixed4 frag(v2f i) : SV_Target
{
    fixed4 texColor = tex2D(_MainTex, i.uv);
    // 只有纹理灰度值大于SliceAmount的区域才保留
    if (texColor.r < _SliceAmount)
        discard;
    return texColor;
}

如果SliceAmount设置不对,哪怕矩形位置准了,Shader也可能裁剪出和预期不符的孔洞。

3. 检查UV空间的原点一致性

Unity里网格的UV原点默认是左下角,但有些情况下(比如用了UI纹理的导入设置),纹理的UV原点会变成左上角,这会直接导致你的绘制位置上下颠倒。要确认射线检测拿到的hit.textureCoord和纹理的UV空间一致:

  • 检查网格的UV映射是否是标准的左下角原点
  • 如果纹理是UI用的,记得翻转Y坐标:
// 翻转UV的Y轴,适配左上角原点的纹理
hitUV.y = 1 - hitUV.y;

4. 用SetPixels批量绘制提升精度

单个SetPixel调用容易出现边缘的微小误差,建议用SetPixels批量绘制矩形区域,这样整个矩形的像素位置会更统一:

// 射线检测得到的起始和结束UV角点
Vector2 startUV = ...;
Vector2 endUV = ...;

int startX = Mathf.RoundToInt(startUV.x * texWidth);
int startY = Mathf.RoundToInt(startUV.y * texHeight);
int endX = Mathf.RoundToInt(endUV.x * texWidth);
int endY = Mathf.RoundToInt(endUV.y * texHeight);

// 计算矩形的宽高(取绝对值避免顺序问题)
int rectWidth = Mathf.Abs(endX - startX);
int rectHeight = Mathf.Abs(endY - startY);

// 创建全黑的像素数组
Color[] blackPixels = new Color[rectWidth * rectHeight];
System.Array.Fill(blackPixels, Color.black);

// 批量设置纹理像素并应用
texture2D.SetPixels(startX, startY, rectWidth, rectHeight, blackPixels);
texture2D.Apply();

批量绘制能避免逐个像素设置的累积误差,让孔洞边缘更整齐,完美贴合射线命中的位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:43:59