第 11 章练习:纹理采样与坐标变形

对应教程:11 纹理采样与坐标变形
起始示例:纹理坐标变形,修改 11-texture-warp.js 和需要时的 11-texture-warp.html。

练习 1:预测采样方向

**目标:**假设图片上有一条横线,原图位于 imageUv.y = 0.6。若写 sampleUv.y = vUv.y + 0.1,它会出现在目标平面的哪个 vUv.y?若改成减 0.1 呢?

**完成标准:**能解释为什么采样坐标上移,图片内容反而下移。

练习 2:加一个水平波浪模式

**目标:**新增第四种变形方式,使图片内容沿水平方向周期性摆动,并能用现有强度与周期数控件调节。

**要求:**偏移量由 vUv.y 和时间决定;沿 x 修改 sampleUv,不修改网格位置或顶点 UV。用越界提示色检查左右边缘。

**完成标准:**竖直方向不同位置的图片内容左右摆动;切换边界模式时,左右边缘分别显示夹住、平铺和提示色。

练习 3:局部放大镜

**目标:**在平面中心做一个半径约 0.25 的放大镜:中心处看见图片更大的内容,半径外保持原图,中间平滑过渡。

**要求:**先在按目标比例修正的二维坐标中算半径;只修改 sampleUv,不要修改网格。放大率约为 2 倍。

**完成标准:**中心内容放大且没有椭圆形边界;与外侧原图平滑衔接。改变浏览器窗口宽高比时,圆形边界仍对应平面本身的比例。

<details><summary>提示</summary>

放大 2 倍意味着从中心向外查询的坐标距离缩小到原来的约一半。

</details>

参考解答


<a id=“reference-answers”></a>

第 11 章练习参考解答

对应练习:纹理采样与坐标变形。

练习 1

若 sampleUv.y = vUv.y + 0.1,要查到原图 y 为 0.6 的线,需要 vUv.y = 0.5,所以内容下移 0.1。若 sampleUv.y = vUv.y - 0.1,则 vUv.y = 0.7,内容上移 0.1。片元着色器是在目标位置反查源图片,不是在移动图片像素。

练习 2

在 HTML 中添加模式 value="3",在片元着色器已有的 uMode 分支末尾添加:

else if ( uMode == 3 ) {
  sampleUv.x += uStrength * sin( TAU * uCycles * vUv.y - 2.0 * uTime );
}

此处 uStrength 是图片 UV x 单位。若右边出现紫色提示色,说明该处向右查询越过了 sampleUv.x = 1.0;左边同理。原有 uBorder 逻辑无需改动。

练习 3

在 HTML 中添加模式 value="4",在片元着色器的模式分支中计算:

else if ( uMode == 4 ) {
  vec2 point = ( vUv - 0.5 ) * vec2( uAspect, 1.0 );
  float influence = 1.0 - smoothstep( 0.20, 0.30, length( point ) );
  vec2 sourcePoint = mix( point, point * 0.5, influence );
  sampleUv = sourcePoint / vec2( uAspect, 1.0 ) + 0.5;
}

中心 influence = 1 时,距离中心的采样距离减半,所以图片内容放大约 2 倍。半径 0.20~0.30 之间逐渐变回原图。圆形范围由比例修正后的 point 定义,因此目标平面宽高不同时仍保持圆形。若希望镜片边界可见,可额外以 length(point) 生成一圈细环遮罩,并在采样颜色之后叠上颜色。