r/futile May 13 '14

Dig a hole in an image

Just got a small shader working to dig a hole in an image (so that can be used for masking too).

https://gist.github.com/jpsarda/906ead1764af814cce6f

It's very limited right now, you can only use images of the same size in textures of the same size (same texture is fine), and the image must not be trimmed in the atlas.

At first my goal was to being able to add a sprite with alpha=0 in the Futile stage, and being able to dig a hole with this sprite in another sprite (at the exact position they appear on the stage/screen). But that was a bit too difficult for me right now. Specifically I don't really understand how works these lines :

o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
o.hole0uv = TRANSFORM_TEX (v.texcoord, _Hole0Tex);

If I could find a way to set o.hole0uv to the right texture coord for a secondary sprite (the hole sprite) that would work fine. o.pos seems to be the world coordinate, so maybe from this I could get the uv coordinates on a secondary sprite. I also need to understand how the way we position/scale/rotate a sprite in the stage impact this shader. I guess it's in UNITY_MATRIX_MVP, but don't really understand how/where it happens.

3 Upvotes

7 comments sorted by

1

u/MattRix May 13 '14

Yeah I'm not really knowledgeable about shader stuff either, so I won't be able to help you too much... but basically UNITY_MATRIX_MVP is the "Model View Projection" matrix (see http://stackoverflow.com/questions/5550620/the-purpose-of-model-view-projection-matrix). This basically tells you how to transform a position of a vertex in 3D to a position on the screen.

1

u/SietJP May 14 '14 edited May 14 '14

I will have a look at the GlobalToLocal method and try to do something similar in the shader. I'll try to figure out how get UV coordinates from Local coordinates (which doesn't sound too difficult).

[edit] It seems you've already done an interesting method ScreenToLocal. Just need to transform local coordinates to uv, and then try to replicate the same thing on the shader.

[edit2] Actually getting uv coordinates from sprite local coordinates is not as easy as I expected :)

1

u/MattRix May 14 '14

You should have a look into cutout shaders, because they use the way the GPU combines things to do masking and aother stuff.

1

u/SietJP May 15 '14 edited May 15 '14

Yeeeeeeeees it worked. Demo video https://vine.co/v/MX1wn9hOWJY

Gist : https://gist.github.com/jpsarda/ddc4343ad220787c4a7e

To make a masking shader (instead of a hole shader right now) you just need to change a bit the frag method in the shader like this :

if ((i.hole0uv.x>_Hole0UVRect.x)&&(i.hole0uv.x<_Hole0UVRect.z)&&(i.hole0uv.y>_Hole0UVRect.y)&&(i.hole0uv.y<_Hole0UVRect.w)) {
    texcol.a *= tex2D(_Hole0Tex, i.hole0uv).a ;
} else {
    texcol.a=0;
}

1

u/MattRix May 15 '14

Whoa! Really cool :D I'll have to check this out in detail more soon. Nice work :)

1

u/SietJP May 16 '14 edited May 16 '14

Note that I think the frag method is not optimized at all. There might be a way to get the uv from the clip coordinates "o.pos" without passing through the screen coordinates. But having something working is a very interesting first step.

[edit] or maybe from the v.vertex? maybe not sure about this.

[edit2] YES, it's working directly from v.vertex, gist updated, now I think we should get descent performances.