Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

DepthNormals Texture - get normals relative to camera viewing direction

Discussion in 'Shaders' started by tomekkie2, Jul 26, 2017.

  1. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    949
    norm_depth2.jpg norm_depth1.jpg

    How to get the normals here relative to viewing direction?
    i.e. so the colours when moving the sphere in camera wouldn't change?

    I was trying to change COMPUTE_VIEW_NORMAL for something different in the function here, but no success yet:
    Code (CSharp):
    1. v2f vert( appdata_base v ) {
    2.     v2f o;
    3.     UNITY_SETUP_INSTANCE_ID(v);
    4.     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    5.     o.pos = UnityObjectToClipPos(v.vertex);
    6.     o.nz.xyz = COMPUTE_VIEW_NORMAL;
    7.     o.nz.w = COMPUTE_DEPTH_01;
    8.     return o;
    9. }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    COMPUTE_VIEW_NORMAL is for transforming vertex normals from object space to view space, and the normals stored in the camera depth normals texture are already in view space. The normals "changing" as it pans across the screen is the correct behavior for a perspective camera as you're seeing different parts of the sphere as it pans across.

    What you seem to want is normals relative to the pixel's view direction, accounting for perspective.

    I wrote a little something for that here for applying that to a matcap shader, but you'd have to figure out how to apply this to the depth normals texture yourself (you have to calculate the view space position of each pixel from the depth).
    https://forum.unity3d.com/threads/getting-normals-relative-to-camera-view.452631/#post-2933684
     
    StaggartCreations and tomekkie2 like this.
  3. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    949
    I am basically going to remake the edge shader to outline backfaces.
    So trying to project normals on the viewing direction, using the below code:
    Code (CSharp):
    1.        [ATTACH=full]240573[/ATTACH] float fov = 3.14/3;   //assumed here fov = 60 deg;
    2.         float3 vDir = normalize(float3(-tan(fov/2)*
    3. (i.pos.x/_MainTex_TexelSize.w-0.5*_MainTex_TexelSize.z/_MainTex_TexelSize.w),
    4. -tan(fov/2)*(i.pos.y/_MainTex_TexelSize.w-0.5),1)); //viewDir
    5.         float3 proj = normalize(dot(Normal0,vDir)*vDir); //normal projected on vievDir
    6.         half4 newcolor = tex2D(_CameraDepthNormalsTexture, i.uv[0].xy);
    7. //normals - lower half of the screen
    8.         if ((i.pos.y/_MainTex_TexelSize.w-0.5)>0) newcolor.xy = EncodeViewNormalStereo(proj);
    9. //normals projected on viewing dir - upper half of the screen
    10.         return newcolor;
    11.  
    I have achieved this:
    norm_depth3.jpg

    The artifacts on the sphere edges show there must some error in the calculated viewing direction.

    But I have found another, much simpler way to edge around backfaces, that is to just to use VFACE and encode two "normal" colors into Internal-DepthNormals shader and use the standard Legacy edge effect.
     
    Last edited: Jul 27, 2017
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    If you're just trying to detect backfaces it is literally impossible to do accurately as part of the image effect. The only way to do it by modifying the Internal-DepthNormals using VFACE. And you're not encoding two normals at that point, you're still just encoding one, you're just encoding the correct normal for unculled, two sided shaders.
     
    tomekkie2 likes this.
  5. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    949
    Yes. thanks.
    That works great, but I got disappointed, because I was hoping to get it to work in conjunction with clipping shaders on object.
    But unfortunately, the depthNormal texture gets rendered before the objects get clipped.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    Clipped how? Via a custom shader? You need to add a custom tagged pass to the Internal-DepthNormals shader and set your clipped shader to use the same tag.
     
    tomekkie2 likes this.
  7. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    949
    Thanks again.
    That worked well. But I still must be missing something: My changes made to the Internal-DepthNormals shader do not bring any effect in the deferred lighting mode.
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    Because deferred doesn't use that replacement shader, it just uses the gbuffers. If you use an opaque shader without a deferred pass, they won't work properly with any post process that relies on normals as they do not render their normals into the gbuffers. Unity renders forward opaque objects into the gbuffers using the shadowcaster pass, which just renders black into the albedo gbuffer and depth buffer. I suspect that's what's happening here.
     
    tomekkie2 likes this.
  9. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    949
    I am using just surface and standard shaders.
    In deferred all the effects work but my Internal-DepthNormals modification has gone away.

    I have just found a way to fix it in Standard would stay here :
    Code (CSharp):
    1.     data.normalWorld = s.normalWorld;
    2.     UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2);
    Just don't know about surface shader - maybe not possible.
     
  10. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    If the surface shader is already handling backface normal flipping, is using the standard lighting model, and is not disabling the deferred pass generation, then you shouldn't have to do anything.
     
    tomekkie2 likes this.
  11. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    949
    Thanks a lot.
    That is the effect I have wanted to get and I did with your help. outline_post_effect.jpg