0

我正在开发一个 CG 着色器,它将在低端硬件上进行有限数量的顶点动画(或“变形”)。我会将动画帧打包到额外的 texcoords 中(有限的分辨率对于我需要做的事情是可以接受的)并在运行时根据主机程序提供的控制值在它们之间进行插值 - 实际上是从姿势 1 到 N 的滑块(N 可能是 6,这看起来像是我必须玩的 texcoords 的数量)。

我知道如何在传统的编程上下文中实现 catmull 插值,但我不确定采用着色器的正确方法。这里有一些具体的问题:

1)我已经看到了以代数和矩阵形式表示的 catmull 插值(这里的例子。在 OGL-ES2 硬件上,一种形式可能比另一种形式更高效吗?

2)我有代数形式适用于一系列花车;它工作正常。但是我似乎无法声明一个 float4s 数组来保存可能的数据。如果我在此示例中更改 line uniform float Key[8] :

sampler2D _MainTex;
float     _KeyTime;
uniform float Key[8];

    struct v2f {
            float4 pos   : SV_POSITION;
            float4 color : COLOR0;


        };

    float4 catmull (float p0, float p1, float p2, float  p3, fixed t)
        {

        fixed t2 = pow(t, 2);
        fixed t3 = pow(t, 3);
        return .5 * ((2.0 * p1) + (-1 * p0 + p2) * t + 
                (2 * p0 - 5 * p1 + 4 * p2 - p3) * t2 +
                (-1 * p0 + 3 * p1 - 3 * p2 + p3) * t3)
                ;
        }


    v2f vert (appdata_base v)
        {
            v2f o;
            o.pos = mul (UNITY_MATRIX_MVP, v.vertex);

            Key[0] = float(1);
            Key[1] = float(1);
            Key[2] =  float(.8);
            Key[3] =  float(.6);
            Key[4] =  float(.4);
            Key[5] =  float(.2);
            Key[6] =  float(.1);
            Key[7] =  float(.1);
            int prior = trunc(_KeyTime);

            o.color = catmull(Key[prior], 
                            Key[prior + 1],
                             Key[prior + 2], 
                             Key[prior + 3], 
                             frac(_KeyTime));
            return o;

统一float4[8] 键;着色器仍然可以编译,但我从统一收到一个错误,说“没有子着色器可以在这个硬件上运行”,我认为这是对其他东西的误导性反映(我有很多其他着色器具有多通道等工作美好的)。如果我在 vert 程序中声明数组而不是统一,我会收到一个错误,即具有非静态索引器的数组需要统一。那么,有没有办法摆脱这种混乱呢?

PS 我匆忙将 catmull 函数更改为在浮点数上工作,只是为了测试一个假设,即它是关于声明一个导致问题的 float4s 数组的东西。

4

2 回答 2

0

我注意到您在输入为浮点时声明了 catrom 输出 float4。为什么?

尝试实际执行您说您计划执行的操作:将 Key 值声明为输入顶点数据的一部分。在这种情况下将其声明为“统一”似乎很尴尬,并且可能会使编译器感到困惑,只需将其作为输入结构的一部分,并且不要尝试覆盖着色器中的值。以这种方式在 texcoords 上声明额外值对于动画蒙皮非常常见。

于 2013-11-24T18:35:01.163 回答
0

对于未来的读者:

解决方案是显然不想编译包含动态索引的着色器 - 这不适用于所有平台,因此编译器显然过于热心地决定在我瞄准的目标的情况下不允许它( IOS 6+ / DX9)。所以它是“设计使然”而不是一个错误,尽管这并没有让它不那么烦人。

我能想到的最好的解决方法是使用Float4x4s,就好像它们是 16 单元数组一样。除了要选择的正确行和列之外,您可以使用全为零的 float4 向量来获取正确的值。将列向量乘以矩阵(就像转换它一样),然后将其点在行向量上。这给出了[行,列]处的项目。解决方法很痛苦,但确实有效。显然,同样的技巧可以用于无点积步骤,仅将行提取为 float4s。

于 2013-11-25T00:44:34.133 回答