Search Unity

Vertex Color + Shadows

Discussion in 'Shaders' started by Foam, Jul 19, 2013.

  1. Foam

    Foam

    Joined:
    Jun 13, 2012
    Posts:
    322
    Hello. I am currently using this shader to set the color of a procedural mesh. It works fine but I would like to take this and then apply real-time shadows to it (I have Pro) but I'm not sure how. Anyone have any suggestions?

    Can't I set the vertex info in "pass one" and then do the lighting calculations in "pass two"? Or something like that?

    Any suggestions?
     
  2. Gibbonator

    Gibbonator

    Joined:
    Jul 27, 2012
    Posts:
    204
    I don't think it's possible to get at the shadow map using a fixed function shader. Your best bet may be to port this to a surface shader.
     
    Last edited: Jul 19, 2013
  3. Foam

    Foam

    Joined:
    Jun 13, 2012
    Posts:
    322
    Do you know how I can access the shadow map in a surface shader?
     
  4. Gibbonator

    Gibbonator

    Joined:
    Jul 27, 2012
    Posts:
    204
    The code to sample it is added automatically in surface shaders.
     
  5. Foam

    Foam

    Joined:
    Jun 13, 2012
    Posts:
    322
    Oh, ok. I thought that was a surface shader but I see what you're saying now.

    Time to study up on my CG.
     
  6. Foam

    Foam

    Joined:
    Jun 13, 2012
    Posts:
    322
    After some research this is what I've come up with. It works pretty good so far. This allows me to pass in a vertex color (for some mock ambient occlusion as well as coloring an object without a texture), as well as use a directional light to alter the color, as well as applying real-time shadows in the last pass (hence the fallback to Diffuse).

    Code (csharp):
    1. Shader "Custom/VertexColorPlusDiffusePlusShadows" {
    2.     Properties {
    3.     _Color ("Diffuse Color", Color) = (1.0, 1.0, 1.0, 1.0)
    4.     }
    5.     SubShader {
    6.     Tags { "RenderType" = "Opaque" }
    7.     Pass {
    8.         Tags { "LightMode" = "ForwardBase" }
    9.  
    10.         CGPROGRAM
    11.         #pragma vertex vert
    12.         #pragma fragment frag
    13.         //#pragma multi_compile_fwdbase
    14.             #pragma multi_compile_fwdadd_fullshadows
    15.         //#pragma fragmentoption ARB_precision_hint_fastest
    16.  
    17.  
    18.         #include "UnityCG.cginc"
    19.         #include "Lighting.cginc"
    20.         #include "AutoLight.cginc"
    21.  
    22.         uniform float4 _Color;
    23.  
    24.         struct vertex_input {
    25.         float4 vertex : POSITION;
    26.         float4 color : COLOR;
    27.         float3 normal : NORMAL;
    28.         };
    29.  
    30.         struct vertex_output {
    31.         float4 pos : POSITION;
    32.         float4 color : COLOR;
    33.         //float4 _ShadowCoord : TEXCOORD3;
    34.         LIGHTING_COORDS(3, 4)
    35.         };
    36.  
    37.         struct fragment_output {
    38.         float4 color : COLOR;
    39.         };
    40.  
    41.         vertex_output vert(vertex_input v) {
    42.         vertex_output o;
    43.         // convert the local position to world position
    44.         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    45.  
    46.         float4x4 model_matrix = _Object2World;
    47.         float4x4 model_matrix_inverse = _World2Object;
    48.         // calculate the diffuse lighting
    49.         float3 normal_dir = normalize(float3(mul(float4(v.normal, 0.0), model_matrix_inverse)));
    50.         float3 light_dir = normalize(float3(_WorldSpaceLightPos0));
    51.         float3 diffuse_reflection = float3(_LightColor0) * float3(_Color) * max(0.0, dot(normal_dir, light_dir));
    52.  
    53.         // combine the diffuse lighting from the light source
    54.                 // with the vertex color passed in by the mesh generator
    55.         /* OUT.color = (IN.color + float4(diffuse_reflection, 1.0)) * 0.5; */
    56.         o.color = lerp(v.color, float4(diffuse_reflection, 1.0), 0.5);
    57.         TRANSFER_VERTEX_TO_FRAGMENT(o);
    58.  
    59.         return o;
    60.         };
    61.  
    62.  
    63.         fragment_output frag(vertex_output IN) {
    64.         fragment_output OUT;
    65.  
    66.         float atten = LIGHT_ATTENUATION(IN);
    67.         OUT.color = IN.color * atten;
    68.  
    69.         return OUT;
    70.         };
    71.         ENDCG
    72.  
    73.     }
    74.     }
    75.  
    76.     Fallback "Diffuse"//, 2
    77. }
     
  7. Foam

    Foam

    Joined:
    Jun 13, 2012
    Posts:
    322
    This shader works fine for me in the Editor but when I try a stand-alone build (at least on OSX) any mesh with this shader doesn't show up at all. Anyone have any suggestions for how to fix this?

    I checked the quality settings on the build and it matches what I am using in the editor. The shader is in the Resources folder.
     
  8. VslPaul

    VslPaul

    Joined:
    Aug 18, 2013
    Posts:
    1
    This is one that works for me:

    Code (csharp):
    1. Shader "Custom/Vertex Colored Diffuse" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB)", 2D) = "white" {}
    5. }
    6.  
    7. SubShader {
    8.     Tags { "RenderType"="Opaque" }
    9.     LOD 150
    10.  
    11. CGPROGRAM
    12. #pragma surface surf Lambert vertex:vert
    13.  
    14. sampler2D _MainTex;
    15. fixed4 _Color;
    16.  
    17. struct Input {
    18.     float2 uv_MainTex;
    19.     float3 vertColor;
    20. };
    21.  
    22. void vert (inout appdata_full v, out Input o) {
    23.     UNITY_INITIALIZE_OUTPUT(Input, o);
    24.     o.vertColor = v.color;
    25. }
    26.  
    27. void surf (Input IN, inout SurfaceOutput o) {
    28.     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    29.     o.Albedo = c.rgb * IN.vertColor;
    30.     o.Alpha = c.a;
    31. }
    32. ENDCG
    33. }
    34.  
    35. Fallback "Diffuse"
    36. }
     
    Shinigami92 and puzzlekings like this.
  9. kritchie

    kritchie

    Joined:
    Mar 17, 2013
    Posts:
    7
    VslPaul - Your shader works wonderfully. I was about to write the same thing, but you saved me several hours to piece it all together.

    Well done, thanks for sharing!
     
  10. deab

    deab

    Joined:
    Aug 11, 2013
    Posts:
    93
    VslPaul shader above is just what I was looking for, but would it be possible to add alpha/transparency to this? If so any pointers as to how to go about it?
     
  11. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202
    Just modify those lines:
    Code (CSharp):
    1.  Tags { "RenderType"="Opaque" }
    2. // TO:
    3. Tags { "Queue" = "Transparent" "RenderType"="Transparent" }
    4.  
    5. #pragma surface surf Lambert vertex:vert
    6. // TO:
    7. #pragma surface surf Lambert vertex:vert alpha
     
  12. deab

    deab

    Joined:
    Aug 11, 2013
    Posts:
    93
    Thanks Phantomx, worked a treat!
     
  13. junglemason

    junglemason

    Joined:
    Dec 30, 2010
    Posts:
    69
    Does anything about it need to be updated to work in Unity 4.5? It's not working for me, keeps falling back to Diffuse.