Search Unity

DX11 tessellation, custom lighting problem

Discussion in 'Shaders' started by Emptiness, Apr 28, 2013.

  1. Emptiness

    Emptiness

    Joined:
    Jul 14, 2012
    Posts:
    33
    Hi!

    Has anyone encountered with this problem?

    1. Switch deferred rendering in player settings and use DX11.
    2. Make two sphere (left, right on the picture).
    3. Apply the built-in "Tessellation/Bumped Specular (smooth)" shader on the left sphere.
    4. Apply the exact same shader like the "Tessellation/Bumped Specular (smooth)" shader to the right sphere, but write in the shader this parameter: "exclude_path:prepass".
    5. The problem is self explanatory. (tweak the smoothness settings to make the artifacts visible)

    If I use this second shader on characters the artifacts always visible, no matter how I tweak the settings.
    I would be really happy if anyone could help me. :)

    Thx.

    $DX11CustomLighting.jpg
     
  2. cician

    cician

    Joined:
    Dec 10, 2012
    Posts:
    233
    Yes, unfortunately. Lost much time trying to find a workaround, to no avail.

    It's not tessellation specific, actually.
    When deferred lighting is enabled unity seems to do an additional pass (shadow receiver? early-z?) that affects even objects that have forward only lighting model.
    This pass is not affected by vertex displacement and pops-out resulting in visual artifacts.
    Tried also bisecting the compiled surface shader to pinpoint the issue: the pass in question is NOT present.

    What also seems to me the same issue happens with transparent (including cutout) forward-only shaders with deferred enabled.

    https://fogbugz.unity3d.com/default.asp?529908_km84u6oc3mc23se5

    http://answers.unity3d.com/questions/149283/vertex-displacement-in-forward-rendering-shader.html

    Edit: unlike what i wrote in the bug report it does happen in Unity 3 IIRC.
     
    Last edited: Apr 28, 2013
  3. Emptiness

    Emptiness

    Joined:
    Jul 14, 2012
    Posts:
    33
    I've found two temporary workaround! :)

    1. Use at the tags the following: "Queue" = "Transparent-1" LINK
    Be careful it might cause rendering issues. (e.g. something rendering in front/behind your model)

    2. Use "Offset -1,-1" in the shader. LINK
    It gives quite acceptable result from distance, maybe good for somebody.

    I know these are not perfect solutions but better than nothing. :wink:
     
  4. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    The issue is likely from the shadow pass not being set up to do the same tesselation as your regular shader.

    You'll have to add custom shadow collector/receiver passes that perform the same tesselation as your regular shader.
     
  5. cician

    cician

    Joined:
    Dec 10, 2012
    Posts:
    233
    Unfortunately it doesn't solve the issue, since the offending pass is NOT part of the shader itself, but something unity does when deferred lighting is active.

    You can try it yourself with this shader. As you can see there's only one pass and it should display the object in in red and translated by 0.1 in x axis.
    With deferred lighting enabled the object itself renders as expected, including the shadows if you decomment the caster/receiver block, but there's a second object beside it showing skybox color.

    Code (csharp):
    1. Shader "Custom/Displacement" {
    2.     Properties {
    3.         _Color ("Color", color) = (1,1,1,0)
    4.     }
    5.     SubShader {
    6.         Tags { "RenderType"="Opaque" }
    7.         LOD 300
    8.  
    9.         Pass {
    10.             Name "Red"
    11.             Tags { "LightMode" = "Always" }
    12.            
    13.             Fog {Mode Off}
    14.             ZWrite On ZTest LEqual Cull Off
    15.    
    16.             CGPROGRAM
    17.                 #pragma vertex vert
    18.                 #pragma fragment frag
    19.                 #pragma fragmentoption ARB_precision_hint_fastest
    20.                 #pragma multi_compile_particles
    21.    
    22.                 #include "UnityCG.cginc"
    23.                
    24.                 struct appdata {
    25.                     float4 vertex : POSITION;
    26.                 };
    27.    
    28.                 struct v2f {
    29.                     float4 vertex : POSITION;
    30.                 };
    31.    
    32.                 v2f vert(appdata v) {
    33.                     v.vertex.x += 0.1;
    34.                    
    35.                     v2f o;
    36.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    37.                     return o;
    38.                 }
    39.                
    40.                 fixed4 frag (v2f i) : COLOR {
    41.                     return fixed4(1, 0, 0, 1);
    42.                 }
    43.             ENDCG
    44.         }
    45.        
    46. /*
    47.         // Pass to render object as a shadow caster
    48.         Pass {
    49.             Name "ShadowCaster"
    50.             Tags { "LightMode" = "ShadowCaster" }
    51.            
    52.             Fog {Mode Off}
    53.             ZWrite On ZTest LEqual Cull Off
    54.             Offset 1, 1
    55.    
    56.             CGPROGRAM
    57.                 #pragma vertex vert
    58.                 #pragma fragment frag
    59.                 #pragma multi_compile_shadowcaster
    60.                 #pragma fragmentoption ARB_precision_hint_fastest
    61.                 #pragma exclude_renderers d3d11_9x
    62.                 #include "UnityCG.cginc"
    63.                
    64.                 struct v2f {
    65.                     V2F_SHADOW_CASTER;
    66.                 };
    67.                
    68.                 v2f vert( appdata_full v ) {
    69.                     v.vertex.x += 0.1;
    70.                                
    71.                     v2f o;
    72.                     TRANSFER_SHADOW_CASTER(o)
    73.                     return o;
    74.                 }
    75.                
    76.                 float4 frag( v2f i ) : COLOR {
    77.                     SHADOW_CASTER_FRAGMENT(i)
    78.                 }
    79.             ENDCG
    80.         }
    81.        
    82.         // Pass to render object as a shadow collector
    83.         Pass {
    84.             Name "ShadowCollector"
    85.             Tags { "LightMode" = "ShadowCollector" }
    86.            
    87.             Fog {Mode Off}
    88.             ZWrite On ZTest LEqual
    89.    
    90.             CGPROGRAM
    91.                 #pragma vertex vert
    92.                 #pragma fragment frag
    93.                 #pragma fragmentoption ARB_precision_hint_fastest
    94.                 #pragma exclude_renderers d3d11_9x
    95.                 #pragma multi_compile_shadowcollector
    96.                
    97.                 #define SHADOW_COLLECTOR_PASS
    98.                 #include "UnityCG.cginc"
    99.                
    100.                 struct appdata {
    101.                     float4 vertex : POSITION;
    102.                 };
    103.                
    104.                 struct v2f {
    105.                     V2F_SHADOW_COLLECTOR;
    106.                 };
    107.                
    108.                 v2f vert (appdata_full v) {
    109.                     v.vertex.x += 0.1;
    110.                                
    111.                     v2f o;
    112.                     TRANSFER_SHADOW_COLLECTOR(o)
    113.                     return o;
    114.                 }
    115.                
    116.                 fixed4 frag (v2f i) : COLOR {
    117.                     SHADOW_COLLECTOR_FRAGMENT(i)
    118.                 }
    119.             ENDCG
    120.         }
    121. */
    122.        
    123.     }
    124.     FallBack Off
    125. }
    $forward_disp_bug3.png

    Since Unity kinda states in documentation that forward and deferred can be mixed I consider this simpy a bug.
     
  6. cician

    cician

    Joined:
    Dec 10, 2012
    Posts:
    233
    Just found a workaround inspired by Emptiness' response, though I'm still testing.
    Just render in Geometry+1!

    Code (csharp):
    1. Tags { "RenderType"="Geometry+1" }
    :-D

    Edit: forget what I said above. As you can see I mistook the tag. Though it works in transparent queue or with custom RenderType value as in the code above ("Geometry+1" is not a standard render type), but it has other consequences making the workaround pretty useless. :(
     
    Last edited: May 1, 2013
  7. Emptiness

    Emptiness

    Joined:
    Jul 14, 2012
    Posts:
    33
    I'm still waiting for a final solution. :)
    Does anyone has a good idea?

    thx
     
  8. cherub

    cherub

    Joined:
    Apr 26, 2006
    Posts:
    493
    Last edited: Jun 27, 2013
  9. cician

    cician

    Joined:
    Dec 10, 2012
    Posts:
    233
    From another thread for more info:

    Also, even if I disable shadows globally in quality setting the issue is still threre.
     
  10. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    the above code is not a DirectX 11 shader , so how can it have tessellation?

    it says #pragma exclude_renderers d3d11_9x
     
  11. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    There are multiple target platforms in Unity for DirectX 11. d3d11_9x is used for Windows RT, and d3d11 is used for the desktop version of Windows. The distinction is made because Windows RT is used for ARM processors, in stead of x86 processors.

    So when you exclude the d3d11_9x platform, it can still be compiled for 'regular' DX11.
     
  12. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202
    we're in 4.5 now this problem is still there... it's mind blowing how everything in unity is broken when you try to push it a bit...
     
  13. cherub

    cherub

    Joined:
    Apr 26, 2006
    Posts:
    493
    there does seem to be a loss of focus as of late. still love unity though.
     
  14. Jonny-Roy

    Jonny-Roy

    Joined:
    May 29, 2013
    Posts:
    666
    The fix is to remove this:

    FallBack "Diffuse"

    If you need the fallbacks for the ShadowCasters, just add them yourself.
     
  15. cician

    cician

    Joined:
    Dec 10, 2012
    Posts:
    233
    Sorry, but it's not enough. To quote myself:

    Btw. for those who didn't know yet, it's fixed in Unity 5.
     
  16. Jonny-Roy

    Jonny-Roy

    Joined:
    May 29, 2013
    Posts:
    666
    Ah, I was using Unity 5, so that's probably why!