Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
2
Question by Sharlatan · Nov 09, 2013 at 01:04 AM · shadergraphicsscalingimage effectsblit

How to (efficiently) make an image pixelated?

I'm trying to write a "Retro Filter" image effect.

Basically I have two steps for now.

  1. Make the image pixelated

  2. Reduce the amount of different colors in the image

For step 2 I'm using a simple shader I wrote that shrinks down the amount of possible colors But step 1 doesn't work. You know how a picture gets very pixelated and "blocky" when you scale it down and up again in an image editing program (Photoshop, Gimp, Paint, etc.)? That's exactly what I was looking for. So, I decided to scale the Image down and up again in OnRenderImage. The code for that looks like this:

 RenderTexture scaleBuffer = RenderTexture.GetTemporary(source.width / DownscaleFactor, source.height / DownscaleFactor);
 
 accumTexture.MarkRestoreExpected();
 Graphics.Blit(accumTexture, scaleBuffer);
 Graphics.Blit(scaleBuffer, accumTexture);
 RenderTexture.ReleaseTemporary(scaleBuffer);

I assumed that would exactly do what I want. But instead of feeling blocky, it looks very washed out. Here you can see it with DownscaleFactor set to 8: Result with factor 8

"Ok, that looks a bit washed out but it surely will get better if I scale it down even more and then back up again! At least that's what i was thinking. But this is what happens when I set DownscaleFactor to 32: Result with factor 32

I have no Idea why this is happening. I tried turning AA off everywhere I could, including setting the AA level of the RenderTexture objects to 1.

I'd be ever so grateful if someone could tell me why this is happening, what I can do about it or what else would work to get the picture all blocky. I'm sure a shader might work but the shader I wrote for reducing the colors was my first shader ever and I'm just about to learn the basics. I have no idea how to go about writing a "pixeling" shader and the down- and upscale approach felt very intuitive to me.

Thank you very much for your help!

Comment
Add comment
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

3 Replies

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

Answer by Bunny83 · Nov 09, 2013 at 02:10 AM

Your problem is the filtermode of your texture. You should set it to "point".

Comment
Add comment · Show 5 · 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 Cherno · Nov 09, 2013 at 02:18 AM 0
Share

Correct, I just started up Unity to check my answer and it's indeed the Point filter mode.

avatar image tanoshimi · Nov 09, 2013 at 08:04 AM 0
Share

@cherno - so please mark this as the correct answer.

avatar image Sharlatan · Nov 09, 2013 at 09:43 AM 0
Share

@Bunny83 This was indeed the problem, thank you very much! Although I'm not new to program$$anonymous$$g, I'm very new to graphics program$$anonymous$$g and I just didn't realize that the filtering does not only occur when e.g. walking towards a texture or away from it but also if you manually blit it from one buffer into another. Now it makes sense and I almost feel stupid. But you have no idea how happy you made me! :)

Here's a comparison shot of the filter in case you're interested in the result: Comparison

$$anonymous$$ight I ask you if you think that this is an efficient approach to pixelate the picture from a computational point? And thanks again!

avatar image Bunny83 · Nov 09, 2013 at 04:31 PM 0
Share

Well, beside setting the screen resolution to your target resolution (which isn't possible anymore for very small resolutions), I don't think you can get it any faster ;)

Since you render your whole scene to a small rendertarget you actually increase the performance since all expensive fragment shaders only run for a small amount of "fragments". If you downscale by 8 that means 8x8 = 64 so only 1/64 of the screen area is actually rendered. The blitting operation is quite cheap (especially with point filtering since you only sample one texel per screen pixel ins$$anonymous$$d of 4 or 8 like you would with billinear or trilinear filtering).

So you're actually $$anonymous$$imizing the actual scene-rendering fillrate by using a small render target and the most efficient blitting filter ;)

avatar image Sharlatan · Nov 17, 2013 at 08:00 AM 0
Share

@Bunny83 Thank you very much for further explaining things to me! Things are quiet a bit clearer now. Although I studied computer science and am working as a programmer for a living, I never laid my hands on games before and I find myself having a much harder time finding comprehensive information about certain topics than I had with other fields of program$$anonymous$$g. Sometimes I feel that most of the things I find are either described so superficially that I don't gain anything from it or so specific and in-depth that I almost already need to understand the topic very well. $$anonymous$$aybe you know what I mean.

In any case: I want to thank you very much for helping me out and making things clearer although those questions are probably stupid beginner problems ;) One of the greatest things when working in this industry is the amazing user base (stackoverflow e.g.) and you are one of those pieces of the puzzle that make it so great :) Thanks again!

avatar image
1

Answer by Owen-Reynolds · Nov 09, 2013 at 05:52 AM

Don't think I've ever done this, but could you have the shader round the texture coords to the nearest 1/100th? Something like: IN.uv.x = (frac(IN.uv.x/100)*100; (same for y, unless frac is a vector operation.)

Then get fancy and have the 100 be a uniform var, if that works.

Comment
Add comment · Show 1 · 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 Sharlatan · Nov 09, 2013 at 09:51 AM 0
Share

Thanks for this idea! Now that I read it, it fells so simple and obvious it almost makes me want to bang my head against my desk. How could I not see this? I was way overthinking it. Even though I got it working now, I'll also try out your idea out of curiosity and to get some more practice with shaders. Also, I'll upvote you as soon as I have enough karma to do so. Sadly, I can't at the moment even though your idea's great.

avatar image
0

Answer by Cherno · Nov 09, 2013 at 02:01 AM

I think it's not about the AA, but about the Anisotropic Filtering that is on by default and can't be disabled as far as I know, at least not for normal model textures.

Edit: I confused AF with Bilninear Filtering, my bad.

Comment
Add comment · Show 2 · 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 Bunny83 · Nov 09, 2013 at 02:18 AM 0
Share

Anisotropic Filtering is just a special kind of mip-mapping which only applies when viewing a surface at a low angle. Since he's blotting the textures the angle will always be 0. So AF has no effect here.

avatar image Cherno · Nov 09, 2013 at 02:19 AM 1
Share

Correct, I mixed it up with Bilinear Filtering, thanks for the note :)

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

20 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

Related Questions

Save a texture after a pass in shader 0 Answers

dynamic hole in layer / texture / camera 0 Answers

Blit into Texture2DArray slice not working in WebGL 0 Answers

OpenGL ES 2.0 support breaks simple shader 0 Answers

use RenderTexture on a sphere correctly? 1 Answer


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