unity3d 如何在着色器中实现“缩放独立”?

9gm1akwq  于 2023-01-31  发布在  其他
关注(0)|答案(1)|浏览(149)

我试图使边界使用矩形sdf,但与不同的规模,它得到扭曲。
我在考虑对象比例,但我自己不知道该怎么做
对象比例:(1,1),(1,0.125)
How it looks
Desired result (Made in photoshop, slightly out of proportion)
有顶点,片段着色器和矩形函数

float rectangle(float2 position, float2 size){
    float2 component_wise_edge_distance = abs(position) - size;
    float outside_distance = length(max(component_wise_edge_distance, 0));
    float inside_distance = min(max(component_wise_edge_distance.x, component_wise_edge_distance.y), 0);
    return outside_distance + inside_distance;
}

v2f vert(appdata v){
    v2f o;
    o.position = UnityObjectToClipPos(v.vertex);
    o.uv = v.uv;
    return o;
}

float4 frag(v2f i) : SV_TARGET
{
    half3x3 m = UNITY_MATRIX_M;
    half3 objectScale = half3(
        length( half3( m[0][0], m[1][0], m[2][0] ) ),
        length( half3( m[0][1], m[1][1], m[2][1] ) ),
        length( half3( m[0][2], m[1][2], m[2][2] ) )
    );
    
    float4 coords = i.uv;
    coords *= 8;

    float2 position = float2(coords.x - 4, coords.y - 4);
    float sdf = step(0, rectangle(position, float2(3, 3)));
    
    float4 col = float4(sdf.xxx, 1);
    return col;
}
ergxz8rk

ergxz8rk1#

是的,您需要在计算中使用比例。
首先,将坐标居中,使其从-1到1而不是从0到1。

float2 coords = i.uv * 2 - 1;

用你的尺度缩放你的坐标。

coords *= objectScale;

现在定义你的矩形的比例边界.

float border = 0.2;
float2 size = float2(objectScale.x - border, objectScale.y - border);
float sdf = rectangle(coords, size);
sdf = step(0, sdf);

这将给予你一个固定宽度的边框,而不管缩放比例如何,尽管从你的图像看起来你希望它随着缩放比例而缩小。要做到这一点,你可以通过最小的轴缩放边框。

border = border * min(objectScale.x, objectScale.y);

请注意,使用对象比例将不适用于UI元素,因为当它们到达着色器时Unity已经将它们全部批处理在一起,它们的对象比例是没有意义的。如果是这种情况,您需要将比例作为脚本中的变量传入。

相关问题