Unity3d Shader Z testing question, ZTest Greater but keep behind - unity3d

I'm rather new with shaders in Unity and I'm trying to create something but all my attempts failed.
The scenario is this, I have the following objects: A,B,C.
A is a sprite, B is a Textmesh (not GUI) and C is a depth mask rectangle.
I wanted to take the text and scroll it over the "A" sprite, but since just scrolling the text over the sprite will result in the text going out of the sprite bounds, I wanted to create a depth mask that only while rendered on that mask the text will appear, and place that mask on the sprite.
That worked just fine, I put the sprite (A) then the text (B) and I added ZTest Greater to it's shader, and then (C) the depth mask, which is basically a rect with the following shader:
Tags { "Queue" = "Transparent" }
Lighting Off
ZTest LEqual
ZWrite On
ColorMask 0
Pass {}
This makes it so the text only appears on the rect of the mask and once its scrolled out, it vanishes, which is great.
Now for my problem, I have another object, which can appear on top of everything, and should make everything vanish as well (so I used a depth mask like stated above), but since I've already defined the text to be ZTest Greater, when that object goes over, everything disappears correctly except for the text.
My question is as follows, is there a way to differentiate between the two masks, so that the text will appear on one (passing the Ztest), but disappear from the other(failing the Ztest?).
Attaching a screenshot depicting my problem, as you can see, the red masks are showing only part of the text (which is good) but the blue mask which needs to be the end of the screen is not working on the text because the text is ZTest greater which is needed for the red mask.
So what I actually need is a way for the blue mask to cover the text but the red mask reveal it.
Any ideas if you can assign specific objects so that they will act differently with each other object, with regards to the shaders' tests? (or a similar solution)

Related

Unity TilemapRenderer draw mode sliced

Unity SpriteRender has a useful drawMode parameter to define how the Sprite scales when its dimensions change, with the option to slice sprite if correctly set in Sprite Editor.
Unlikely TilemapRenderer does not have this drawMode option, therefore it is impossibile to correctly slice a Sprite of a Tile.
The image below is an example of what I would achieve, the first image is the sprite itself, the second one is the tile (NOT sliced) the third one is a UI Image, where the sprite is correctly sliced (this is what I want to achieve).
Is there any way to have that result with TilemapRenderer?

How to mask a UI.RawImage in Unity?

In Unity UI, I have an ordinary RawImage
(It's just sitting on a Panel)
I have a png, mask.png which is just a white shape on transparent.
How do you mask the RawImage ?
I have tried Mask, SpriteMask in many ways and it just won't work.
Even RectMask2D would be fine (to mask to a square shape) but it just doesn't seem to work?
Should I use Mask or SpriteMask
If so, do you perhaps have to / have to not set a Material, on the mask? On the RawImage?
I assume the Mask game object should be the parent of the RawImage, but??
What is the secret ?
The RawImagecomponent should work with masks just like your normal Image component does. Granted that the checkmark Maskable is ticked.
Note that the Mask or rect Mask 2D should be the parent of the (raw)images you are trying to mask. The hierarchy should be something like this:
Canvas<br>
| MaskObject (Contains (Raw)Image and Mask or Rect Mask 2d components)
| Object to mask (Contains the (raw)image to mask)
Notice how the white square (Image) gets cut off by the red square (Mask).
The component types between the masking image and the masked image do not need to match either. A RawImage can mask an Image and vice versa.
The Masking objects are again shown in red, where the white are the masked objects. The GameObject's names show the used (raw)image component for that gameobject.
The only exception is the SpriteMask which exclusively works with the Sprite Renderer component
There is not much explanation from Unity on masks... This being the closest to an explanation there is
Some more info about masks:
Masks work by comparing the ref(erence) values of the stencil buffers of the two (or more) objects (in this case images) and only drawing the pixels where the stencil buffer for both equals to 1 using the Stencil's Comp(arison) function. Meaning it is possible to create your own implementation of masks by creating a shader and implementing the Stencil buffer, this comes in handy when for example you want something like an inversed mask, where pixels are drawn everywhere except where the mask is (creating holes in an image) :)
just put the raw image as a child of a UI image and call the parent image "Mask" then put in any shape of sprite in the "Mask" image. Go to 'add component' then 'UI' then add 'mask'. Please look at this link https://learn.unity.com/tutorial/ui-masking#6032b6fdedbc2a06c234cd3e it work well for me

HLSL lighting based on texture pixels instead of screen

In HLSL, how can I calculate lighting based on pixels of a texture, instead of pixels that make up the object?
In other words, if I have a 64x64px texture being rendered on a 1024x768px screen, I want to calculate the lighting as it affects the 64x64px space, resulting in jagged pixels instead of a smooth line.
I've researched dozens of answers but I'm not sure how I can determine at all times if a fragment is a part of a pixel that should be fully lit or not. Maybe this is the wrong approach?
The current implementation uses a diffuse texture and a normal map. It results in what appear as artifacts (diagonal lines) in the output:
Note: The reason it almost looks correct is because of the normal map, which causes some adjacent pixels to have normals that are angled just enough to light some pixels and not others.

Unity - Avoid quad clipping or set rendering order

I am using Unity 5 to develop a game. I'm still learning, so this may be a dumb question. I have read about Depth Buffer and Depth Texture, but I cannot seem to understand if that applies here or not.
My setting is simple: I create a grid using several quads (40x40) which I use to snap buildings. Those buildings also have a base, made with quads. Every time I put one one the map, the Quads overlap and they look like the picture.
As you can see, the red quad is "merging" with the floor (white quads).
How can I make sure Unity renders the red one first, and the white ones are background? Of course, I can change the red quad Y position, but that seems like the wrong way of solving this.
This is a common issue, called Z-Fighting.
Usually you can reduce it by reducing the range of “Clipping Planes” of the camera, but in your case the quads are at the same Y position, so you can’t avoid it without changing the Y position.
I don't know if it is an option for you, but if you use SpriteRenderer (Unity 2D) you don’t have that problem and you can just set “Sorting Layer” or “Order in Layer” if you want modify the rendering order.

Transparent shader allows the objects below to show on top

In my scene, the smileys(Quad with png image) are placed at Y:0 and the dots(Quad with tiling 3X3) are placed at Y: -0.25.
The shader I need to use for the smileys is Transparent-Diffuse as I am using a circle png image.
But the dots I use below are showing up above the smiley. Using any other shader like Diffuse solves the issue but the smiley becomes a square.
Screenshot:
If you need any more clarifications please dont hesitate to ask.
Edit:
I have attached the shader details of both the smiley and the dots from the inspector panel.
link: http://postimg.org/image/cvws1os7d/
Edit 2:
I have found that the issue should be with the MainCamera and especially with distance & "Field Of View".
I need to use "Perspective" as projection type and 140 as Field of View.
If I change the projection type to Orthographic the issue is completely fixed.
The below screenshots show how the distance and Field of View controls the appearance of the dots over the smiley.
Screenshot 1:
Y position: 8.48
Field of View: 30
link: http://postimg.org/image/s31tttrkp/
Screenshot 2:
Y position: 9.7
Field of View: 30
link: http://postimg.org/image/f71sq0y4b/
Screenshot 3:
Y position: 11.41
Field of View: 30
link: http://postimg.org/image/3uk4az3d3/
Screenshot 4:
Y position: 1
Field of View: 140
link: http://postimg.org/image/bul9zwg7z/
Can this be a clue?
Just a couple of info, on how transparency is typically implemented (not only by Unity).
Meanwhile opaque objects can be drawn in any order (even if sorting them in front-to-back order can eventually improve some GPU performances relying on an early z-cull). Which pixels are visible can be deduced using the depth value stored into the z-buffer.
You can't rely on z-buffer for transparency.
For rendering translucent objects a typical approach is to draw them after all opaque objects, and sorting them in back-to-front order (transparent objects more distant from the camera are drawn first).
Now the question is: how do you sort objects? with a perspective camera and meshes of a generic shape, the solution is not obvious.
For quad meshes oriented parallel to a ortographic camera view plane, the z order is implicitly correct (that's why it always works for you).
You can also notice that camera position influences the drawing order, because with perspective camera the order is calculated as distance between object position and camera.
So what can you do with Unity3d, in your specific use case scenario?
A couple of tricks:
Explicitly set the render queue of the material
Explicitly set the render order inside the shader (similar of the above, but equals to every object with the same shader)
Fake the depth using Offset into the shader (not that useful in your case but worth to be known)
hope this helps
EDIT
I didn't know that, the camera transparency sorting mode appears to be customizable. So this is another solution, maybe the best for your case if you want to use a perspective camera.
If you are using Sprite Renderer component to render the images, you have to change the rendering order with Sorting Layer and Order in Layer parameters instead of changing the Y position.
Sorting layers can be added by clicking the "default" and choosing "Add Sorting Layer..". The order of the layers is changed by dragging them into different order. With Order in Layer lower numbers are rendered first. This means that higher numbers will be drawn on top of lower ones.