如何以程序方式渲染不规则形状的保健棒?


35

传统的矩形或基于心脏的健康栏的问题已得到很好的理解,并且很容易解决。但是,像我在下面制作的样机那样,更“创意形状”的健康条的公认解决方案是什么?

空健康 完全健康,部分健康

这样做的明显方法是让“精灵”处于“中间”状态,因此第三个图像将是它自己的精灵,以及许多其他针对不同级别的健康的过渡。但是,这似乎非常微不足道,在健康状态之间建立平稳过渡所需的中间次数将很大。

我唯一能想到的想法是将“完全健康”子图覆盖在“空健康”子图和预先烘焙的像素坐标集上,以代表每个健康点,然后使它们像健康一样不透明或透明上升或下降。

我希望这个问题与语言和平台无关,但如果有帮助,可以随时以任何语言/库/框架提供具体示例。


5
“儿子N̶a̶n̶o̶m̶a̶c̶h̶i̶n̶e̶s̶着色器”
Mukesh Ingham

我觉得过渡可以用数学定义,从那里您可以让计算机计算要显示/隐藏的像素坐标,而不是预先烘焙它们
理查德·廷格2016年

心形保健棒如何“轻松解决”?
MooseBoys

1
@MooseBoys我在谈论基于心脏的健康,而不是心脏型。想想《塞尔达传说》游戏。抱歉,不清楚。
msd7734 '16

@RichardTingle,好主意:)
乔恩

Answers:


48

有一种非常简单的方法可以使用着色器实现此目的,您需要三种*纹理:空的健康条,健康条纹理和蒙版,并在其一端具有一个极端(例如,最暗而不是黑色或最透明的alpha值),并且具有一个极端的健康分布梯度。在另一端。最好在图像上显示出来,我目前无法绘制仅线性的曲线渐变-但我敢肯定您的美术师不会有任何麻烦: 在此处输入图片说明 现在,在着色器中对纹理进行采样并为蒙版值设定阈值,并丢弃所有非像素比输入阈值亮(基于健康状况着色器输入百分比)。
可以使用数学公式而不是纹理来进行遮罩,但是如果您这样做,您仍然会非常受限于可以使用所述公式创建的形状(简单的形状),而且找到一个形状并非易事。
* 查看评论


9
在很多情况下(包括OP的示例),使用单独的纹理作为颜色是过分的。在大多数情况下,您可以将灰度蒙版渐变重新映射为指定为着色器均匀性的颜色,同时仍丢弃低于特定阈值的任何蒙版值。
bcrist

1
实际上,您不需要最暗而不是黑色,可以使用Alpha通道来滤除不需要的像素。
杰克·艾德利

1
@JackAidley肯定这是可能的,但是我希望该解决方案尽可能灵活-在大多数AAA称号中,您没有hp只是“红色”,但它具有纹理。
温德拉

1
@bcrist好点,我考虑建议将其作为优化。但是我无法正确绘制它,因此我决定将其保持尽可能简单,而将优化留给实现。
温德拉

@wondra在很多情况下,包括在OP中的示例外观,您都可以使用过程渐变或一维颜色查找(以遮罩级别作为输入),而不是纹理。
Random832 '16

34

作为像素着色器以数学方式实现:

在CPU上,使用V2计算HealthDirection及其点积 在此处输入图片说明

在GPU上,为每个像素计算远离中心点的归一化方向。将每个点产品与HealthDirections进行比较,以选择是对“背景”进行着色还是对颜色进行着色。 在此处输入图片说明

如果“反转”此算法并从另一个方向进行工作,则可以将每个像素的方向“解压”回一个百分比,然后将它们与HealthPercent进行比较。计算每个像素的百分比后,在GPU上执行从红色到绿色的渐变变得微不足道。

首先将算法应用于四边形绘制一条线;输出rangeMin和rangeMax之间的颜色(可以烘焙)和clip()或在其他位置输出透明颜色。接下来,使用Alpha在其上绘制(修改的)精灵。我用CAD追踪了您的条形图,对其进行了填充,然后“神奇地消失”了Paint中的纯色形状以将其删除。由于手工混合了AutoCAD和Paint,因此矿山看起来像废话。假设您将内部边缘混合为透明的,则您的外观会很完美

白色边框是四边形的界限。它和红色的X仅供参考:

在此处输入图片说明

不需要与运行状况栏同时渲染“带孔的精灵”。在完成所有健康状况指示条之后,应立即实例化它们并绘制它们。由于该算法是独立存在于着色器中的,因此您还可以为其添加实例化,然后还可以通过一个实例化的绘制调用来绘制所有运行状况栏。在屏幕上绘制每个运行状况栏应进行2次DrawInstanced(...)调用,并且“抓狂”。


1
如果要以这种圆形方式进行遮罩,则可以通过简单地更改绘制为圆形渐变的三角形来更有效地实现它。
杰克·艾德利

@JackAidley,请更具体一些,因为我不考虑这种掩盖;第一次通过后,进度条仅在两个三角形上完全渲染,没有采样。Sprite恰好在其中有一个洞,最终使整个事物“漂亮”。(这是一种掩盖,但不是算法的组成部分吗?)谢谢
Jon

您正在执行的操作等效于在已经具有灰色位置的背景精灵上绘制彩色条的遮罩版本。因为您的方法需要自定义着色器,并且写入每个像素,所以比仅绘制形状的所需部分要慢得多。
杰克·艾德利

@JackAidley,但是没有背景精灵吗?仅使用float3世界上的四个位置绘制彩虹;没有紫外线,没有“背景精灵”。另外,您担心像素着色器会陷入一些微小的四边形的困境吗?此外,RangeMin和RangeMax会立即剪辑其中的大多数片段。
2016年

您将需要背景精灵才能获得原始图像中所示的边框。如果您省略这些,那么是的,方法是不同的。
杰克·艾德利
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.