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

GLSL中如何缩放纹理图集指定纹理并保持偏移

在GLSL中缩放纹理图集内的特定纹理(不显示其他纹理)

假设你有一个4x4的纹理图集(共16个纹理,每个纹理占图集的1/4区域),已经能通过索引定位到目标纹理,但直接缩放UV会导致纹理位置偏移,甚至采样到图集中的其他纹理。需要实现的是:保持目标纹理的原始偏移位置,单独对其进行放大/缩小,且不显示图集中的其他内容。

你当前的代码能定位到目标纹理,但直接缩放newUv会出现问题:

float scale   = 1.0/4.0;
vec2 offset   = vec2(1.0,2.0);
vec2 newUv    = (vUv+offset)*scale;
// 直接缩放会导致位置偏移、采样到其他纹理
// vec2 scaledUp = newUv*.8;
// vec2 scaledDown = newUv*2.0;

核心解决方案

要实现正确的缩放,需要把UV坐标拆分为图集全局坐标和目标纹理的局部坐标:先对局部坐标做缩放变换,再映射回全局坐标,同时限制UV范围避免越界。

代码示例(中心对齐缩放,推荐)

这种方式会以目标纹理的中心为原点进行缩放,保持纹理在原位置中心放大/缩小:

// 纹理图集是4x4,单个纹理格子的尺寸占图集的1/4
float tileSize = 1.0 / 4.0;
// 目标纹理在图集中的索引(x:1, y:2,对应你要定位的纹理位置)
vec2 tileIndex = vec2(1.0, 2.0);
// 缩放系数:>1是放大,<1是缩小
float textureScale = 2.0;

// 1. 计算目标纹理在图集中的起始UV坐标(格子的左上角)
vec2 tileStartUV = tileIndex * tileSize;

// 2. 将原始vUv(0-1范围,对应目标纹理的局部空间)转换为中心原点的坐标,再缩放
vec2 centeredLocalUv = vUv - 0.5;   // 把局部UV的原点移到纹理中心
vec2 scaledLocalUv = centeredLocalUv * textureScale; // 对局部UV进行缩放
scaledLocalUv += 0.5;               // 把原点移回局部UV的左上角

// 3. 将缩放后的局部UV转换为图集的全局UV坐标
vec2 finalUv = tileStartUV + scaledLocalUv * tileSize;

// 4. 可选但推荐:限制UV在目标纹理范围内,防止纹理过滤时采样到其他纹理
finalUv = clamp(finalUv, tileStartUV, tileStartUV + tileSize);

// 采样纹理并输出颜色
vec4 texColor = texture2D(u_tex, finalUv);
gl_FragColor = vec4(texColor.rgb, 1.0);

简化版(左上角对齐缩放)

如果你的需求是保持纹理左上角对齐缩放(而非中心对齐),可以用更简洁的代码:

float tileSize = 1.0 / 4.0;
vec2 tileIndex = vec2(1.0, 2.0);
float textureScale = 0.8;

vec2 tileStartUV = tileIndex * tileSize;
// 直接缩放局部UV,再映射到全局坐标
vec2 scaledLocalUv = vUv * textureScale;
vec2 finalUv = tileStartUV + scaledLocalUv * tileSize;

// 限制UV范围,避免采样到其他纹理
finalUv = clamp(finalUv, tileStartUV, tileStartUV + tileSize);

gl_FragColor = vec4(texture2D(u_tex, finalUv).rgb, 1.0);

关键说明

  • 为什么不能直接缩放全局UV?因为newUv是图集的全局坐标,直接缩放会连偏移量一起放大/缩小,导致目标纹理的位置偏移,甚至跑到其他格子区域,采样到无关纹理。
  • clamp的作用:如果使用线性过滤或mipmap,纹理边缘的采样可能会超出目标格子的范围,用clamp限制UV后,边缘会重复采样目标纹理的边缘像素,不会显示其他纹理的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 13:58:11