最近我在 Unity 中开发了一款 LED 墙壁渲染器,并已在 Asset Store 上发布。更有趣的部分并不是编写 UI(虽然它仍然很好!),而是渲染设置。以下是一些可能对其他人有用的实现注意事项。
1. 不要渲染每个 LED 为几何体
该板块被表示为一个逻辑纹理,例如 192 x 108 发射器。内容首先被组合到纹理中,然后 shader 重构可见的 LED 细胞。
该 shader 使用板块 UV、逻辑分辨率和发射器单元坐标来绘制 LED 形状。这样就可以支持圆形、正方形或六边形发射器,而不需要生成数千个网格。
有用的分离是:
- C# 拥有板块分辨率、渲染纹理、布局、时间和源更新。
- shader 拥有发射器重构、间隔、衰减、亮度响应、缝隙和距离混合。
这也避免了大显示器上的巨大 GameObject 或网格数量的问题。
2. 硬件缺陷更好地作为一个单独的遮罩
缺陷并没有被烘焙到源内容中。板块有一个单独的缺陷纹理/遮罩,shader 在呈现最终 LED 输出时采样这个缺陷。
这个遮罩可以编码如下内容:
- 死的发射器
- dim 发射器
- 卡住的颜色
- 闪烁参数
- 线或柜台故障
源纹理保持清洁。缺陷通道修改了模拟硬件输出。这使得重用相同的内容在不同板块条件下变得更容易,并且通过种子使过程缺陷变得确定。
3. 多面板板块组合一次,然后切割
对于视频墙或长条板,各个面板不应独立组合相同的内容。这会导致同步和对齐问题。
我最终使用的设置是:
- 找到子板块控制器。
- 从所有子逻辑分辨率中计算一个主分辨率。
- 添加可选的边框像素。
- 将布局一次性组合到一个主 RenderTexture 中。
- 将主纹理切割成每个面板的渲染纹理。
- 将每个切片传入子板块。
每个子板块仍然拥有其材质、shader设置和缺陷配置,但内容保持连续在整个墙壁上。
4. 跨管道shader需要共享的核心逻辑
板块shader支持 Built-in、URP 和 HDRP。最不痛苦的设置是将 LED 数学放在共享 HLSL 包括中,并且使每个管道的通道尽可能地薄。
共享包包括处理发射器重构、缝隙数学、亮度响应和缺陷应用。每个 shader 通道处理管道特定的包包括、标签、混合状态和输出约定。
我还添加了检查器测试,检查 shader 源代码是否有回归,例如:
- HDRP 包括顺序
- 正确的通道标签
- 缺陷逻辑存在于 Built-in 通道中
- 缝隙宽度保持在发射器单位中,而不是任意 UV 缩放
这不是高级测试,但它捕捉了通常只有在导入到另一个渲染管道后才会出现的 shader 漏洞。
主要的架构性教训是保持系统分层:C# 中的逻辑板块组合、硬件模拟通过遮罩和板块状态以及 shader 中的可视 LED 重构。这样做使实现更容易测试,并且在板块大小和渲染管道之间保持一致性变得更加容易。
评论 (0)