I'm working on a CG shader which will do a limited amount of vertex animation (or 'morphing') on low end hardware. I'll be packing animation frames into extra texcoords (the limited resolution is acceptable for what I need to do ) and interpolating between them at runtime based on a control value provided by the host program - effectively a slider that goes from pose 1 to N (N is probably 6, that looks like the number of texcoords I have to play with).
I know how to implement the catmull interpolation in a conventional programming context, but I'm not sure the right approach to take in a shader. Here's some concrete questions:
1) I've seen the catmull interpolation expressed in algebraic and matrix form (examples here. Is one form likely to be more performant than the other on OGL-ES2 hardware?
2) I've got the alegebraic form working for a sequence of floats; it works fine. However I can't seem to declare an array of float4s to hold may data. If I change the line uniform float Key[8] in this example:
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;
to uniform float4[8] Key; the shader still compiles but I get an error from unity saying 'No subshaders can be run on this hardware', which I take to be a misleading reflection of something else (I've got plenty of other shaders with multipass and so on that work fine). If I declare the array inside the vert program instead of as a uniform, I get an error that arrays with non static indexers need to be uniform. So, is there a way out of this mess?
PS I hastily changed the catmull function to work on floats just to test the hypothesis that it was something about declaring an array of float4s that caused the problem.