MY BLOG DIRECTORY:
YivanLee:专题概述及目录![图标](https://i-blog.csdnimg.cn/blog_migrate/42afae69d12d14607236c022a16ae4b4.jpeg)
INTRODUCTION:
我们的游戏里经常会用到统计功能,需要制作各种曲线图像,上一篇文章我做的雷达统计图,然后下面就有人在问曲线统计图怎么做,我这里试一下在shader里用很少的计算来制作统计曲线图。
Forward declaration:
本文章内容过于浅显rua鸡,如有错误还请斧正。
MAIN CONTENT:
【1】f(x) = kx + b
![v2-e85b4a1d22073d377c4a7f922e65aa4c_b.gif](https://i-blog.csdnimg.cn/blog_migrate/fda5494925d4c31e0ecdc65fe31595dc.gif)
材质节点如下:
![v2-77e32bd6079712c51f1fb6762a2ff097_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/9fa016e1ac1713e122ba856333254077.jpeg)
材质的思路非常简单,首先计算坐标系,把UV坐标变换成y轴向上,o点在面片中心的状态,如UV坐标一开始就是这样了那就不需要变换了。然后我们构造一个fx,把x值输入到fx里做自变量然后由这个函数计算出fx的值。然后比较fx的值和UV的y坐标的距离。
![v2-c5fabdbdaa5984778ef1f61fcff3e6c4_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/1cec273dcb896b9c71365f440834620d.jpeg)
然后我们把它clamp在【0,1】的范围内然后再反一下。
然后再把函数值稍稍加一点上去,让离函数曲线比较近的像素的值能大于1,然后再用floor把大于1的值等于1,小于1的值为0,这样就画出了我们的函数。后面如果想画其他函数只需要变化fx节点即可
【2】f(x) = sin(x)
![v2-e8d4eab00e428fbe3e773b24df76d00a_b.gif](https://i-blog.csdnimg.cn/blog_migrate/cf22cd8e1c2ed8f935ce4847cfa08d5c.gif)
![v2-9513227d39f9d490f11421f1d1562e1c_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/338b1426ac5b7e2d1860c9ce91a4adf0.jpeg)
【3】f(x) = Ax^2 + b
![v2-f9b7ae2978123a774c54a701f5ee4937_b.gif](https://i-blog.csdnimg.cn/blog_migrate/4cda4bae374d9ab6105659491596be0e.gif)
![v2-51bdc08c5939303fe56b203f28f46617_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/b5a4fbf6d6b5c56b838e5cd991b031cc.jpeg)
【4】f(x) = a^x
![v2-e1f1438a883af5f15af34f0d7781a942_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/7da80ddf10a414165d857860413fc682.jpeg)
【5】Piecewise function
我们先把我们的材质再美化一下
![v2-931e7e0fbeaccdc51eecc4bc82cfc25a_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/67fb9e4a695acfae1d8dcc06b1deacfc.jpeg)
![v2-afd45e416c67f7fadb2d34e7388f0d6d_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/9cc39401a20e89552f816cac996dd5cf.jpeg)
做了一个坐标系方便看结果是否正确。下面就开始做曲线统计表。假设现在的游戏里有四个统计时段,玩家的时间和得分分别是【0,0】,【2,4】,【6,1】,【8,8】,我们用线性函数的两点式。
我的代码如下:
float TwoPointFunction(float2 p1, float2 p2, float x)
{
float fx = ((x - p1.x)/(p1.x - p2.x) + p1.y / (p1.y - p2.y)) * (p1.y - p2.y);
fx = x > p1.x ? fx : 0;
fx = x < p2.x ? fx : 0;
return fx;
}
float CustomNode_FX(float x)
{
float Ret = 0;
float2 p1 = float2(0, 0);
float2 p2 = float2(2, 4);
float2 p3 = float2(6, 1);
float2 p4 = float2(8, 8);
Ret = TwoPointFunction(p1, p2, x);
Ret += TwoPointFunction(p2, p3, x);
Ret += TwoPointFunction(p3, p4, x);
return Ret;
}
效果如下:
![v2-11d5566246094558306c51976dede362_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/f5d718156ff3976e1b73c0e995ca869b.jpeg)
为了让曲线粗细一致,我们需要更改一下距离公式
![v2-253d27e222cf9484e8cc2bd1938402c2_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/707c56fc111c273b01337744bd6d3ffb.jpeg)
之前是算L的长度,现在使用S的长度。对函数F(x)求导求得 。然后用
求得
进而求得s的长度。
![v2-3337c41cc5706aad85f39580819a5559_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/0b16537adeae1285c73a8d0abc1fe4a6.jpeg)
![v2-da472d7dcf45b333bcd5cfa40d81f77c_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/1317f525f202c8e2f3144cbcdbf5f017.jpeg)
这样函数图像的粗细就均匀了,不会因为斜率过大而变得很细。
SUMMARY AND OUTLOOK:
至此我们可以在游戏里做各种统计图了,Enjoy it。
NEXT:
todo...