Can’t use UVs because they are not in local space but relative to the entire atlas texture
Sprites can’t use local vertex space only models can?
GLES version does not support the function required to turn world into local?
I want to make shaders which can impact sprites directionally without needing to isolate them in a power of 2 atlas / use a mesh instead of a normal sprite component.
I see that in a material there is the choice for local / world vertex coordinates
from local to world you just need to multiply by a matrix and GLES can of course do this
To go from local space to screen space you need the world, view and projection matrix composed (multiplied) together. I think you have them as vertex constants (two of them already multiplied). I don’t remember exactly the order of multiplication (Perhaps view * proj * world * vertex ??? but I am not sure).
If you still need help I may try to write the shader in details. Just let me know.
GLES2.0 cannot do matrix inverse, you need the inverse of the world_matrix to go from world to local
The inverse of a 4x4 matrix is expensive to do per-vertex
BUT, if you are just doing 2D, I would say that the world matrix should be of this form
a b 0 u
c d 0 v
0 0 e w
0 0 0 1
where
the 2x2 submatrix with a,b,c,d takes into account rotations and scaling for x,y and e is for z-scale
u, v, w are the traslation.
If so then the inverse of this type of matrix may be reasonably computed. WARNING: I am not sure if we need this matrix of its transpose (I don’t remember and it depends if the system uses row-vectors or col-vectors).
The engine is precomputing the world * vertex and is passing world = identity to the shader. This is useful for batching sprites… and prevents the computation I was outlining above…
I have to think about this, probably it is not possible.
Is there any special condition in your use case? something we may assume about the sprite? Let me say something stupid: if you don’t need alpha then you may use the alpha channel to bake in the sprite the Y coordinate; then it is obvious to use it in the shader…
That would be neat to try for some effects but for general purpose shaders you want to be able to use alpha.
I don’t know of a real solution, but maybe we could get a new sprite component / a checkbox that gives more freedom with those sprites but doesn’t work in batching.
Maybe you may use two sprites: one with the normal sprite and another one with just the alpha to draw the fill of the sprite and the Y coordinate baked in the red channel. Of course this costs you two sprites.
If your effect is some kind of add-a-color or multiply-by-a-color then this should work.
Does your sprite rotate? If not then you may pass the center position as a user-data constant and compute the local uv. But this breaks the batching of the sprites…
I am sorry for the multiple answers, I am looking for some solution and writing as I think
Hopefully, in the future we have the ability to let the user set the vertex formatfor sprites (and others), just like they can do with meshes.
I don’t think we’ll add an extra set of uv’s as default though, since most users don’t need it.
This was something we said “we’ll add it later if it’s needed”, when introducing the notion of local space coordinates. The reason for that is that it will break the batching and create a unique drawcall for each such sprite. Probably not what you want here either.
Since iOS is supporting Metal now (via our VUlkan backend) and the number of OpenGLES2 on Android is down to 10% (link) we’re looking into updating to OpenGLES 3.
This, for instance, would allow you to use e.g. gl_VertexID to figure out your local uvs (if you’ve turned off sprite trimming so each sprite is 4 vertices).
Between these, I’d say the #3 is pretty close on the horizon and we’ll start working on it this spring.
It’s part of what needs to be decided in the design phase.
But in short, you cannot have both OpenGLES 2 and 3 features in the same shader and expect it to work. You will have to make an active choice of what platforms you support.
E.g. you could opt to support WebGL2, but then only a few browsers would support it.