Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by tcz8 · Feb 07, 2017 at 09:18 PM · shaderspriteshaderssprites

Skew a sprite at runtime while preserving the pixel shape?

Hello,

I currently use a 4x4 transformation matrix within a vertex shader to skew (or is it shear?) my sprites. It works but it is also skewing the shape of individual pixels which gives a weird look to my pixel art.

Transformed by my current shader: alt text

Transformed by Gimp's perspective tool, notice the pixels are still square: alt text

  • What would be the best way of skewing a sprites without affecting the pixel shapes?

  • Is there a trick that could be used to correct the result of the vertex shader? Force all edges to be either vertical or horizontal? (that one is for you shader gurus.. I know your out there!)

FYI I have also tried applying my transformation matrix to the texture coordinates but it's giving similar results. I have also came accross an opengl article mentionning something about modifying the coordinates while doing something similar to a tex2d lookup but I didnt quite get it and lost the link :(

EDIT: Hey followers! Ok, no definitive answer but there's lots of people following this. How about a group brainstorm? Pitch in some ideas! No matter how far fetched it sounds just pitch it in, worst case it will serve to elimiate what doesnt/can't work. Personally my shader knowledge is limited but im sure that as a group we can manage it! I'll update this question with our R&D results as we go.

What doesnt work:

  • 4x4 Transform matrix on the vertex also skew the pixel shape

  • 4x4 Transform matrix on the texture coordinates also skew the pixel shape and causes the texture to move outside the sprite's mesh, making parts of it disappear.

circletransformedgimp.png (684 B)
circletransformedshader.png (3.9 kB)
Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image aFeesh · Feb 07, 2017 at 09:48 PM 1
Share

Have you tried http://www.sector12games.com/skewshear-vertex-shader/

avatar image tcz8 aFeesh · Feb 07, 2017 at 09:58 PM 0
Share

Yes, same results.

avatar image elenzil · Feb 08, 2017 at 07:39 PM 1
Share

i'm not sure transformation matrices are going to do this for you.

you may need to dynamically create a new texture and do the skew yourself to the actual pixels.

skew is an affine transformation, and one of the properties of all affine transformations is that parallel lines in the original are still parallel after the transformation. so consider your original image. the walls of each pixel are vertical, and the walls of the overall image are also vertical: they're parallel. but after the skew, what you want is the walls of the overall image to be slanted but the walls of the individual pixels to still be vertical: no longer parallel. therefore no affine transformation will achieve this.

what's going on in the Gimp version is that individual pixels are being moved, while in the shader version it's the geometry/texture mapping underneath the pixels which is being transformed.

avatar image tcz8 elenzil · Feb 08, 2017 at 08:32 PM 0
Share

Thats confirms what I tought was going on, thx.

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by FortisVenaliter · Feb 08, 2017 at 08:06 PM

If you're going to do this at runtime, you're probably going to need to write a specialized shader to do so.

The way to do it would be as follows:

When taking in the UV coordinates, multiply them to the target resolution and middle them (like a mix of floor/ceil, leaving you with a .5 after the decimal), then bring them back to the 0-1 UV space. This will get you a non-blended UV no matter the scale, as if you were turning off texture filtering.

From there, you can apply your skew function to the modified uv to get the lookup value from the source texture, and output it through the return value of the pixel shader.

That should allow you to get the effect you want. The most likely problem with this is that the geometry won't change, so you'll likely want to use oversized quads to render it with out of bounds UV values so it doesn't skew the image right off the geometry. Just remember to sanitize the UVs in your shader and add a transparent buffer border to your images.

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image tcz8 · Feb 08, 2017 at 08:56 PM 0
Share

Thank you very much, I almost understand what you mean... almost... (/sweat)

Could you or someone else clarify the following points?

  1. Target resolution: Are we talking about the resolution of the sprite when pixels are 1:1 ie.: uv.xy = uv.xy * float2(64,64)? or do I need to take into account the PPU?

  2. $$anonymous$$iddle them: Not sure I know how to do this, is there a built in function?

  3. Sanitize the UV: Obviously of course... mmm how is that done again?

The rest (the easy part) I understand.

Thank you.

avatar image FortisVenaliter tcz8 · Feb 08, 2017 at 09:30 PM 1
Share
  1. Correct.

  2. You can use floor(value)+0.5

  3. Clamp it to 0-1

avatar image tcz8 FortisVenaliter · Feb 09, 2017 at 05:52 PM 0
Share

Hi, I got my code together and the good news is it does preserve the pixel shape. The bad news is it completely deforms the sprite.

Here it is with no transformation code applied, the circle is deformed anyways:

Here it is with an horizontal transformation of -0.2. When increasing the value (in the negaives) it first enlarges then eventually moves further to the right. Going into positive values makes it colapse on itself from both sides equally until pixels start disapearing and nothing is left.

Here is the code from my fragment shader:

 // Build a transform matrix
 float4x4 transform$$anonymous$$atrix = float4x4(
     1,-0.2,0,0,
     0,1,0,0,
     0,0,1,0,
     0,0,0,1);
 
 // $$anonymous$$ultiply UV by target res (actual resolution of the png file)
 float2 uv = IN.texcoord * float2(24, 24);
 
 // $$anonymous$$iddle the values
 float2 middleUV = floor(uv) + 0.5;
 
 // Bring values back to 0-1 UV space
 float2 normalizedUV = normalize(middleUV);
 
 // Sanitize UV values
 float2 sanitizedUV = clamp(normalizedUV, 0, 1);
 
 // Apply transform matrix
 float2 transformedTextcoord = mul(transform$$anonymous$$atrix, sanitizedUV);
 
 // Fetch the color and apply tint
 fixed4 c = tex2D(_$$anonymous$$ainTex, transformedTextcoord) * IN.color;
 
 // Apply the alpha
 c.rgb *= c.a;
 
 // Output the values
 return c;


Since we normalize the values, do we really need to sanitize them afterwards?

To be honest, other than having something to do with "upscaling" the UV map and middleing the values, I dont understand how this manages to keep the pixels straight. If you have the time to explain the logic behind it I may be able to troubleshoot it.

Thank you very much.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

112 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Allow 2D sprite to receive light from any direction and show on both sides 0 Answers

Are shaders more efficient than manual pixel replacement? 0 Answers

Grass shader sprite 2D 3 Answers

Shader on 3D model not seen over 2D sprites 0 Answers

Distort shader not showing sprites 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges