Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How can I fake 3D sprite rotation in 2D (ex. with skewing)?

Discussion in 'Shaders' started by Bixbite, Jul 26, 2015.

  1. Bixbite

    Bixbite

    Joined:
    Nov 1, 2012
    Posts:
    12
    This is one of those cases where I'm looking to do a fairly specific thing, but perhaps there's a better way to achieve my goal, so feel free to suggest other possible means to accomplish this!

    Objective: To render 2D sprites (meshes) with an orthographic camera in such a way that they appear to be rotating away from the viewer in perspective space.

    This effect is being performed on a custom sprite class, which uses MeshFilter/MeshRenderer components, not SpriteRenderer. So far I've only got a very basic implementation; assuming the sprite in question is a single quad, I'm manipulating the vertices of said quad to get the desired shape, gradually skewing the sprite to create the illusion of it rotating away in 3D space. That much works so far, the sprite does look like it's rotating away, but the sprite's texture doesn't look quite right during the skewing...

    Here's an image to demonstrate what I have (red) and what I'm aiming for (green):


    The issue is that the texture is essentially "folding" across the quad's middle edge. It appears that I need a custom shader to skew not just the vertices of the mesh, but the texture coordinates as well, to get the perspective effect shown on the right.

    Question 1: What's the math behind skewing the texture data to get the perspective effect shown above?

    Question 2: Manually adjusting vertices on a single quad is simple, but what's the correct way to skew the vertices of any arbitrary 2D mesh to create the same perspective rotation effect (ex. a sliced sprite)?

    Alternate question, am I going about this in all the wrong ways, and is there a better method of faking 3D rotation in 2D sprites? Thanks in advance!
     
  2. brownboot67

    brownboot67

    Joined:
    Jan 5, 2013
    Posts:
    375
    The theory is pretty straight forward, create a mask for local X position. Use this to mask how much Y and X scaling is applied relative to the center of the mesh (mul(_Object2World,float4(0,0,0,1))).

    However, I am also stuck getting the above mesh center to return anything but 0s on Sprites and Rects w/ Images : http://forum.unity3d.com/threads/_object2world-vs-ui-canvas.343538/

    BUT, it does work fine on 3d meshes.

    So my not terribly helpful solution is to just put your texture on a plane, simply rotate the plane, and render it with a perspective camera. (or an orthographic and then you only need to scale the corners as before in your shader).
     
  3. Bixbite

    Bixbite

    Joined:
    Nov 1, 2012
    Posts:
    12
    Thanks for the idea about skewing vertex coordinates, I'll test some things out when I get the chance.

    I've thought about using additional cameras to render the cells separately, but I'm worried about rendering overhead affecting performance (this is for a mobile game). Perhaps I could rig something up so that a second camera renders directly to the portion of the screen the cell takes up, rather that using RenderTextures... a simpler solution would have been nice though.

    This makes me wonder how rendering systems draw textures on 3D meshes in the first place. There must be a step in the rendering pipeline that somehow skews texture data based on distance from camera or normals or something, to prevent the issue I'm having here from occurring in everyday 3D rendering...
     
  4. Bixbite

    Bixbite

    Joined:
    Nov 1, 2012
    Posts:
    12
    Oh, I found another example of what I'm seeing here!

     
  5. Bixbite

    Bixbite

    Joined:
    Nov 1, 2012
    Posts:
    12
    Bingo, the article here described the difference between linear texture interpolation and projective texture interpolation, which is the solution to what I'm looking for! I'm taking notes now and planning on coming up with either a solution using what Unity has to offer, or just a custom shader like the one described in the linked article!
     
    Thomas-Mountainborn likes this.
  6. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
    I was about to pop up and say that the affine texture mapping's the issue, but it appears you worked that out yourself! :) Well done. :)