仅对某些顶点进行顶点着色器

3

我正在尝试编写一个只应用于某些顶点的顶点着色器。

在Unity中,文本被呈现为一系列不连续的四个顶点的多边形。 我正在尝试分别对这些多边形进行变换/旋转/缩放。 以便我可以单独移动每个字母。

我认为这是不可能的,但如果每个顶点都有一个ID,我可以将它们分组为0-3、4-7等,并进行移动。

是否有任何技巧可以根据它们所连接的对象或它们的“编号”来修改顶点?


1
请使用unity3d标签来标记那个东西。unity标签是用于微软Unity的。 - Lex Li
1
我的错,我以前从未听说过MS Unity :) 我将来会使用unity3d。 - benui
1个回答

2

我不相信你可以直接这样做,但你可以使用第二个UV通道来存储你的ID。

这里有一个重新设计的Unity法线着色示例,使用“顶点ID”来确定何时将法线应用为颜色。

Shader "Custom/ColorIdentity" {
Properties {
    //_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
    Pass {  
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct appdata {
                float4 vertex : SV_POSITION;
                float3 normal : NORMAL;
                float4 texCoord2 : TEXCOORD1;
            };
            struct v2f {
                float4 pos : SV_POSITION;
                float3 color : COLOR0;
            };

            v2f vert (appdata v)
            {
                v2f o;

                //here is where I read the vertex id, in texCoord2[0]
                //in this case I'm binning all values > 1 to id 1, else id 0
                //that way they can by multiplied against to the vertex normal
                //to turn color on and off.
                int vID = (v.texCoord2[0]>1)?1:0;   

                o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                o.color = v.normal * vID; //Use normal as color for vertices w/ ids>1
                return o;
            }

            half4 frag (v2f i) : COLOR
            {
                return half4 (i.color, 1);
            }
        ENDCG
    }
}
Fallback "Diffuse"
} 

此外,这是我编写的虚拟脚本,用于分配完全任意的ID。 ID是基于顶点在y轴上的位置分配的。边界是根据我手头的网格随机选择的:

public class AssignIdentity : MonoBehaviour {
public GameObject LiveObject;

// Use this for initialization
void Start () {
    Mesh mesh = LiveObject.GetComponent<MeshFilter>().mesh;
    Vector3[] vertices = mesh.vertices;
    Vector2[] uv2s = new Vector2[vertices.Length];

    int i = 0;
    foreach(Vector3 v in vertices){
        if(v.y>9.0f || v.y < 4.0){
            uv2s[i++] = new Vector2(2,0); 
        } else {
            uv2s[i++] = new Vector2(1,0);
        }
    }
    mesh.uv2 = uv2s;
}
}

2
对于这个好建议点赞。顺便说一下,如果他需要独立地转换每个字母,他是否可以为每个字母创建一个文本网格? - Heisenbug
@Heisenbug 哦,好吧,你选择了简单的路线。:) 但是,你说得很对。最简单的解决方案是将每个字母作为自己的文本网格。 - Jerdak
1
@Heisenbug 我也想过这个问题,但是这样会不会破坏字距?一定有一种方法可以访问 Text Mesh 下面的多边形... - benui
1
@Ben Humphreys:说得好,我没有考虑到那一点。所以,如果只是将不同的着色器效果应用于每个四边形/字母,我会采用Jerdak的解决方案。但是,如果您想要“我正在尝试单独转换/旋转/缩放这些多边形。”那么字距调整无论如何都会被您应用的变换打破,对吧? - Heisenbug
我在考虑一个逐字动画。它们会飞行/旋转/缩放和淡出,坐在正确的字距位置,然后再次动画化。 - benui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接