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?
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.
Oh, ok. I thought that was a surface shader but I see what you're saying now. Time to study up on my CG.
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): Shader "Custom/VertexColorPlusDiffusePlusShadows" { Properties { _Color ("Diffuse Color", Color) = (1.0, 1.0, 1.0, 1.0) } SubShader { Tags { "RenderType" = "Opaque" } Pass { Tags { "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag //#pragma multi_compile_fwdbase #pragma multi_compile_fwdadd_fullshadows //#pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" uniform float4 _Color; struct vertex_input { float4 vertex : POSITION; float4 color : COLOR; float3 normal : NORMAL; }; struct vertex_output { float4 pos : POSITION; float4 color : COLOR; //float4 _ShadowCoord : TEXCOORD3; LIGHTING_COORDS(3, 4) }; struct fragment_output { float4 color : COLOR; }; vertex_output vert(vertex_input v) { vertex_output o; // convert the local position to world position o.pos = mul(UNITY_MATRIX_MVP, v.vertex); float4x4 model_matrix = _Object2World; float4x4 model_matrix_inverse = _World2Object; // calculate the diffuse lighting float3 normal_dir = normalize(float3(mul(float4(v.normal, 0.0), model_matrix_inverse))); float3 light_dir = normalize(float3(_WorldSpaceLightPos0)); float3 diffuse_reflection = float3(_LightColor0) * float3(_Color) * max(0.0, dot(normal_dir, light_dir)); // combine the diffuse lighting from the light source // with the vertex color passed in by the mesh generator /* OUT.color = (IN.color + float4(diffuse_reflection, 1.0)) * 0.5; */ o.color = lerp(v.color, float4(diffuse_reflection, 1.0), 0.5); TRANSFER_VERTEX_TO_FRAGMENT(o); return o; }; fragment_output frag(vertex_output IN) { fragment_output OUT; float atten = LIGHT_ATTENUATION(IN); OUT.color = IN.color * atten; return OUT; }; ENDCG } } Fallback "Diffuse"//, 2 }
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.
This is one that works for me: Code (csharp): Shader "Custom/Vertex Colored Diffuse" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Base (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 150 CGPROGRAM #pragma surface surf Lambert vertex:vert sampler2D _MainTex; fixed4 _Color; struct Input { float2 uv_MainTex; float3 vertColor; }; void vert (inout appdata_full v, out Input o) { UNITY_INITIALIZE_OUTPUT(Input, o); o.vertColor = v.color; } void surf (Input IN, inout SurfaceOutput o) { fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb * IN.vertColor; o.Alpha = c.a; } ENDCG } Fallback "Diffuse" }
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!
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?
Just modify those lines: Code (CSharp): Tags { "RenderType"="Opaque" } // TO: Tags { "Queue" = "Transparent" "RenderType"="Transparent" } #pragma surface surf Lambert vertex:vert // TO: #pragma surface surf Lambert vertex:vert alpha
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.