The theory of this relies on one property of the cross product, that it can be replaced by a matrix multiplication. The other operations in the shader scale and offset the vector, and are equivalent to scaling and translation matrix operations. So it should be possible to create a matrix that transforms a colour the same way as the shader does, and use a ColorMatrixFilter to apply it.
At least that is the theory. In practice it turned out to be much more work than I expected. The resulting code is here on Wonderfl, forked from the shader code, and is much longer and more complex than that. In particular:
- Everything is now matrices, so the operations to scale and offset, previously single lines of mathematics, now require matrices to be created, scaled and translated (although at least this can be done beforehand).
- I subclassed the Matrix3D class as recommended by the documentation to avoid it complaining about being passed non-invertable matrices (though I did this before I got it working so don't know if it's necessary).
- It seems there's no way to pass the raw values to the Matrix3D constructor, or at least that seemed not to work. Instead I had to get the existing rawData and modify it.
- More generally one problem Flash has is a profusion of ways of handling matrices. As well as Matrix and Matrix3D classes many functions that use matrices such as the ColorMatrixFilter actually take a Vector or Array of numbers, making the code very verbose.
This, together with the need to synthesise the cross product with a matrix, makes the code much longer. And it doesn't work identically. Compared to the shader it is much darker, as the 50% grey that should be added back in by the final transformation seems to be missing.
This is a fairly artificial example, as it's not only an impractical shader but it's one written to experiment with the mathematical operations of the shader language. It's not surprising that it was hard to code in ActionScript. It does show though what's possible with a ColorMatrixFilter and despite the length of the code it performs pretty well.
No comments:
Post a Comment