Search Unity

Fix billboard shader lighting

Discussion in 'Shaders' started by pointcache, Aug 14, 2017.

  1. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    579
    Hi guys i made a simple script to generate BillboardAssets from anything

    Now the problem is that its too dark when facing away from light source.


    This can be fixed if i crank up ambient lighting

    So when ambient is at max it looks just like it should at normal
    I am using a slightly cut down version of SpeedTreeBillboard shader
    from which i removed crap like wind and hue,
    now my idea is to force it to have max ambient value,
    but i am unable to find the way to do so.

    If i simply insert o.Emission = .. it says its a wrong subscript, but the doc says use Emission,
    so im out of ideas on how to achieve this.

    Code (CSharp):
    1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
    2.  
    3. Shader "BillboardMaker/Billboard"
    4. {
    5.     Properties
    6.     {
    7.         _Color ("Main Color", Color) = (1,1,1,1)
    8.         _MainTex ("Base (RGB)", 2D) = "white" {}
    9.         _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    10.         [MaterialEnum(None,0,Fastest,1)] _WindQuality ("Wind Quality", Range(0,1)) = 0
    11.     }
    12.  
    13.     // targeting SM3.0+
    14.     SubShader
    15.     {
    16.         Tags
    17.         {
    18.             "Queue"="AlphaTest"
    19.             "IgnoreProjector"="True"
    20.             "RenderType"="TransparentCutout"
    21.             "DisableBatching"="LODFading"
    22.         }
    23.         LOD 400
    24.  
    25.         CGPROGRAM
    26.             #pragma surface surf Lambert vertex:SpeedTreeBillboardVert nolightmap addshadow dithercrossfade
    27.             #pragma target 3.0
    28.             #pragma multi_compile __ BILLBOARD_FACE_CAMERA_POS
    29.             #include "SpeedTreeBillboardCommon.cginc"
    30.  
    31.             void surf(Input IN, inout SurfaceOutput OUT)
    32.             {
    33.                 SpeedTreeFragOut o;
    34.                 SpeedTreeFrag(IN, o);
    35.                 SPEEDTREE_COPY_FRAG(OUT, o)
    36.             }
    37.         ENDCG
    38.  
    39.         Pass
    40.         {
    41.             Tags { "LightMode" = "Deferred" }
    42.  
    43.             CGPROGRAM
    44.                 #pragma vertex vert
    45.                 #pragma fragment frag
    46.                 #pragma target 3.0
    47.                 #pragma multi_compile_fog
    48.                 #pragma multi_compile __ LOD_FADE_CROSSFADE
    49.                 #pragma multi_compile __ BILLBOARD_FACE_CAMERA_POS
    50.                 #include "SpeedTreeBillboardCommon.cginc"
    51.  
    52.                 struct v2f
    53.                 {
    54.                     UNITY_POSITION(vertex);
    55.                     UNITY_FOG_COORDS(0)
    56.                     Input data      : TEXCOORD1;
    57.                     UNITY_VERTEX_OUTPUT_STEREO
    58.                 };
    59.  
    60.                 v2f vert(SpeedTreeBillboardData v)
    61.                 {
    62.                     v2f o;
    63.                     UNITY_SETUP_INSTANCE_ID(v);
    64.                     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    65.                     SpeedTreeBillboardVert(v, o.data);
    66.                     o.data.color.rgb *= ShadeVertexLightsFull(v.vertex, v.normal, 4, true);
    67.                     //o.data.color.rgb *= unity_AmbientSky;
    68.                     o.vertex = UnityObjectToClipPos(v.vertex);
    69.                     UNITY_TRANSFER_FOG(o,o.vertex);
    70.                     return o;
    71.                 }
    72.  
    73.                 fixed4 frag(v2f i) : SV_Target
    74.                 {
    75.                     SpeedTreeFragOut o;
    76.                     SpeedTreeFrag(i.data, o);
    77.                     UNITY_APPLY_DITHER_CROSSFADE(i.vertex.xy);
    78.                     fixed4 c = fixed4(o.Albedo, o.Alpha);
    79.                    
    80.                     UNITY_APPLY_FOG(i.fogCoord, c);
    81.                     return c;
    82.                 }
    83.             ENDCG
    84.         }
    85.     }
    86.  
    87.    
    88.     FallBack "Transparent/Cutout/VertexLit"
    89. }
    90.  
     
  2. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    579
    Upclose


    "quality" speed tree billboards

     
  3. Pode

    Pode

    Joined:
    Nov 13, 2013
    Posts:
    145
    I suppose you are use planes or quads to show your billboard texture.
    How are the normals of the quad ? Are they perpendicular to the plane of the quad, or pointing up ?
     
  4. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    579
    No im using BillboardAsset with BillboardRenderer, its native unity functionality and it handles the geometry internally. And geometry is correct.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Why does your shader have both a surface shader and a deferred pass? The deferred pass you have written out will just be ignored since the surface shader should be generating one and I believe Unity still only runs the first deferred pass in a shader.

    The "o.Emission" is for the surf function of a surface shader; Emission is a value in the SurfaceOutput struct, which in that setup is actually assigned to the "OUT" variable as "o" is the SpeedTreeFragOut struct.

    I suspect it'll work more like you expect if you delete the entire additional pass (lines 39 to 84), remove the SPEEDTREE_COPY_FRAG line from the surf function, and replace it with this:

    OUT.Emission = o.Albedo;
    OUT.Alpha = o.Alpha;
     
  6. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    579
    @bgolus

    Thanks, it's certainly better now, ill try adding ambient there, but later, cheers!