Search Unity

Gradual appearance of objects

Discussion in 'General Graphics' started by StarTwinkle, Jul 18, 2017.

  1. StarTwinkle

    StarTwinkle

    Joined:
    Jul 13, 2015
    Posts:
    13
    Hi,
    In my 3d game it is necessary that the objects (stones, trees) smoothly appear as the player moves through the territory.
    I tried to do this through gradual changing the transparency of the material, but this option is not very good. The main problem is that to regulate the transparency of each object - I need to make a copy of the material, turn on Fade mode and smoothly change the alpha channel. It works, but the performance drops significantly. It seems to me that reason is that I make a lot of copies of the material. In addition, switching to Fade does not always work for a mysterious reason.
    How to solve this problem? Can there be other ways?

    Thanks.
     
  2. StarTwinkle

    StarTwinkle

    Joined:
    Jul 13, 2015
    Posts:
    13
    I have fully procedurally generated world (open and endless). So I can not to draw all objects - even with low LOD.
    Before I used Fog to hide far landscape. However objects (trees, stones, etc) have lesser radius of visibility than terrain. Therefore Fog does not help me to hide them.
    It is logical to use the alpha channel for the gradual appearance of objects. But it's expensive because you have to create a separate material for each object.
     
    Last edited: Jul 18, 2017
  3. BakeMyCake

    BakeMyCake

    Joined:
    May 8, 2017
    Posts:
    175
    How about Camera.layerCullDistances?
    https://docs.unity3d.com/ScriptReference/Camera-layerCullDistances.html
    It lets you set the far clip plane of your camera on per-layer basis, so you can put your detail objects on a separate layer with a shorter far distance.

    If this is not what you want, you might have to write a primitive shader that manages alpha based on distance from the camera. That way you will reduce the material instances to just one for all detail objects.
     
    StarTwinkle likes this.
  4. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    AAA games don't even fade LOD, they use a dithering texture in screen space, alpga hit the fillrates.
     
    Lin-Dong and theANMATOR2b like this.
  5. BakeMyCake

    BakeMyCake

    Joined:
    May 8, 2017
    Posts:
    175
    Could you elaborate what you mean by dithering texture in screen space? I seem to have trouble finding related material by simply googling it.
     
  6. StarTwinkle

    StarTwinkle

    Joined:
    Jul 13, 2015
    Posts:
    13
    Well, as an option it will do. Thanks.
    However it will look worse in compare with transparency, of course.
    Yes I can. But this is not exactly the same. Because once I created an object - I want it to gradually appear, even if the player stopped. In the case of calculating the distance in the shader, the object still transparent if player have stopped.
     
  7. DominoM

    DominoM

    Joined:
    Nov 24, 2016
    Posts:
    460
    BakeMyCake likes this.
  8. StarTwinkle

    StarTwinkle

    Joined:
    Jul 13, 2015
    Posts:
    13
    I've tried this way. Unfortunately it is not fit for me.
    Array layerCullDistances is not same that CliipingFar.
    Array layerCullDistances just cut whole object if it is out of clipping. There is described more detailed:
    http://answers.unity3d.com/questions/712088/cameralayerculldistances-help.html

    I read this article. But it is very difficult for me :)
     
    Last edited: Jul 18, 2017
  9. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    StarTwinkle and BakeMyCake like this.
  10. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Keijiro posted an example of how to use dithered cross fading here:
    https://github.com/keijiro/CrossFadingLod

    It's also built into the Standard shader in 2017.1 so you don't need a custom shader to use it anymore. Previously was only built into the speed tree shader.

    edit: I'm wrong, they built it in as an option for surface shaders, not the standard shader, so you'll still need a custom shader to use it, but it's a potentially little easier to use than what's in Keijiro's example.

     
    StarTwinkle, BakeMyCake and DominoM like this.
  11. StarTwinkle

    StarTwinkle

    Joined:
    Jul 13, 2015
    Posts:
    13
    Ok, guys.
    I made surface shader, based on dithered cross fading.
    There is two variants - shader with adjustable fading factor (I use it for specific objects that have own non standard shader), and a shader that determines the fading factor by the distance to the camera (for most count of objects).

    Second variant looks by following way:
    Code (CSharp):
    1. Shader "Transparent/FadingDistance"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Main Color", Color) = (1,1,1,1)
    6.         _MainTex("Base (RGB)", 2D) = "white" {}
    7.         _Cutoff("Alpha cutoff", Range(0,1)) = 1
    8.         _NearDistance("NearDistance", Float) = 20
    9.         _FarDistance("FarDistance", Float) = 30
    10.         _CutTex("Cutout (A)", 2D) = "white" {}
    11.         _ScreenWidth("Screen Width", Float) = 500
    12.         _ScreenHeight("Screen Height", Float) = 500
    13.     }
    14.  
    15.     SubShader
    16.     {
    17.         Tags{ "Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout" }
    18.         LOD 200
    19.         Cull Off
    20.  
    21.         CGPROGRAM
    22.  
    23.         #pragma surface surf Lambert alphatest:_Cutoff
    24.  
    25.         sampler2D _MainTex : TEXCOORD0;
    26.         sampler2D _CutTex: TEXCOORD1;
    27.         fixed4 _Color;
    28.         float _ScreenWidth;
    29.         float _ScreenHeight;
    30.         float _FarDistance;
    31.         float _NearDistance;
    32.  
    33.         struct Input
    34.         {
    35.             float2 uv_MainTex;
    36.             float2 screenPos;
    37.             half3 worldNormal;
    38.             float3 viewDir;
    39.             float3 worldPos;
    40.         };
    41.  
    42.         void surf(Input IN, inout SurfaceOutput o)
    43.         {
    44.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    45.  
    46.             float2 pos = IN.screenPos;
    47.             half u = pos.x * _ScreenWidth / 1024;//size of cutoff texture
    48.             half v = pos.y * _ScreenHeight / 1024;//size of cutoff texture
    49.             float ca = tex2D(_CutTex, float2(u, v)).a;
    50.  
    51.             //dist
    52.             float2 v1 = IN.worldPos.xz;
    53.             float2 v2 = _WorldSpaceCameraPos.xz;
    54.             float dist = distance(v1, v2);
    55.  
    56.             if (dist < _NearDistance)
    57.                 ca = 1;
    58.             else
    59.             {
    60.                 if (dist > _FarDistance)
    61.                     ca = 0;
    62.                 else
    63.                     ca = ca + (_FarDistance - dist) / (_FarDistance - _NearDistance);
    64.             }
    65.  
    66.             //back side must be transparent always
    67.             float n = dot(IN.viewDir, IN.worldNormal);
    68.  
    69.             if (n < 0)
    70.                 ca = 0;
    71.             //
    72.             o.Albedo.rgb = c.rgb;
    73.             o.Alpha = ca;
    74.         }
    75.  
    76.         ENDCG
    77.     }
    78.  
    79.     Fallback "Transparent/Cutout/VertexLit"
    80. }
    For fading (parameter _CutTex of shader) I use texture with randomly alpha transparent pixels from 0 to 255.

    The result:
     
    roundyyy and BFlorry like this.
  12. Paul-Swanson

    Paul-Swanson

    Joined:
    Jan 22, 2014
    Posts:
    319
    @Storm23 I'm pretty new to understanding how shaders work. I want to us the Standard shader but that Dither affect that you used is perfect. However it looks in that video that it would only work on base colors rather that texture maps.
    So in short I need all the features from the Normal Standard Shader plus that affect. I cannot for the life of me figure out how to add it. It compiles but never transitions.

    Do you know of a way to make that system work in the PBR Standard Shader?
     
  13. Paul-Swanson

    Paul-Swanson

    Joined:
    Jan 22, 2014
    Posts:
    319
    I figured it out. I just needed to manually add all the maps to it. So I'v got what I want to. All the cross fade dithering plus the PBR function from the Standard Vertex\Frag shader