Rounded Polygon 节点
描述
以输入 Width 和 Height 指定的大小基于输入 UV 生成圆角多边形。输入 Sides 确定多边形的边数,输入 Roundness 定义每个角的圆度。
通过连接 Tiling And Offset 节点可以偏移或平铺该形状。为了保留在 UV 空间内偏移形状的能力,如果进行平铺,形状将不会自动重复。要实现重复圆角多边形效果,应首先通过 Fraction 节点连接 UV 输入。
Rounded Polygon 节点只能在片元着色器阶段使用。
端口
名称 | 方向 | 类型 | 绑定 | 描述 |
---|---|---|---|---|
UV | 输入 | 矢量 2 | UV | 输入 UV 值 |
Width | 输入 | Float | 无 | 圆角多边形宽度 |
Height | 输入 | Float | 无 | 圆角多边形高度 |
Sides | 输入 | Float | 无 | 多边形的边数 |
Roundness | 输入 | Float | 无 | 角的圆度 |
Out | 输出 | Float | 无 | 输出值 |
生成的代码示例
以下示例代码表示此节点的一种可能结果。
void RoundedPolygon_Func_float(float2 UV, float Width, float Height, float Sides, float Roundness, out float Out)
{
UV = UV * 2. + float2(-1.,-1.);
float epsilon = 1e-6;
UV.x = UV.x / ( Width + (Width==0)*epsilon);
UV.y = UV.y / ( Height + (Height==0)*epsilon);
Roundness = clamp(Roundness, 1e-6, 1.);
float i_sides = floor( abs( Sides ) );
float fullAngle = 2. * PI / i_sides;
float halfAngle = fullAngle / 2.;
float opositeAngle = HALF_PI - halfAngle;
float diagonal = 1. / cos( halfAngle );
// Chamfer values
float chamferAngle = Roundness * halfAngle; // Angle taken by the chamfer
float remainingAngle = halfAngle - chamferAngle; // Angle that remains
float ratio = tan(remainingAngle) / tan(halfAngle); // This is the ratio between the length of the polygon's triangle and the distance of the chamfer center to the polygon center
// Center of the chamfer arc
float2 chamferCenter = float2(
cos(halfAngle) ,
sin(halfAngle)
)* ratio * diagonal;
// starting of the chamfer arc
float2 chamferOrigin = float2(
1.,
tan(remainingAngle)
);
// Using Al Kashi algebra, we determine:
// The distance distance of the center of the chamfer to the center of the polygon (side A)
float distA = length(chamferCenter);
// The radius of the chamfer (side B)
float distB = 1. - chamferCenter.x;
// The refence length of side C, which is the distance to the chamfer start
float distCref = length(chamferOrigin);
// This will rescale the chamfered polygon to fit the uv space
// diagonal = length(chamferCenter) + distB;
float uvScale = diagonal;
UV *= uvScale;
float2 polaruv = float2 (
atan2( UV.y, UV.x ),
length(UV)
);
polaruv.x += HALF_PI + 2*PI;
polaruv.x = fmod( polaruv.x + halfAngle, fullAngle );
polaruv.x = abs(polaruv.x - halfAngle);
UV = float2( cos(polaruv.x), sin(polaruv.x) ) * polaruv.y;
// Calculate the angle needed for the Al Kashi algebra
float angleRatio = 1. - (polaruv.x-remainingAngle) / chamferAngle;
// Calculate the distance of the polygon center to the chamfer extremity
float distC = sqrt( distA*distA + distB*distB - 2.*distA*distB*cos( PI - halfAngle * angleRatio ) );
Out = UV.x;
float chamferZone = ( halfAngle - polaruv.x ) < chamferAngle;
Out = lerp( UV.x, polaruv.y / distC, chamferZone );
// Output this to have the shape mask instead of the distance field
Out = saturate((1 - Out) / fwidth(Out));
}