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
1
Question by eradiuslore · Oct 11, 2011 at 11:22 PM · texture2darraysstencilsetpixelsgetpixels

getPixel/setPixels or stencil eraser brush

hi im trying to build a eraser brush that you can clear away a texture on a gameObject with. i have succeeded in doing so using getPixel and setPixel however i am now encountering a dilemma. at the moment i create the brush around a central pixel then with a little math (and a nested loop) add each pixel in an area around the original pixels co-ordinates to an array with each being set to alpha=0, which is then processed into the new texture for the gameObject. the result of this sets a square of pixels around the mouse position to invisible. my question, is their a better and more efficient way to do this?

i have also attempted to implement a stencil script that paints a texture over another at the point you select, however i cant seem to see a way to make a section invisible if i use an image that is effectively empty.

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

2 Replies

· Add your reply
  • Sort: 
avatar image
9

Answer by KvanteTore · Oct 12, 2011 at 06:58 AM

In order to do the stencil thing, you could create your own shader that takes in the original texture and the stencil texture, and outputs rgb from the original texture and alpha of the stencil texture.

something like this

 Shader "Custom/CustomDiffuse"
 {
     Properties 
     {
         _MainTex("Main Texture (rgb)", 2D) = "white" {}
         _Color ("Main Color", Color) = (1,1,1,1)
         _Stencil("Stencil Texture (a)", 2D) = "white" {}
     }
 
     Subshader
     {
         Tags
         {
             "Queue"="Transparent"
             "IgnoreProjector"="False"
             "RenderType"="Transparent"
         }
         
         CGPROGRAM
             #pragma surface surf Lambert alpha
             #pragma target 2.0
 
             struct Input {
                 float2 uv_MainTex;
             };
     
             half4 _Color;
             sampler2D _MainTex;
             sampler2D _Stencil;
     
             void surf (Input IN, inout SurfaceOutput o) 
             {
                 o.Albedo = tex2D(_MainTex, IN.uv_MainTex) * _Color;
                 o.Alpha = tex2D(_Stencil, IN.uv_MainTex).a;
             }
         ENDCG
     }
 }

Regarding the getpixel/setpixel, if you have unity pro, you could paint your changes to a RenderTexture. That way, the stencil generation is done on the GPU, which is usually a lot faster. The easiest is probably to generate your stencil texture first and then apply that stencil to your texture, either as a shader (as mentioned above) or premultiplied into the texture using another RenderTexture.

To create your stencil, you could create a small brush texture that is opaque in the center and transparent at the edges and use Graphics.DrawTexture to draw int onto the rendertexture at the desired location. The following code is one way of using graphics.blit and graphics.drawtexture to create a stencil (note that I haven't actually tested this, so there might be some bugs).

 void AddToStencil(Texture2D stencil, Texture2D brush, Vector2 brushPosition, int brushSizePixels)
 {
     //Create temporary render texture
     int width = stencil.width;
     int height = stencil.height;
     RenderTexture rt = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32);

     //Copy existing stencil to render texture (blit sets the active RenderTexture)
     Graphics.Blit(stencil, rt);
     
     //Apply brush
     RenderTexture.active = rt;
     float bs2 = brushSizePixels / 2f;
     Graphics.DrawTexture(new Rect(brushPosition.x - bs2, brushPosition.y - bs2, brushSizePixels, brushSizePixels), brush);

     //Read texture back to stencil
     stencil.ReadPixels(new Rect(0, 0, width, height), 0, 0, true);
     stencil.Apply();

     RenderTexture.active = null;
     rt.Release();
 }

Depending on how many of these stencils you want, and how much GPU memory you have, you could also consider having the stencil in a permanent RenderTexture, and save the first blit and the ReadPixels at the cost of having a permanently allocated RenderTexture.

Note that the stencil texture is now inverse, so in the shader above, you would change the alpha to be

   o.Alpha = 1 - tex2D(_Stencil, IN.uv_MainTex).a;

Comment
Add comment · Show 18 · 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 eradiuslore · Oct 12, 2011 at 09:53 AM 0
Share

hmmm interesting, just had a look at graphics.blit, how would you go about 'painting' the texture onto the rendertexture say in a small area rather than painting an entire image onto another, from what i can see pass might have something to do with it but im a little unsure how that works.

avatar image KvanteTore · Oct 12, 2011 at 10:30 AM 0
Share

updated answer to include some more details regarding rendertextures

avatar image eradiuslore · Oct 13, 2011 at 05:51 PM 0
Share

ok a few further questions (sorry!) should i use a rendertexture on gui or just on a plane/gameObject? im also a little unclear on how your actualy using Graphics.DrawTexture to draw the stencil onto the rendertexture. how does ReadPixels free up the render texture and return the stencil back to normal?

avatar image KvanteTore · Oct 13, 2011 at 09:07 PM 0
Share

I added an example of how you could update your stencil buffer using the GPU. We're using a similar technique for texture stamping in our avatar system, and if you have a lot of pixels to update it is a lot faster than setting pixels using SetPixel or SetPixels

avatar image KvanteTore · Oct 26, 2011 at 10:02 AM 2
Share

sweet. I would apreciate it if you mark my answer as accepted :)

Show more comments
avatar image
0

Answer by dbravo · Apr 05, 2012 at 12:39 PM

How can this be done if you don't have Unity pro? I need something like this for iPhone and Get/Set pixels runs too slow on that device

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 KrishnaMV · Sep 17, 2013 at 12:31 PM 0
Share

yaa....getpixel and setpixels r too slow in devices...lead to crash also..in low end devices...hw to resolve this prob with optimised solution...???!!

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

8 People are following this question.

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

Related Questions

Painting stencil on a surface. 6 Answers

Setting pixels on a texture? 2 Answers

Setpixels leads to a blank texture? 1 Answer

How can I show my SetPixels() texture changes without having to zoom my orthographic camera? 1 Answer

Baking decals into a texture 3 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