Download

The Mathematic Principle Of Curved HUD

我最初想要做一个类似明日方舟的初始界面的 HUD,然后搜到了曲面 HUD 的实现方法。虽然 UV 偏移的方法会让按钮渲染位置并不等于实际输入检测位置,导致它的实用性降低,但是我还是希望弄懂他的原理,以便按照我的喜好更改。
捣腾了好久,从弄懂 TexCoord 的含义开始,终于理解了 UMG parabolic distortion effect - UE4 AnswerHub 中讲解的曲线 HUD 的原理。看网上没有关于这个原理讲解,就想着发一篇文章hhh

首先我们知道,改变 UV 坐标,就改变了从纹理渲染到游戏中的实体的坐标。在 HUD 中,texcoord 就是纹理的 UV 坐标。要做一个曲线 HUD 的效果,就要改变 HUD 的 UV 坐标。
观察这个曲线 HUD,很难说它在 U 方向有没有改变,但是你能肯定他在 V 方向上移动了一段距离,如果要拆解它的原理,你起码要知道他在 V 方向移动的原理。

I initially wanted to make a HUD which is similar to the initial interface of Tomorrow’s Ark, and then I found out the way to implement the curved HUD. Although the UV offset method will make the button rendering position not equal to the actual input detection position, which reduces its usefulness, I still hope to understand its principle so that I can change it according to my preferences.
After working on it for a long time, starting from understanding the meaning of TexCoord, I finally understood the principle of curve HUD explained in UMG parabolic distortion effect - UE4 AnswerHub. Seeing that there is no explanation about this principle on the Internet, I thought about posting an article hhh

First of all, we know that changing the UV coordinates changes the coordinates of the entities rendered from the texture to the game. In HUD, texcoord is the UV coordinate of the texture. To make a curve HUD effect, it is necessary to change the UV coordinates of the HUD.
Observing this curve HUD, it is difficult to say whether it has changed in the U direction, but you can be sure that it has moved a certain distance in the V direction. If you want to disassemble its principle, you must at least know the principle of its movement in the V direction.


如图所示,我已经给这个材质的结构加好了注释。
油管上一些视频的教程从后往前连接的,这容易使人一头雾水——不过还是可以从后往前推导的:

1.看到 Append 节点后面连着输入参数的 UV,说明我们要将改变后的 U 坐标矩阵和 V 坐标矩阵输入Append 节点

2.看到 Append 节点的第一个输入是 TexCoord 的 R 通道,说明 U 坐标没变,可以专心看 V 坐标了

3.看到 Append 节点的第二个输入是 Add 了一个 TexCoord 的 G 通道,说明这里通过锚点加偏移量算出改变后的 V 坐标,那么 DistortionAmount 前面那部分就是偏移量了

4.看到偏移量用一个 Multiply 得出,那就只能先看乘子,实际算一下他这个是个什么效果
(当然。你可以打开节点预览,但是小于等于0的值会被显示成黑色,所以这不可靠)
(当然如果你真的想看负数的话也可以加一个小的正数再看,这方法挺巧hhh)
第一个乘子 A,把 [0,1] 放大一倍再移动 1/2 长的的距离,从 [0,1] 变换到了 [-1,1]
第二个乘子 B,[0,1]*[-1,0],相当于 x(x - 1),得到了一个抛物线(可能这个时候你就会发现他就是用的这个抛物线)
为这两个乘子矩阵简单计算一下,你就会发现,你得到了一个左右两边元素绝对值小,上下两边元素绝对值大,中间元素绝对值为0的一个矩阵

As shown in the picture, I have added a comment to the structure of this material.
In some video tutorials on the youtube, nodes are connected from back to front, which is easy to get confused, however it can also be deduced from back to front:

  1. See the UV of the input parameter behind the Append node, indicating that we need to input the changed U coordinate matrix and V coordinate matrix into the Append node

  2. See that the first input of the Append node is the R channel of TexCoord, indicating that the U coordinate has not changed, so you can focus on the V coordinate

  3. See that the second input of the Append node is Add a G channel of TexCoord, which means that the changed V coordinate is calculated by adding the offset to the anchor point, then the part behind the DistortionAmount is the offset

  4. See that the offset is obtained with a Multiply, then you can only look at the multiplier first, and actually calculate what effect it is
    (of course. You can open the node preview, but the value less than or equal to 0 will be displayed as black , So this is unreliable)
    (Of course, if you really want to see negative numbers, you can also add a small positive number and then look at it. This method is quite coincidental hhh)
    The first multiplier A, doubles [0,1] and then moves 1/2 length of the length, from [0,1] to [-1,1]
    The second multiplier B, [0,1]*[-1,0], is equivalent to x(x-1), and got a parabola (maybe at this time you will find that he is using this parabola)
    Simply calculate these two multiplier matrices, and you will find that you have a matrix with smaller absolute values ​​on the left and right elements, larger absolute values ​​on the upper and lower sides, and 0 in the middle.

>> [1 1 1;0 0 0;-1 -1 -1]*[0 -0.25 0;0 -0.25 0;0 -0.25 0]

ans =

         0   -0.7500         0
         0         0         0
         0    0.7500         0

>> [1 1 1 1 1;0.5 0.5 0.5 0.5 0.5;0 0 0 0 0;-0.5 -0.5 -0.5 -0.5 -0.5;-1 -1 -1 -1 -1]*[0 -0.125 -0.25 -0.125 0;0 -0.125 -0.25 -0.125 0;0 -0.125 -0.25 -0.125 0;0 -0.125 -0.25 -0.125 0;0 -0.125 -0.25 -0.125 0]

ans =

         0   -0.6250   -1.2500   -0.6250         0
         0   -0.3125   -0.6250   -0.3125         0
         0         0         0         0         0
         0    0.3125    0.6250    0.3125         0
         0    0.6250    1.2500    0.6250         0

这个矩阵要作为偏移量,那么你就懂了——他把这个抛物线的值作为行向量,按列平铺到整个平面上,得到的矩阵作为 V 方向上的偏移量。
根据乘法的规则,在这个矩阵中,对于同一列而言,更靠近上下两边,值由乘子 A 中更靠近上下两边的行向量乘得,也就是由绝对值更大的数乘得,因此靠近上下两边的元素的值的绝对值更大,表现在 UV 上,就是弯曲程度越高。
根据抛物线的性质,在这个矩阵中,对于同一行而言,更靠近中间,值由乘子 B 中更中间的列向量乘得,也就是由绝对值更大的数乘得,因此靠近中间的元素的值的绝对值更大,表现在 UV 上,就是更靠近抛物线的顶点

我使用了Matlab来验证我的猜想,结果是很好看的

This matrix is to be used as the offset, then you will understand. He uses the value of this parabola as a row vector, tiling the entire plane column by column, and the resulting matrix is used as the offset in the V direction.
According to the rules of multiplication, in this matrix, for the same column, the closer to the upper and lower sides, the value is multiplied by the row vector closer to the upper and lower sides of the multiplier A, that is, multiplied by the number with the larger absolute value, so the absolute value of the elements close to the upper and lower sides is larger. Its performance on UV is the higher the degree of curvature.
According to the nature of the parabola, in this matrix, for the same row, the closer to the middle, the value is multiplied by the more middle column vector in the multiplier B, that is, multiplied by the number with the larger absolute value, so the closer to the middle sides, the absolute value of the value of the element is larger. Its performance on UV is closer to the vertex of the parabola.

I used Matlab to verify my conjecture, and the result is very beautiful

%使用矩阵作为演示
%矩阵大小
Num=100;
%扭曲程度
DistortionAmount=0.2;
%R的规律
fun = @(x) x.*(x-1);
%构造R向量
x=linspace(0,1,Num);
R=fun(x);
%构造R矩阵
R1=R;
for i=2:1:Num
R1=[R1;R];
end
%G的规律
%构造G向量
G=-linspace(-1,1,Num);
%构造G矩阵
G1=G;
for i=2:1:Num
G1=[G1;G];
end
G1=G1';
%矩阵相乘
Ans=G1*R1;
%绘图
subplot(2,1,1);
imagesc(Ans);
%应用扭曲程度
Ans=Ans*DistortionAmount;
%普通的G的规律
%构造G向量
G=linspace(0,1,Num);
%构造G矩阵
G2=G;
for i=2:1:Num
G2=[G2;G];
end
Ans=Ans+G2;
%绘图
subplot(2,1,2);
imagesc(Ans);

理论上如果手写 Shader 的话,这种操作是很简单的,但是万一有的人就是想纯蓝图实现呢hhh

知道了这些原理,我们可以做些什么修改呢?
你可以对 V 方向上的偏移量的计算做一些修改,来达到别的一些效果。比如我不想要曲线,我想要斜线,那么你就知道你需要一个绝对值函数形式的偏移量,这就很容易实现了。

In theory, if you write the Shader by hand, this operation is very simple, but in case some people just want to implement it in pure blueprint hhh

Knowing these principles, what modifications can we make?
You can make some modifications to the calculation of the offset in the V direction to achieve other effects. For example, if I don’t want a curve, I want a diagonal line, then you know that you need an offset in the form of an absolute value function, which is easy to implement.

这是我第一次发帖,如果有哪里不符合规范,还请指出,谢谢

This is the first time I post, if there is any non-compliance, please point out, thank you

2 Likes

It may be that the health bars in the example result are just too small, but they seem perfectly straight to me.

I would expect them to look curved, just like your Mathlab gradient sample.

1 Like

Thanks for your reply
Oh yes you are right, my last example image looks straight, that is what I want, beacause i use a abs function, to show what can I do except from curve
In fact, the last but one is original curved HUD. I should have pointed it out. Because the health bar is too small so it is hard to distinguish one from the other.
If you aren’t satisfied with that curve, you can increase the parameter “DistortionAmount”

I love your background image :two_hearts:

1 Like

ACG Yes!(`ε´ )