1.请高手把这个通达信主公式改成选股指标
2.几何非线性有限元基本原理及matlab编程-Part 1
3.3D实践3D曲率原理及计算(3D-Mesh)
4.自动驾驶笛卡尔坐标系和frenet坐标系相互转换
5.竟用Python画一只兔子?——turtle库circle()画圆函数的切线切线详细用法介绍
6.基于Shell的毛发系统
请高手把这个通达信主公式改成选股指标
第一个N:=IF(BARSCOUNT(C)>=,,BARSCOUNT(C));
AMOV:=VOL(C+L+H)/3;
MN:=SUM(AMOV,N)/SUM(VOL,N);
XG1:C>MN;
第二个
N1:=IF(BARSCOUNT(C)>=8,8,BARSCOUNT(C));
MN1:=SUM(AMOV,N1)/SUM(VOL,N1);
XG2:C>=MN1 AND REF(C
你说的收盘价由灰色变为**我没看见,短线是由绿色变为**,中线是由灰色变为**,上面公式第一个是收盘价大于中线,第二个是短线由绿线变为
**麻烦朋友给我编辑一个通达信的选股指标
可以编写当日涨幅大于%,日跌幅-%以上,源码去除一字板,软件但是切线切线这个条件的第一个条件获利筹码比例计算结果与系统显示结果会有误差,这个误差无法解决你能接受这个问题这个公式就可以编写。源码
请问各位有没有比较好的软件双龙乾坤线指标公式源码炒股短线卖出指标或者条件选股。我用的切线切线是通达信。
做短线不等同于今天买明天卖。源码最后,软件从道斯理论来看,切线切线尽管做短线是源码短期行为,但是软件短期行为不是对长期走势的否定,对一个短线品种的切线切线把握应该是看长做短,通常笔者将一个图形分解为周线,源码月线,软件日线,分钟线来观察,只有那些四种周期同时处于波浪理论中上升三浪的股票才是短线安全与收益最大化的保证。
分析一个股票首先从它的形态入手,短线炒手拒绝任何的失去上攻动力的股票,也就是说一只真正值得介入的股票,其上攻的形态一定要完全完美,这种形态的完美不是仅仅表现在日线图表上。应该将其展开看成各种周期复合状态下的攻击形态。
最重要的是分时报价震荡图上的上攻状态与上攻气势,关键技术点位是采取压单突破还是轻松突破。这都是必须考核的指标。从现行券商主力运作的习惯来看前者运用的比较多。有一个值得一提的问题是关于上攻的浪型的如何判断完毕?笔者没有完全分析清楚,只是提出一些解决途径:
第一,大盘的见顶决定了个股的上攻浪型运行完毕。板块的回调加速了浪型的完毕。
新浪财经网|新浪财经博客|新浪财经股票首页,没有击穿前期一年之内顶的股票可以认为是上攻浪型没有运行完毕。
如何判断一只股票能够有能力穿过前期高点这里面牵涉到一些分析盘面的真功夫,如主力的试盘,夹板,逼仓,压盘,震仓,倒仓和反技术的高级技术骗线等等。以后的论述中将进一步的阐明。
主力运作背离与同步在价量等历史资料的军团vscsgo源码基础上进行统计,数学计算,绘制方法是技术分析方法的主要手段。通常技术分析分为五类:指标类,切线类。形态类,k线类与波浪类。这是一个初学者必须掌握的实战基本技能。我们将着重分析其中的可利用性。
(1)所谓指标类技术分析是指考虑市场行为的各个方面,建立一个数学模型,给出数学上的计算公式,得到一个体现市场的某个方面的内在实质的数字,这个数字叫指标数值。例如传统的kdj,macd。大家知道了指标是如何产生的便知道所谓的万能指标是不复存在的。那些企图利用某些特定的历史条件下的指标黑马擒拿术证明自己的指标如何万能是自己欺骗自己的鬼把戏。
股市的未来预测性决定了指标是来实战的,不是靠几个做了手脚的数据游戏来安慰自己。这个通病在现在的股票软件开发商身上很流行。有很多善良的投资者在初入股市的过程中不注意指标的特定范围和含义,盲目的利用指标进行投资。结果得出了一个指标无用论的论调。其实在我们新兴的市场里主力庄家常利用广大股民对指标的一知半解达到自己不可告人的目的。指标一般分为预测型、讯号型指标、交易系统型指标三大类。我们做短线的时候应该知道指标的适用期限才能够将十八般武器全部使用灵活,达到每战必胜。
(2)切线类指标是比较强调趋势的,趋势简单的说便是股票价格运行的方向,某种趋势形成之后若想改变的话是要有足够影响它的外力。所以一旦股票处于加速上扬期间的话,持有是我们最好的选择。当然这种趋势应该是从长期去把握。切线理论中比较重要的是一些趋势线与黄金分割线的技巧,这对于短线投资者来说很重要。适当的应用江恩回调带的理论可以对你有极大的帮助。
(3)形态理论与周线理论:由于现阶段主力运作周期的加大,长庄股的粉墨登场。日线图上揭示的传统理论信息容易被主力骗线。所以在这里我引入了一个周线理论。fusionapp源码2021从周线上我们可以以战略者的眼光观察股价现在处于何种状态之中。形态理论的效用才能达到完美的体现。如果只注意所谓的短期日线形态,你将饱尝主力骗线的苦果。如主力成本区域内做的m头。具体参考年的4.-4.的()通葡萄酒。从日线看形态极其恶劣。但是从周线看便恍然大悟了,主力的欲擒故纵之心跃然“图”上,投资者可以大胆坚决吸纳。
我想把这个指标用通达信选股器选出来,条件是出现“看底”的时候,求高手帮忙!
VAR1:=(CLOSE>REF(CLOSE,1) AND CLOSE>REF(CLOSE,2));
VAR2:=(REF(VAR1,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VAR3:=(REF(VAR2,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VAR4:=(REF(VAR3,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VAR5:=(REF(VAR4,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VAR6:=(REF(VAR5,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VAR7:=(REF(VAR6,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VAR8:=(REF(VAR7,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VAR9:=(REF(VAR8,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VARA:=(REF(VAR9,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VARB:=(REF(VARA,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VARC:=(REF(VARB,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VARD:=(CLOSE
VARE:=(REF(VARD,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VARF:=(REF(VARE,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VAR:=(REF(VARF,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VAR:=(REF(VAR,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VAR:=(REF(VAR,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VAR:=(REF(VAR,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VAR:=(REF(VAR,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VAR:=(REF(VAR,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VAR:=(REF(VAR,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VAR:=(REF(VAR,1) AND CLOSE=REF(CLOSE,1) AND CLOSE>=REF(CLOSE,2));
VAR:=(REF(VAR,1) AND CLOSE>=REF(CLOSE,1) AND CLOSE=REF(CLOSE,2));
VAR:=((REF(VARD OR VARE OR VARF OR VAR OR VAR OR VAR OR VAR OR VAR OR VAR OR VAR OR VAR OR VAR,1)) AND VAR1);
A:=(3C+H+L+O)/6;
XJ:=(A+REF(A,1)+REF(A,2)+REF(A,3)+REF(A,4))/;
YCZXH:=(MA(HHV(A,2),5)+MA(HHV(A,2),)+MA(HHV(A,2),)+MA(HHV(A,2),))/4;
YCZXL:=(MA(LLV(A,2),5)+MA(LLV(A,2),)+MA(LLV(A,2),)+MA(LLV(A,2),))/4;
SMH:=EMA(YCZXH,);
SML:=EMA(YCZXL,);
SMJ:=(SML+SMH)/2;
PJ:=(A+9REF(A,1)+8REF(A,2)+7REF(A,3)+6REF(A,4)+5REF(A,5)+4REF(A,6)+3REF(A,7)+2REF(A,8)+REF(A,9))/;
A1:=EMA(PJ,3),COLOR;A2:=EMA(PJ,5);
A3:=EMA(PJ,7),COLOR;A4:=EMA(PJ,9);
A5:=EMA(PJ,);
LX:=REF(XJ,1);
ZD:=(SMA(MAX(XJ-LX,0),5,1)/SMA(ABS(XJ-LX),5,1));
KX1:=(CLOSE>=OPEN) AND ZD>=;
KX2:=(CLOSE=;
KX3:=(CLOSE>=OPEN) AND ZD
KX4:=(CLOSE
AAA2:=SUM(IF( CLOSE>REF(CLOSE,1),VOLC,0),0);
AAA3:=SUM(IF( CLOSE
AAA4:=SUM(IF( CLOSE=REF(CLOSE,1),VOLC,0),0);
BB1:=0;
B1万元:=DVOLDCLOSE/;
B1差:=B1万元-REF(B1万元,1);
B2万元:=DVOLDCLOSE/;
B2比:=B2万元/REF(B2万元,1);
净流入万元:=(AAA2-AAA3-AAA4);
PM:=MA(净流入万元,1);
PMA:=PM/REF(PM,1)>1;
PMB:=REF(PMA,1)
密码:=(EMA(MA(B1万元,2),2))/;
二日比:=密码/REF(密码,1);
选股:=PMB AND 密码>REF(密码,1) AND 二日比>1;
均价线:=AMOUNT/V/;
均价线2:=MA(均价线,3);
均价线5:=MA(均价线,5);
均价线:=MA(均价线,);
均价线:=MA(均价线,);
XG:C>均价线2 AND 均价线2
ANDREF(均价线2,2)0;
股票公式专家团为你解答,希望能帮到你,祝投资顺利。
通达信短线指标
VAR1:=(CLOSE-LLV(LOW,))/(HHV(HIGH,)-LLV(LOW,));
VAR2:=SMA(VAR1,3,1);
VAR3:=SMA(VAR2,3,1);
VAR4:=3VAR2-2VAR3;
VAR5:=LLV(LOW,5);
VAR6:=HHV(HIGH,5);
VAR7:=EMA((CLOSE-VAR5)/(VAR6-VAR5),4)2;
VAR8:=EMA(REF(VAR7,1)+VAR7,2);
VAR9:=3VAR7-2VAR8;
VARA:=POW(MA(CLOSE,5),2)+MA(CLOSE,5);
VARB:=POW(MA(LOW,5),2)+MA(LOW,5);
VARC:=POW(MA(HIGH,5),2)+MA(HIGH,5);
VARD:=(VARA-LLV(VARB,))/(HHV(VARC,)-LLV(VARB,))+-;
VARE:=SMA(VARD,3,1)-;
VARF:=SMA(VARE,3,1);
VAR:=3VARE-2VARF;
VAR:=(HIGH+LOW+CLOSE2)/4;
VAR:=EMA(VAR,);
VAR:=STD(VAR,);
VAR:=(VAR-VAR)/VAR;
VAR:=EMA(VAR,5);
VAR:=EMA(VAR,)+-;
VAR:=EMA(VAR,);
VAR:=3VAR-2VAR;
VAR1A:=VAR2+VAR7+VARE+VAR;
VAR1B:=VAR3+VAR8+VARF+VAR;
VAR1C:=VAR4+VAR9+VAR+VAR;
VAR1D:=(HIGH+LOW+CLOSE)/3;
VAR:=(VAR1D-MA(VAR1D,))/(AVEDEV(VAR1D,));
VAR:=(HIGH+LOW+CLOSE+VAR1D)/4;
VAR:=EMA(VAR,);
VAR:=STD(VAR,);
VAR:=(VAR-VAR)/VAR;
VAR:=(VAR1D-MA(VAR1D,))/(AVEDEV(VAR1D,));
VAR:=EMA(VAR,5);
VAR2A:=((VAR+VAR+VAR)/3+)/4;
VAR2B:=(EMA(EMA(EMA(VAR2A,),),5)-)2;
VAR2C:=(VAR1A+VAR1B+VAR1C)//5-;
VAR2D:=EMA(VAR2C,7);
VAR2E:=(VAR2A+VAR2C)/2/;
超短:=EMA(VAR2E,3);
短线:=EMA(超短,5);
趋势线:=EMA((VAR2B+VAR2D)/2,2);
XG:趋势线>REF(趋势线,1)AND REF(趋势线,1)
声明:以下公式不含任何未来函数,如果哪位觉得有未来函数,或者有类似的性质,请指出。
兄弟,指标很多,有用的也很多,但是最关键的还是临盘时的心态,要重视,要像打仗似的,要有性命攸关的觉悟。
送你一个最近帮别人修改的公式,买的信号是原来公式的,我就帮他加了个卖出信号,看起来还不错。直接发到这里,要不往你邮箱发了,公式不要怕被人知道,知道是一回事,会用又是一回事,你敢用,用的好,就是知道的多了,也没事,像MACD之类的不是全世界都知道,只要自己总结出自己的事务传播源码方法,一样会盈利。最后提醒一下兄弟,有了指标,还是要锻炼自己的心态,我们都是在路上,一起共勉吧。分不分的无所谓,你看着给吧。
通达信公式源码:
{ 锯齿顶底 }
STICKLINE(O>C,H,O,0,1), COLORGREEN;
STICKLINE(O>C,O,C,2,1),COLORGREEN;
STICKLINE(O>C,L,C,0,1), COLORGREEN;
STICKLINE(O
STICKLINE(O
STICKLINE(O
STICKLINE(CLOSE=O,LOW,H,0,1),COLORRED;
STICKLINE(CLOSE=O,O,C,2,1),COLORRED;
MA2:MA(CLOSE,M2),COLORCYAN;
MA3:=MA(CLOSE,M3),COLORA6A6A6;
MA4:=MA(CLOSE,M4),COLORGREEN;
MA1:MA(CLOSE,M1),COLORYELLOW;
LC:=REF(CLOSE,1);
RSI5:=((SMA(MAX((CLOSE - LC),0),5,1) / SMA(ABS((CLOSE - LC)),5,1)) );
TR1:=SUM(MAX(MAX((HIGH - LOW),ABS((HIGH - REF(CLOSE,1)))),ABS((LOW - REF(CLOSE,1)))),);
HD:=(HIGH - REF(HIGH,1));
LD:=(REF(LOW,1) - LOW);
DMP:=SUM(IF(((HD > 0) AND (HD > LD)),HD,0),);
DMM:=SUM(IF(((LD > 0) AND (LD > HD)),LD,0),);
PDI:=((DMP ) / TR1);
MDI:=((DMM ) / TR1);
ADX:=MA(((ABS((MDI - PDI)) / (MDI + PDI)) ),5);
AV:=(RSI5 + ADX);
DXR:=(((ADX + REF(ADX,5)) / 2) + RSI5);
WR:=(( (HHV(HIGH,) - CLOSE)) / (HHV(HIGH,) - LLV(LOW,)));
NEWVOL:=(RSI5 - WR);
NEWVOL2:=(RSI5 + WR);
买:=(AV + NEWVOL);
DRAWTEXT(CROSS(买,0),L,'买'),COLORFFFF;
DRAWICON(CROSS(买,0),L,1);
卖:=(AV + NEWVOL2);
{ 卖2:=(AV - NEWVOL);}
{ DRAWTEXT(CROSS(MAX(买,DXR),卖2),H,'卖2'),COLORLIGREEN;
DRAWICON(CROSS(MAX(买,DXR),卖2),H,2);}
DRAWTEXT(CROSS(卖,),H,'卖'),COLORLIGREEN;DRAWICON(CROSS(卖,),H,2);
最后再送你 买 信号的 选股 预警 公式:
LC:=REF(CLOSE,1);
RSI5:=((SMA(MAX((CLOSE - LC),0),5,1) / SMA(ABS((CLOSE - LC)),5,1)) );
TR1:=SUM(MAX(MAX((HIGH - LOW),ABS((HIGH - REF(CLOSE,1)))),ABS((LOW - REF(CLOSE,1)))),);
HD:=(HIGH - REF(HIGH,1));
LD:=(REF(LOW,1) - LOW);
DMP:=SUM(IF(((HD > 0) AND (HD > LD)),HD,0),);
DMM:=SUM(IF(((LD > 0) AND (LD > HD)),LD,0),);
PDI:=((DMP ) / TR1);
MDI:=((DMM ) / TR1);
ADX:=MA(((ABS((MDI - PDI)) / (MDI + PDI)) ),5);
AV:=(RSI5 + ADX);
WR:=(( (HHV(HIGH,) - CLOSE)) / (HHV(HIGH,) - LLV(LOW,)));
NEWVOL:=(RSI5 - WR);
买:=(AV + NEWVOL);
买预警:CROSS(买,0);
几何非线性有限元基本原理及matlab编程-Part 1
本文主要围绕几何非线性有限元分析的 MATLAB 编程进行讲解。以二维梁单元为对象,内容涵盖几何非线性有限元分析的基本理论和具体实现。为方便学习,已录制视频课程与课程源码一同提供在仿真秀平台。课程分为多个部分,包括更新拉格朗日法(UL)、共旋法(CR)和切线刚度矩阵等内容。
目录:
Part 1:介绍基于不同运动描述方法的切线刚度矩阵推导,解释 UL 和 CR 方法,以及非线性系统求解算法。
Part 2:非线性系统求解算法的实现。
Part 3:通过具体案例的 MATLAB 编程实现,讲解几何非线性代码的构建。
课程主要内容:
Part 1 包括 UL、CR 方法与切线刚度矩阵的推导,解释几何非线性特性导致刚度矩阵的变化。
Part 2 涉及非线性求解算法的实现,解释增量迭代求解的过程,以及不同非线性(几何、材料)问题的适用性。
Part 3 通过具体案例的 MATLAB 编程实现,旨在打破理论与实际编程之间的壁垒。
Part 1 的内容包括:
1. 大变形下的几种几何非线性情况,如大挠度、大转动、大曲率。
2. 大变形与线性假定的对比,以及在几何非线性条件下的结构刚度变化。
3. 几何非线性有限元分析的基本概念,如何通过数值方法离散问题,形成矩阵系统。
4. 切线刚度矩阵的推导,解释 UL 和 CR 方法在几何非线性分析中的定制私服源码应用。
Part 2 重点解释非线性求解算法的实现,包括标准牛顿迭代、修正牛顿迭代、弧长法等。
Part 3 通过 MATLAB 编程实现具体案例,演示几何非线性代码的构建过程。
课程完整案例源码链接:几何非线性梁单元 MATLAB 有限元程序 | 源码+理论文本。
课程主要内容:通过 Part 1 的 UL、CR 方法与切线刚度矩阵推导,Part 2 的非线性求解算法实现,以及 Part 3 的 MATLAB 编程案例,旨在提供从入门到精通的 MATLAB 有限元编程学习体验。
3D实践3D曲率原理及计算(3D-Mesh)
源代码可在此仓库中找到,若大家发现错误或不合理之处,欢迎指出。
总结曲率原理,参考内容包括:图形学书籍、维基百科、GitHub项目。
曲率描述几何体弯曲程度,应用于几何分析、地理测绘等。如材料学中,材料活性与表面活性位点有关,曲率影响活性位点数量。
曲线P点切线定义:任意点Q与P无限接近,所连直线为切线。曲线P点曲率:三点确定一圆,圆心C无限接近P点,圆半径r的倒数为曲率。
平面圆上弯曲程度相同,任意点曲率相等,越弯曲曲率越大,直线曲率为0。
曲面曲率:在曲面P点取法线n,过n有无限多个剖切平面,交线为平面曲线。不同平面曲线在P点曲率半径不相等。
三维空间中,曲面有主曲率和高斯曲率。主曲率k1和k2为主方向上的最大值和最小值,高斯曲率K=k1*k2反映曲面不同方向弯曲程度是否相同。平均曲率H=(k1+k2)/2反映曲面凹凸程度。
高斯曲率:正数为球面,负数为双曲面。平均曲率:正数局部凹,负数局部凸。
示例:第一个图形高斯曲率为负,第二个为0,第三个为正。
曲率计算方法:调研发现使用C++图形学库libigl和三维几何处理系统MeshLab较多,具体实现可自行搜索教程。
自动驾驶笛卡尔坐标系和frenet坐标系相互转换
自动驾驶中的车辆运动在笛卡尔坐标系和Frenet坐标系之间转换是关键。在笛卡尔系统中,车辆运动通过航向角[公式]和曲率[公式]描述,而在Frenet坐标(S-L坐标)下,车辆运动则用[公式]表示,其中下标[公式]和[公式]分别代表车辆和参考点,对时间求导用点表示,对自变量求导用撇表示。 Frenet坐标系常用于路径规划,通过先在S-L坐标系规划轨迹得到[公式]关系,再在S-T图规划速度得到[公式]。参考线通常用散点表示,包含位置[公式]、切线方向[公式]、曲率[公式]等信息。在Apollo源码中,涉及如下转换:从笛卡尔的[公式]和[公式]转换到S-L的[公式]和[公式]
从S-L的[公式]到笛卡尔的[公式]
例如,从笛卡尔到S-L,首先找到最近的参考点,通过向量关系推导出[公式],然后利用速度关系式[公式],结合向心力类比的Frenet公式推导出[公式]。整个过程涉及速度的定义、链式求导法则和Frenet公式的应用。 在S-L坐标到笛卡尔坐标转换时,通过参考点的几何位置和车辆与参考线的关系,可以计算速度、加速度等参数,从而完成坐标间的转换。这些转换公式确保了自动驾驶系统在不同坐标系间的运动描述和控制的灵活性和准确性。竟用Python画一只兔子?——turtle库circle()画圆函数的详细用法介绍
周末我学习了一下turtle库的基本函数,试着画了一只大耳朵小兔子,灵感来源于jellycat邦尼兔。turtle库中的circle()函数用来画弧,与通常先确定原点,再根据半径、夹角画弧的方法有所不同。使用之后,我深刻理解了circle()函数的巧妙之处。我发现,边想边做边改比完美的空想更有收获。
绘制效果如图:
在circle(radius,extent)函数中,参数radius取像素值,extent取角度的整数值,两参数均可取正负值。运行以下代码,可以直观地理解circle(radius,extent)函数参数正负值时的绘制特点:
circle()函数以画笔当前方向(y')为y轴方向,以经过画笔当前绝对坐标(x0,假设y0=0)、垂直于y轴的方向为x轴方向,则圆心(即原点)坐标为(x0-radius=0,0),由当前画笔位置(x0,y0)为弧线起始点,画出extent角度的圆弧。
为了方便理解,我绘制了circle()函数的相对坐标体系,如下图:需要注意的是:radius为正时,圆心在当前位置左侧(如下图);radius为负时,圆心在当前位置右侧;extent为正时,顺画笔当前方向绘制,extent为负时,逆画笔当前方向绘制。
circle()函数可以以画笔当前位置为切点,画出与(画笔当前方向所在直线为)切线相切的任意圆弧。所以在绘制曲线时十分自由好用。抛开用圆规先确定圆心再画圆的惯常思维,慢慢使用便能理解circle()函数的巧妙。以上为个人的学习理解,初识turtle,不当之处欢迎指正。
兔の绘图代码如下:
python开发IT交流群: 分享源码等相关资料
更多精彩文章请关注公众号python社区营其它相关文章
基于Shell的毛发系统
最近两天我研究了一下gFur插件。由于该插件目前停止了维护,所以我对其源码进行了修改,以便支持UE5.1。
Shell技术是一种构建面片并叠加以实现毛发效果的技术。构建的面片越多,效果越好,但性能也会越低。因此,在实际使用中,需要平衡层数(Layer)以实现视觉效果与性能成本的平衡。
关于Shell技术的详细介绍,可以参考:gim.studio/an-introduct...
gFur插件通过自定义MeshComponent来实现毛发效果。除了定义配置参数和自定义FPrimitiveSceneProxy,它还通过重写以下两个方法来更新数据。
本篇文章主要分析了Vertex Shader相关内容,对如何自定义MeshComponent、数据如何从CPU传递到GPU以及如何创建shader文件等不做过多介绍。感兴趣的读者可以阅读以下系列文章,内容比较详细。
这里的shader文件只需要定义一个xxVertexFactory.ush文件即可。.ush文件是头文件,提供给.usf文件依赖的,这里指的是BasePassVertexShader.usf文件。
FVertexFactoryInput可以理解为VS的input参数,它随着BasePassVertexShader.usf的Main函数传入。自定义的每个xxVertexFactory.ush都可以定义自己需要的入参,gFur中定义的参数如下:
在CPU运算的InitDeclaration阶段,完成了参数的一一对应。
在自定义的VertexFactory.ush中,需要重写一些函数,具体可以参考UE本身的GPUSkinVertexFactory.ush。这里我们只关注这几个方法:
上面提到.ush文件是提供给BasePassVertexShader.usf依赖的,而这些方法也是在这里进行调用的。
完整内容如下:
这里可以看到,从VertexFactory中得到的World position,然后转换到裁剪空间(Clip Space)。
为什么不是传统的World Space -> Camera Space -> Clip Space呢?我的理解是,从VertexFactory中得到的Position其实是一个TranslatedWorld Position,而TranslatedWorld Position = World Position + PreViewTranslation。PreViewTranslation数值上等于相机平移的反向量(剥离了相机的旋转),负责把世界坐标转换到不考虑相机旋转的相机空间(即translated world)。
所以从方法名上来看,可能会产生一些误解,认为返回的是世界空间的位置,而实际上返回的是相机空间位置(即TranslatedWorldPosition)。
UE中对各个坐标空间的解释可以参考:Coordinate Space Terminology
GetVertexFactoryIntermediates函数会在BasePassVertexShader中最先调用,用来预先计算一些数据,并缓存到FVertexFactoryIntermediates结构体中,避免重复计算。该结构体也是定义在自定义的VertexFactory.ush文件中,需要什么数据就定义什么。在UE5中,该结构体需要定义一个FSceneDataIntermediates类型的SceneData参数(必须要有,不然会无法编译shader),该参数会在很多shader文件中进行使用。
其中LocalToWorld参数是顶点从Local Space转换到World Space的转换矩阵。WorldToLocal是World Space到Local的转换矩阵。BlendMatrix是骨骼矩阵,用以蒙皮计算。TangentToLocal则是Local Space下的切线信息。
GFUR_PHYSICS主要是蒙皮操作,通过mesh骨骼以及影响权重来计算我们生成的毛发顶点位置,以此来实现某些动画效果。这里是先把顶点位置从Local转到了World,蒙皮计算完成后,再转回Local。
此时我们得到的Position是在Local Space下的顶点位置。UE本身提供了TransformLocalToTranslatedWorld方法来将Local Space下的顶点位置转为TranslatedWorld position。
VertexFactoryGetPreviousWorldPosition方法与VertexFactoryGetWorldPosition类似,只需要将最后的LocalToWorld矩阵替换为PrevLocalToWorld即可。
真实感人物渲染(四)布料篇
在布料渲染领域,Charlie的高光公式常被用于实现较为出色的视觉效果,Unity HDRP管线的Fabric Shader是一种较为完整的实现方法。本文旨在基于HDRP管线,探讨棉布与丝绸材质的实现。
棉布材质特征为平纹或斜纹,这类材质几乎无镜面反射,粗糙度极高;相反,丝绸材质拥有显著的镜面反射能力,表面光滑,高光光泽明显,并且展现出各向异性特点。
实现过程中,需准备BRDF LUT贴图。棉布材质使用特定的Fabric Charlie LUT贴图,而丝绸材质则采用Disney GGX LUT贴图。为了增加布料细节,还需要添加Thread贴图(螺纹贴图)和Fuzz贴图(绒毛贴图)。
棉布渲染时,其直接光漫反射与光通量无关,仅与粗糙度相关。HDRP的高光项采用Charlie的法线分布与可见性项。Fabric Charlie LUT解码时需注意,直接光漫反射和镜面反射部分应除以π,与HDRP Fabric Shader源码中使用的版本保持一致。
丝绸渲染则遵循PBR篇章中的迪士尼漫反射公式。高光部分使用Smith Joint的各向异性GGX高光的D项与V项。丝绸材质使用Disney GGX LUT,LUT解码方式与棉布有所不同。在渲染丝绸时,进行除以π的操作,以确保布料整体效果不会过亮。各向异性渲染中,通常使用切线与副切线,若资产提供法线贴图,则需考虑法线贴图中的法线是否需要调整切线与副切线方向。HDRP的布料渲染流程中并未对切线与副切线进行调整,但有的博客提及了调整方法,无需使用三角函数,性能更为高效。各向异性间接光通过调整后的法线进行计算,调整anisotropy值以选择偏移强度,并结合anisDirection参数进行间接光照计算。解码LUT时,使用原始的NdotV。
在Filament引擎中,可手动设置Sheen Color颜色,以调整布料的高光光泽颜色。该引擎文档提供了详细的解释和代码,关于布料次表面散射的特性在文档中亦有提及,但本文未进行实现。
本系列文章旨在全面探索布料渲染技术,涵盖多种材质的实现与优化。在后续篇章中,将更深入地探讨不同技术细节与实际应用案例,旨在为读者提供全面且实用的布料渲染知识。如需进一步了解相关技术与实现细节,欢迎查阅本系列其他文章及官方文档资源。