Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Problem with vertex shader only showing ~8 lights?

Discussion in 'Shaders' started by Strom_CL, Sep 8, 2014.

  1. Strom_CL

    Strom_CL

    Joined:
    Nov 17, 2012
    Posts:
    112
    I have a mesh that I'm creating that makes a 1x1x1 meter block and creates 32 of them in a "square" pattern, making a 2D style level. I found and tweaked an existing vertex lit shader to allow for colors on each block to be set as I create them, but I've run into a problem where when I place lights in the scene I'm limited to ~8 lights per block of blocks. I'm also seeing a weird separation between meshes.

    I'm using deferred lighting and the torches are point lights. I've highlighted the border of the mesh of blocks, and you can see where the lights don't "bleed over", also the circled torches were placed first and I've numbered the next 8 I placed. If i place another torch on that chunk then light #1 would go out, and so on.

    I think I have two problems with the shader: 1) it doesn't allow for more than 8 lights per mesh, and 2) the light doesn't properly display across boundaries of the mesh. Is this the case? Or does my problem lay somewhere else?

    My level of shader programming is very basic, so I think I also need to read up on that some more, but hopefully someone who's more knowledgeable can help shed some "light" on this for me! :)


    Thanks!


    This is the shader I'm using on the blocks:

    Code (CSharp):
    1. Shader "Vertex Colored" {
    2.  
    3. Properties
    4. {
    5.     _Color ("Main Color", Color) = (1,1,1,1)
    6.     _SpecColor ("Spec Color", Color) = (1,1,1,0)
    7.     _Emission ("Emmisive Color", Color) = (0,0,0,0)
    8.     _Shininess ("Shininess", Range (0.01, 1)) = 0.7
    9.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    10. }
    11.  
    12. SubShader {
    13.     ZWrite On
    14.     Alphatest Greater 0
    15.     Tags {Queue=Transparent}
    16.     Blend SrcAlpha OneMinusSrcAlpha
    17.     ColorMask RGB
    18.     Pass
    19.     {
    20.         Material
    21.         {
    22.             Shininess [_Shininess]
    23.             Specular [_SpecColor]
    24.             Emission [_Emission]  
    25.         }
    26.         ColorMaterial AmbientAndDiffuse  
    27.         Lighting On
    28.         SeparateSpecular On
    29.         SetTexture [_MainTex]
    30.         {
    31.             Combine texture * primary, texture * primary
    32.         }
    33.         SetTexture [_MainTex]
    34.         {
    35.             constantColor [_Color]
    36.             Combine previous * constant DOUBLE, previous * constant
    37.         }
    38.     }
    39.  
    40. }
    41.  
    42.  
    43. Fallback "VertexLit", 1
    44. }
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Your shader is written as a fixed function (vertex-lit only) shader, so it is subject to a vertex light limit. If you use a surface shader, you should be able to use as many per-pixel lights as you want.
     
  3. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Split them into separate meshes as the unity vertex lit limit is per object/mesh. So that's 4 + 1 dir per mesh.
     
  4. Strom_CL

    Strom_CL

    Joined:
    Nov 17, 2012
    Posts:
    112
    I had originally used the Transparent/Cutout/Diffuse shader and it worked perfectly, with the exception that I didn't get the vertex coloring that I passed to the mesh. My knowledge of shader code is extremely limited, but is there a way to just add vertex coloring to that Diffuse shader?

    This one does everything I want but has no transparency and I don't know enough to modify it.

    Code (CSharp):
    1.     Shader "Custom/Diffuse Vertex Colored" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "white" {}
    4.     }
    5.     SubShader {
    6.         Tags { "RenderType"="Opaque" }
    7.  
    8.    
    9.     CGPROGRAM
    10.     #pragma surface surf Lambert noforwardadd
    11.    
    12.     sampler2D _MainTex;
    13.    
    14.     struct Input {
    15.         float2 uv_MainTex;
    16.         float3 color : COLOR;
    17.     };
    18.    
    19.     void surf (Input IN, inout SurfaceOutput o) {
    20.         fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
    21.         o.Albedo = c.rgb * IN.color.rgb;
    22.     }
    23.     ENDCG
    24.     }
    25.    
    26.     Fallback "Mobile/VertexLit"
    27.     }
    28.    
    29.  
     
    Last edited: Sep 9, 2014
  5. Strom_CL

    Strom_CL

    Joined:
    Nov 17, 2012
    Posts:
    112
    Tried changing a few things around using these:

    Code (CSharp):
    1. SubShader {
    2.         Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    Changed the noforwardadd to alpha:
    Code (CSharp):
    1. #pragma surface surf Lambert alpha
    and added this after my o.Albedo line:
    Code (CSharp):
    1. o.Alpha = tex2D (_MainTex, IN.uv_MainTex).a;
    And this gets me the transparency back on the 2nd shader above but loses the diffuse lighting, I get the gap across meshes again and only 8 lights work. If I change the SubShader lines back to Opaque and remove the alpha line it works again.
    Below you can see the solid version has great color and lighting across all of the meshes but no transparency for the sky (which is a blank/transparent spot in my texture atlas), and then when I enable transparency it works but the lighting/mesh division is apparent again and only 8 lights as well as some weird Z errors on some of the blocks.


    Solid:

    Transparent:
     

    Attached Files:

    Last edited: Sep 9, 2014
  6. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Transparent shaders do not support deferred rendering. You will need to increase your pixel light count in order to let Unity do additional passes for lights.

    Additionally, switching to an opaque (or alpha tested) shader in as many places as possible will speed up rendering, support the deferred renderer, and avoid ugly sorting issues.