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 Smg065 · Sep 10, 2019 at 03:54 AM · spritestransparency2.5dsorting orderz-buffer

Semi-Transparency, Sprites, and Sorting Groups [Unity 3D]

Hi. I'm working on a 3D game with 2D sprites. I'm having difficulty with finding an appropriate solution to the z-buffer/transparency problem. Currently, I'm using render order to try and fix it, though it is not working how I would hope.

I have 3 elements in play;

  1. The 2 Players [Sprites]

  2. Water [Transparent Model]

  3. Ice [Transparent Model]

I need ice and the players to always be on the same sorting group layer, as the way they're sorted is already correct. However, I need Ice to always render above Water, and any player that's underwater needs to be rendered under the water. My current solution is with Sorting Groups, but it seems to not be working correctly.

     //Update render order
     public void waterRenderUpdate(bool underWater)
     {
         if (underWater)
         {
             transform.GetComponent<SortingGroup>().sortingOrder = -2;
         }
         else
         {
             transform.GetComponent<SortingGroup>().sortingOrder = 0;
         }
     }

When the code above is used, the players do go under the water, but it causes ice to always be rendered ontop of submerged characters. If I change the ice as well by shifting groups, the other player will appear wrong through the ice. If I set the ice to the same layer as the underwater player, this causes the ice to always appear under the water, which should never happen.

alt text

I am not using the Lightweight Render Pipeline, due to a combination of issues it causes. I'm also looking for a non-resource intensive solution. I am not concerned with characters gradually entering a transparent material, popping in/out from them is fine (it's why I tried sorting groups). That being said, a solution that happens to cause that as well is equally valid. I don't need to use sorting layers. Are there any solutions to the z-buffer issue that I can apply here?

waterorder2.png (184.4 kB)
Comment
Add comment · Show 3
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 Namey5 · Sep 10, 2019 at 08:25 AM 0
Share

Your sprite seems to have defined edges - are you willing to sacrifice semi-transparency? It will make the edges aliased, but using an alpha-cutoff shader will write to the depth buffer. Alternatively, you could use dithered transparency, but that has it's own issues.

avatar image Smg065 Namey5 · Sep 10, 2019 at 08:50 AM 0
Share

I can think of a few causes where I would want semi-transparency, though they all have work-arounds the dithered transparency option viable. $$anonymous$$y biggest concern is that shaders area really painful to write. The reason I tried to implement the LRP really early on is to avoid them, though ultimately it just caused more problems. I get the feeling that writing shaders might be unavoidable for the situation however, so maybe something similar that doesn't discard pixels? There's a few solutions here, I'm sure.

As for alpha-cutoff shaders, I'm afraid I'm unfamiliar with the term, and looking it up online doesn't clarify much seeing as alpha cutout shaders keep popping up. Cases where I could find shaders titled 'alpha-cutoff' are this , which seems to refer to using them like the filled tool on the UI, this , which uses angle offsets, 2 sprites ins$$anonymous$$d of a sprite and a 3D transparent surface, and this , which cuts holes in 3D meshes similar to how masks work, though done shader-side.

If you're referring to the shader for Alpha Cutout, those sprites aren't quads. They're Sprite Renderers, and they already can cutout sprites. Would modifying the default sprite shader somehow fix this? If you meant Alpha Cutout on the surface of the water/ice, I tried doing the pixel tiled trick, though it proved very ineffective as the center of the volume would either snap between transparent and filled depending on the cutoff value, or the pixels would be so big that you could clearly see it's a cutoff (even if you stop compression).

Could you please clarify what you meant by alpha-cutoff? Thank you for responding, by the way, it's very much appreciated.

avatar image Namey5 Smg065 · Sep 10, 2019 at 09:53 AM 1
Share

I use cutoff interchangeably with cutout; both mean the same thing - rather than blending across transparency changes, only render pixels that are above a specified opacity. In this case, it looks like your sprite doesn't have semi-transparent sections, hence I was suggesting to use a cutout shader in its place. If the sprite shader already supports cutout, then in theory it should write to the depth buffer and solve this problem. If it doesn't, then yes you would need to modify the sprite shader (which isn't too difficult, although I'm not sure on how sprite materials are implemented). As for dithered transparency, it would be similar to a cutout shader, but using a noise grid (similar to what you mentioned). To fix the problem of visible missing pixels, you would need to sample random values every frame and use something like TAA to blend them together.

1 Reply

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

Answer by Smg065 · Sep 11, 2019 at 02:53 PM

So I took a look at @Namey5 's suggestions, and found that Dithered Textures for the water was the solution I wanted. Moreover, I like how it looks so much that I'm alright with the missing pixels, because unlike the attempt I made before, it seems to have a slider for pixel size, and keep it as a multiple of 2 (0.5, 0.25, 0.75, 0.125, etc), it's unnoticeable enough to work for my game. This is the dithered shader I used, credit to Alexander Ocias.

 Shader "Ocias/Diffuse (Stipple Transparency)" {
 Properties {
     _MainTex ("Base (RGB)", 2D) = "white" {}
     _Transparency ("Transparency", Range(0,1)) = 1.0
 }
 SubShader {
     Tags { "RenderType"="Opaque" }
     LOD 150
 CGPROGRAM
 #pragma surface surf Lambert noforwardadd
 sampler2D _MainTex;
 struct Input {
     float2 uv_MainTex;
     float4 screenPos;
 };
 half _Transparency;
 void surf (Input IN, inout SurfaceOutput o) {
     fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
     o.Albedo = c.rgb;
     o.Alpha = c.a;
     // Screen-door transparency: Discard pixel if below threshold.
     float4x4 thresholdMatrix =
     {  1.0 / 17.0,  9.0 / 17.0,  3.0 / 17.0, 11.0 / 17.0,
       13.0 / 17.0,  5.0 / 17.0, 15.0 / 17.0,  7.0 / 17.0,
        4.0 / 17.0, 12.0 / 17.0,  2.0 / 17.0, 10.0 / 17.0,
       16.0 / 17.0,  8.0 / 17.0, 14.0 / 17.0,  6.0 / 17.0
     };
     float4x4 _RowAccess = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
     float2 pos = IN.screenPos.xy / IN.screenPos.w;
     pos *= _ScreenParams.xy; // pixel position
     clip(_Transparency - thresholdMatrix[fmod(pos.x, 4)] * _RowAccess[fmod(pos.y, 4)]);
 }
 ENDCG
 }
 Fallback "Mobile/VertexLit"
 }

I know that this doesn't act as a satisfying answer for people who might be interested in other solutions, so here's some more that I know of, but didn't work on my project.

  1. You can use a non-sprite cutout shader in Unity's defaults if you aren't worried about shadows being cast on the sprite (I am).

  2. You can attach a dithered texture to the player rather than the water, and keep it at 1. This, as stated above, writes the sprite to the depth buffer, at the cost of not being able to have transparency in your sprites. I personally put it in the water, so I could have the freedom of semi-transparent sprites.

  3. If you need to write to depth, you're using transparent/unlit sprites, and you can't use dithering on the material, consider looking at this thread. It seems the post works really well for old versions of unity, and a post in the comments has one that works for Unity 2017.

Thank you for your help, and I hope one of the solutions above helped out others with similar problems.

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

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

115 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 avatar image avatar image avatar image

Related Questions

Transparency Sort Axis on Y with Pivot instead of Center of object? 1 Answer

How to sort draw order on transparent character puppet. 0 Answers

Is it possible to z-order triangles with transparency? 1 Answer

What do you put in the Project Settings>Graphics>Transparency Sort Axis, and what does those values mean (e.g. the difference between x = 1 and x = 69) ? 0 Answers

What can I do to solve problems of z-fighting with sprites in a 3d world 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