Issue on Mac, with deferred path and Metal in graphics

Hi,

I have an issue with artifacts when i try in Mac PC, in deferred path and Metal in graphics.

I have pinpointed the issue to be in the way i use the water pro shader of Unity

https://forum.unity.com/threads/porting-water-foam-and-edge-blend.260926/

Specifically when i call the below

[LIST=1]
[*]#ifdef WATER_EDGEBLEND_ON
[*]       half depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos));
[*]       depth = LinearEyeDepth(depth);
[*]       edgeBlendFactors = saturate(_InvFadeParemeter * (depth-i.screenPos.w));
[*]       edgeBlendFactors.y = 1.0-edgeBlendFactors.y;
[*]     #endif
[/LIST]

i get artifacts in water, and when i saturate the i.screenPos.w, they go away (but not works as expected after that)

Anyone has any idea how to fix this one ? Thanks in advance

I think might be related to this as well

'"Water artifacts due to transparent textures in deferred lighting fixed, but fog artifacts are a Metal shader language issue with Apple.“”

i found the issue, i had to use ZWrite off in the shader, seems it creates issue if not defined for transparency in Metal

I still have a problem with this though, as i need the ZWrite to not be Off to get the correct result for upper and under sides of water at same time, so i wonder if this is a known bug in Mac and Metal.

Hi, we are facing similar issue with water. When reading data from _CameraDepthTexture and ZWrite On we are getting nasty artifacts.

I have tried various approaches to get copy of DepthBuffer, but with no result. When sampling _CameraDepthTexture directly artifacts are there, from that _CameraDepthTexture should cause the problems.

1 Like

And in comparison to DirectX. There is no event in the frame debugger that copies the depth texture somewhere.

I see that obtaining depth texture could be expensive on TLDR for example on iOS, but would it be possible to get depth texture just for current tile?

metal needs you to create a custom copy of the depth buffer when it comes to deferred – which can then be used by the water to do depth related calculations.
see lux water :slight_smile:

This is probably not so straightforward as it looks. We would like to obtain that texture between some opaque draw calls. But only place where it is possible to copy it is AfterDepthTexture, which is way behind what we need :wink:

this is not supported…

Do you know why it is not supported? Seems a little buggy to me that Grab texture works, so the copy of color buffer is ok, but the copy of depth buffer is not ok? It is almost the same resource produced while rendering. In fact, on the deferred renderer it should be much harder to obtain copy of the color buffer, than the copy of depth buffer i guess.

grab texture works when rendering opaques?

Indeed, seems like big bug that needs to be fixed, if adds extra render step for no reason

Yes, that correct question. I haven’t time to test it, but Before/AfterForwardOpaque should be just fine even on the deferred rendering path? From my point of view, color buffer and depth buffer should be accesible here to make a copy. Am i right?

i tried do the fill of depth buffer in a million ways and none seems to work out correctly, i still get either black artifacts or overlapping polygons or polygon gaps in my water mesh :frowning:

Any luck with this? I’ve faced with the same issue and have not found any solution so far…

After many investigations, you will find that Metal probably passes to _CameraDepthTexture, current depth buffer. From my point of view, due to synchronization it is impossible to read and write to that texture. If you need this functionality on metal best for you will be do a copy beforehand and then pass it to your shader as _CameraDepthTextureCopy for example and don’t access _CameraDepthTexture at all. Or you can use _CameraDepthTexture, but then you will have turn off ZWrite and somehow tackle issues connected to that

You can copy _CameraDepthTexture using Blit into arbitrary texture

Yeh… seems like this is the exact issue.

Here is my workaround in case someone will face the same issue -_CameraDepthTexture workaround for Metal · GitHub