硬件相关问题 - Soft8Soft
Description: 学习如何处理与硬件有关的问题和限制。

# 硬件相关问题

本章节描述了在开发web应用过程中可能会遇到的典型的硬件问题， 以及项目实施相关的限制。

- 使用渐变或暗光环境时出现条带伪影
- Too Many Attributes
- 使用程序纹理时出现锯齿问题
- 当两个物体过于靠近时出现相交伪影

#

## 使用渐变或暗光环境时出现条带伪影

在使用渐变或较暗环境中着色时，您可能会遇到类似以下的条带伪影：

这些伪影是由颜色缓冲区的精度有限引起的，可以通过使用抖动技术来缓解（或大幅减少）：

获取在Blender、3ds Max或Maya中启用抖动的说明。

#

## Too Many Attributes

在您的场景运行过程中， 偶尔可能会遇到一些对象没有被渲染的问题， 浏览器控制台会显示如下错误：

"浏览器控制台中出现“Too Many Attributes（属性太多）”错误

这个错误意味着一些对象(很显然， 是那些未被渲染的对象)， 超过了单个着色器可使用的顶点属性的最大数量限制。

一个对象使用多少属性取决于不同的因素： 是否存在形态键(Blender)/变形目标(3ds Max)/混合形状(Maya)及其数量， 是否用到蒙皮， 是否用到特定的材质节点，等等…… /p>

下表解释了如何计算对象所使用属性 的数量:

属性的数量 | 说明
--- | ---
3 | 必要属性： position， normal， uv。
+2x | 每用到1个形状键(Blender)/变形目标(3ds Max)/混合形状目标(Maya)， 则增加两个属性。 此类属性值上限为 +12。
+2 | 如果用到蒙皮则增加两个属性。
+1x | 对象材质中每使用1个不同的 * 顶点颜色时， 为以下节点增加一个属性: Blender: Attribute， Vertex Color
+1x | 当对象材质中使用了不同*的uv贴图时， 每增加一个以下节点（第一个除外， 已包含在必要属性中，见第一行）， 则增加一个属性： Blender: UV贴图(UV Map) 3ds Max: Bitmap(位图)（仅当“映射类型”设置为“纹理”时）， Gradient Ramp(梯度渐变)，Noise(噪波)（仅当“映射”设置为“显式贴图通道”时） Maya: place2dTexture
+1 | 如果对象材质有任意以下节点，每个增加1个属性： Blender: Normal Map, Tangent， (仅计"UV Map"模式) 3ds Max: Normal Bump aiNormalMap, bump2d (仅在"Bump Interp"输入 > 0时计算), samplerInfo
+1 | 如果对象材质有任意以下节点，每个增加1个属性： 3ds Max: 顶点颜色(Vertex Color)

*如果多个节点使用相同的顶点颜色或uv贴图， 则在计算属性极限时，将所有这些节点都计为一个节点。

通常情况下，限制顶点属性在16个以下即可 （尽管某些老旧/低端的设备仅能支持8个顶点属性）。 大部分情况下， 您只需关注使用了多个形态键的对象。 除此之外，特定对象/材质的顶点属性一般都不会突破极限。

#

## 使用程序纹理时出现锯齿问题

在使用过程纹理时，有时你可能会遇到锯齿问题。例如，当使用Checker映射贴图时：

当 Anti-Aliasing 导出设置为 MSAA 或 Auto 时，这种情况就会发生（在任意兼容硬件上，默认设置为 MSAA 4x）。MSAA（多样本抗锯齿）技术可产生不错的图像质量，并且对性能的影响较小。但对于对象颜色突然变化的程序纹理效果不佳。

将 Anti-Aliasing 技术切换为 FXAA 可解决该问题：

FXAA 使用后期处理渲染来减少锯齿，并在这类由程序贴图生成的“边缘”上表现很好。

#

## 当两个物体过于靠近时出现相交伪影

有时您可能会遇到类似下面的情况：

这种现象称之为 z-fighting(z缓冲冲突) (见维基百科名词解释)。当不同的多边形到摄影机的距离相等或非常相近时，就会发生这种情况。

要解决此问题，你可以采用以下方案之一：

- 最直接且简单的解决办法是：将对象彼此位置放远一点。
- 增大摄影机的 near（或 Clip Start）距离，或减小 far（或 Clip End）距离。这将使摄影机的距离范围缩小，从而提高深度缓冲区中存储数值的精度。
- 如果您需要在某个表面上放置billboard纹理——请禁用其材质上的 Depth Test 参数，并增大billboard对象的 Rendering Order 参数。这样billboard对象将在表面对象渲染完成后再渲染，并且忽略了该对象存储的深度。这样可以有效消除两个对象之间可能发生的 z-fighting 。