GPU Gems 1 · Chapter 20. Texture Bombing

用规则 cell 网格、伪随机偏移和邻居采样把小图像或 procedural shape 不规则地散布到 UV 或 object space,减少大面积纹理的重复感。

学习目标

  • 能把 texture bombing 拆成 cell 寻址、伪随机参数、邻居覆盖和最终合成四步
  • 能实现二维四邻居采样,并说明 image 大小、offset 限制和 priority 如何影响 coverage 与遮挡顺序
  • 能把真实小图像替换为 procedural circle、Voronoi-like region 或多图随机选择,并处理 clamp、mipmap 与边界伪影
  • 能比较二维和三维 bombing 的 sample、指令与视觉成本,按目标密度和重复感选择方案

大面积草地、花田、瓦片、鳞片或一整座相似建筑,直接重复一张纹理会暴露规则周期;使用更大的唯一纹理又会增加数据、带宽和制作成本。GPU Gems 1 第 20 章的 Texture Bombing 采用一个规则网格做寻址,再在每个 cell 中放置位置、优先级和图像选择都不同的小元素,让规则只保留在计算结构里,而不直接出现在最终图案中。

的目标不是完全消除 grid,而是把 grid 变成廉价的候选生成器。每个像素先找到自己所在 cell,再读取该 cell 的随机参数,最后检查可能跨界的邻居;因此它可以替换真实 image,也可以生成圆、斑点、鳞片或细胞区域。

texture bombing:用规则寻址制造不规则细节UV gridfloor(UV × scale)cell datarandom.xy + woffset + priorityneighborscurrent + adjacent4 or 9 cellscompositeimage / shapecell 坐标稳定,cell 参数变化,重复纹理因此不再显眼
规则网格只是寻址结构;视觉变化来自每个 cell 的伪随机位置、优先级、密度、缩放、旋转和图像选择。

1. cell 坐标与 cell 内 offset

将连续 UV 变成可寻址的整数网格。设 scale 控制 cell 密度,则像素的 cell 与 cell 内 offset 为:

float2 scaledUV = UV * scale;
int2 cell = floor(scaledUV);
float2 offset = scaledUV - cell;

cell 用作随机参数的索引,offset 用来访问 image。相邻 cell 的整数坐标差一个单位,因此可以用固定偏移枚举邻居。这里的 scale 不是图像缩放本身,而是决定单位 UV 中包含多少候选 cell;提高 scale 会增加细节数量,也会让每个 image 可用的像素更少。

可以把 integral cell name 映射到近似不相关的值。二维随机纹理的坐标不需要神秘常数,只要相邻 cell 不落在同一个 texel、并且不会形成明显短周期即可:

float2 randomUV = cell * float2(0.037, 0.119);
float4 random = tex2D(randomTex, randomUV);
float2 imageOffset = random.xy;
float priority = random.w;

random 的不同通道可以承担不同职责:xy 控制 image 位置,z 选择多图纹理中的某一张,w 作为 priority 或出现概率。为 image 采样时,要把 imageOffset 从 cell 内 offset 中扣除;image 的 alpha 可以表示透明或不透明,从而决定是否覆盖背景。

2. 邻居采样:先保证 coverage,再压缩成本

若 image 不大于 cell,且它的 opaque 区域始终落在 cell 内,边界附近仍可能受到邻居 image 的影响。没有额外限制时,需要检查当前 cell 周围的九个 cell;如果规定 offset 只向一个固定方向跨界,且 image 尺寸不超过 cell,则可以只检查当前 cell 与三个方向邻居,共四个候选。

float4 color = background;
float bestPriority = -1.0;
 
for (int i = -1; i <= 0; ++i) {
  for (int j = -1; j <= 0; ++j) {
    int2 candidateCell = cell + int2(i, j);
    float2 candidateOffset = offset - float2(i, j);
    float2 randomUV = candidateCell * float2(0.037, 0.119);
    float4 random = tex2D(randomTex, randomUV);
    float4 image = tex2D(imageTex, candidateOffset - random.xy);
    if (image.a > 0.0 && random.w > bestPriority) {
      color = image;
      bestPriority = random.w;
    }
  }
}

代码中的四邻居不是一个可以无条件复制的常数:image 被放大、旋转、offset 范围改变或 opaque 区域进入更多角落时,候选集合也要扩大。为了避免多次真实 image texture read,procedural shape 可以先保存 winner 的坐标,循环结束后只做一次最终颜色 lookup;依赖 alpha 判断的真实 image 则不一定能使用这个优化。

neighbor sampling:修复 cell 边界的截断cellcellcellcellpixelcellcellcellcellimage crosses edgecandidate cells9 cells:无大小限制4 cells:受限 imagepriority 决定重叠谁在上面先证明 coverage 边界,再用更少 texture samples 优化
四候选优化依赖明确限制:image 不大于 cell,offset 在 cell 内,且只会向固定方向跨界;放宽限制就必须扩大邻居集合。

如果要让重叠结果有稳定层次,priority 比访问顺序更重要。priority 可以表示前后关系,也可以设置初值来控制出现概率:例如初始阈值提高后,部分 image 会被拒绝,密度自然降低;这种 rejection 仍然要经过 coverage 和性能测试。

3. image、procedural shape 与多样性

真实 image 的 alpha 能提供精细花朵、瓦片或树叶轮廓,但它需要多次 dependent texture samples。程序形状可以用 cell 内距离平方判断,例如把中心移到 (0.5, 0.5) 后检查 dot(p, p) 是否落在半径平方内;这样可以把最终颜色 sample 移出内部循环,并很适合圆、斑点与简单鳞片。

image 选择也可以增加变化:将多个小图横向打包,用 random.z 计算整数 index,再把 x 坐标限制在所选子图区域;子图之间要有足够边框,mipmap 每一级也要保留边框,否则边界颜色会从相邻子图渗入。静态 image 可以使用 CLAMP 防止越界 ghost sample;动画 image 的 random 参数若使用 LINEAR,运动更平滑,但随机值的方差会被压低。

随机 scale 和 rotation 要服从邻居范围。若旋转后的 opaque 圆盘进入 cell 角落,四邻居假设可能漏掉它;要么缩小 image,要么扩大候选 cell。视差、法线和简单 diffuse factor 也可以作用在 procedural 3D bombing 的形状上,让球和体积元素不再只是平面圆。

4. priority 与 Voronoi-like cellular 方法

让重叠 compositing 有可解释的 winner。随机 w 可以形成鳞片或瓦片的遮挡层;将 priority 换成到 cell 内随机点的距离平方,则能生成 Voronoi-like regions,并且不需要计算平方根。

的简化算法先把 priority 设为很大,再对候选点计算 radius2 = dot(offset, offset);距离更小的点覆盖当前结果。严格的 Voronoi 区域可能需要检查更远的 cell,因为第二邻居有时会比已检查的近邻更近;增加每 cell 的样本数可以降低这种错误出现的概率,也能减弱矩形 grid 感。

priority:从重叠图像到 Voronoi-like cellsp₁p₂p₃p₄choose winnerrandom.w → prioritydistance² → Voronoi最小 distance² 赢得 pixel更多样本可减少 grid 感priority 让重叠结果可解释,避免“最后测试者永远在最上面”
priority 不只可以是随机深度,也可以是距离平方;后者会形成 Voronoi-like cellular 图案,并省掉开方。

这类 cellular 结果适合裂纹、皮肤、干泥和叶片等需要空间变化但不要求精确几何边界的材质。不要把近似区域当成严格的几何分割:边界统计、sample 数和 cell scale 改变时,结果会随之变化,必须用目标纹理分辨率重新校准。

5. 二维、三维与性能预算

把 UV 网格换成 object-space unit cube。二维四邻居可能只需四次候选,二维九邻居覆盖更安全,而三维受限的邻居集合也通常需要八次访问;每次访问都可能包含 random sample、image 或 shape 计算。

主要成本来源包括 dependent texture read、重复执行候选 shading、每 cell 的多个 image、寄存器压力和最终颜色采样。可以按以下顺序优化:

  1. 先证明 image 大小与 offset 限制,再从九候选缩减到四候选。
  2. 对 procedural shape 保存 winner 坐标,把最终 color lookup 移到循环外。
  3. 用 random.w 做 rejection 或减少每 cell 的 sample 数,但记录密度变化。
  4. 让坐标保持 full precision,颜色和中间值在目标 framebuffer 允许时再评估 half 或 fixed precision。
performance budget:coverage 与 samples 的交换低成本高成本4-cell 2D4 image samples9-cell 2Dcoverage safe8-cell 3D3D neighborsprocedural shape 可先存最终坐标,循环外只做一次 color lookup
texture bombing 的成本主要来自依赖 texture reads、邻居数量、每 cell 的候选数量和重复颜色采样;先定义覆盖约束,再决定优化空间。

动画时可以让 random lookup 坐标随时间缓慢变化,但要注意 bilinear random 的 ramp-like 运动和人眼对方向断点的敏感性。静态材质优先稳定与低成本,动态材质再选择平滑随机参数,不能只凭一帧截图判断质量。

6. 动手实验:从“重复”调到“丰富”

先预测四个变化:提高 density 会减少空洞但增加重叠和成本;增大 image size 会让 coverage 更完整却需要更多邻居;提高 cell scale 会增加元素数但让单个 image 更小;从二维四邻居切到三维或九邻居会提高成本并降低边界漏采样。

Texture Bombing Lab

先猜:image 变大时,为什么要检查更多邻居?

可交互
UV-space 2D bombing4 samplescoverage 0.61 · repetition 0.20 · cost 0.51规则 grid 可见,但随机 offset、density 和 priority 打破重复

观察:image 接近 cell 边界或变大时,四邻居可能漏掉 coverage;提高 density 会减少空洞但增加成本;3D 模式要检查更多 unit cube 邻居。

这个实验使用确定性的示意点,不替代真实 image texture 的 alpha 和 mipmap 测试。工程验收应覆盖静态重复感、cell 边界、image 旋转、透明边框、多图 atlas、动画 random、目标分辨率和 shader 指令数。

小结:把重复变成可控的随机变化

  • texture bombing 用规则 cell 寻址,把 image 或 procedural shape 以伪随机位置散布到大面积表面。
  • cell coordinates、cell 内 offset 和 pseudo-random texture 是基础数据流;xy 可控制位置,z 可选图,w 可做 priority 或概率。
  • image 靠近 cell 边界时必须检查邻居;四邻居需要受限 image,九邻居更安全但更贵。
  • priority 解耦重叠顺序与访问顺序,Voronoi-like regions 则把距离平方作为 winner 条件。
  • procedural 3D bombing 更有体积感却需要更多邻居;先验证 coverage,再用候选数、最终 sample 和精度策略做性能优化。

练习

问题 1|改 Demo 代码 当前 shader 只采样当前 cell,花朵在 cell 边缘被切断。请把它改为四邻居采样,并说明 image 尺寸与 offset 必须满足的限制。

问题 2|推导题 一个像素所在 cell 的 scaledUV(3.35, 1.72),scale 已经应用。请写出 cell 坐标和 cell 内 offset;如果 imageOffset 是 (0.20, 0.60),采样坐标的基本形式是什么?

问题 3|独立实现题 为一片需要叶片密度可控、远景不重复、近景不出现明显 grid 的地面设计 texture bombing。请选择 2D 或 3D、邻居数量、priority、随机纹理过滤,并列出性能与视觉验证项。

名词解释

本章出现的专业名词,用大白话再讲一遍。

texture bombing
将小图像或程序形状以伪随机位置放入规则 cell 并合成出不规则细节的程序化纹理技术。
cell coordinates
由缩放 UV 取 floor 得到的整数网格坐标,用于索引相邻 cell 的参数。
pseudo-random texture
将 cell 坐标映射到偏移、颜色、priority 或图像索引等参数的随机纹理。
priority
决定重叠候选的前景顺序、出现概率或距离 winner 的值。
procedural 3D bombing
在 object-space unit cube 中进行三维 cell 寻址和邻居采样的 bombing 变体。
Voronoi-like regions
以到随机特征点的距离平方选择 winner,近似生成细胞分区的图案。

资料与写作方式声明

本章以GPU Gems 1 · Chapter 20. Texture Bombing公开完整正文核定章节范围、事实坐标与时代语境,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…