Recently in the optimization of doing unity Shader Forge and Marmoset, TA has encountered a shadow display problem, specifically as follows:
In the forward rendering state, the static scene uses Blendlayer, which is the shader class generated by the shader forge, and when the dynamic character goes near a static object using Lightmap Bake map, the directional light is projected on the character. cannot be projected onto objects that use shader forge material, but other materials and materials using Marmoset can be received normally. After querying some Web site solutions, the final confirmation is custom shader writing problem, shader Forge generated shader belong to their own implementation of the function of VS and PS, and write surface shader different, except coloring with shader pass (" The 2nd pass {"Lightmode" = "Forwardadd"} is required for cast shadow outside Lightmode "=" forwardbase "). The following is a code for a reference scheme
1 "Test" {2 Subshader {3Tags {"Rendertype"="Opaque"}4 5 //This pass acts the same as the surface shader first pass.6 //calculates per-pixel the most important directional light with shadows,7 //Then Per-vertex the next 4 most important lights,8 //Then Per-vertex Spherical harmionics The rest of the lights,9 //and the ambient light value.Ten One Pass { ATags {"Lightmode"="Forwardbase"} - Cgprogram - the #pragmaMulti_compile_fwdbase - #pragmaVertex vert - #pragmaFragment Frag - #pragmaFragmentoption Arb_precision_hint_fastest +#include"Unitycg.cginc" -#include"Autolight.cginc" + A structInput at { - float4 pos:sv_position; - FLOAT3 Vlight:color; - FLOAT3 Lightdir:texcoord1; - FLOAT3 Vnormal:texcoord2; -Lighting_coords (3,4) in }; - to Input Vert (appdata_full v) + { - Input o; theO.pos =Mul (UNITY_MATRIX_MVP, V.vertex); * //Calc Normal and light dir. $O.lightdir =Normalize (Objspacelightdir (V.vertex));Panax NotoginsengO.vnormal =normalize (v.normal). xyz; - the //Calc spherical harmonics and vertex lights. Ripped from compiled surface shader +FLOAT3 Worldpos =Mul (_object2world, V.vertex). xyz; AFLOAT3 Worldnormal =Mul ((float3x3) _object2world, scaled_normal); theO.vlight = FLOAT3 (0); + #ifdef Lightmap_off - $FLOAT3 shlight = ShadeSH9 (Float4 (Worldnormal,1.0)); $O.vlight =Shlight; - #ifdef vertexlight_on -O.vlight + =Shade4pointlights ( the - unity_4lightposx0, Unity_4lightposy0, Unity_4lightposz0,Wuyi theunity_lightcolor[0].rgb, unity_lightcolor[1].rgb, unity_lightcolor[2].rgb, unity_lightcolor[3].rgb, - Wu Unity_4lightatten0, Worldpos, Worldnormal - About ); $ - #endif //vertexlight_on - #endif //Lightmap_off - transfer_vertex_to_fragment (o); A returno; + } the -FLOAT4 _lightcolor0;//Contains the light color for this pass. $ the Half4 Frag (Input in): COLOR the { theIn.lightdir =normalize (in.lightdir); theIn.vnormal =normalize (in.vnormal); - in floatAtten =light_attenuation (in); the FLOAT3 color; the floatNdotl =saturate (dot (in.vnormal, in.lightdir)); Aboutcolor = Unity_lightmodel_ambient.rgb *2; the theColor + =In.vlight; the +Color + = _lightcolor0.rgb * Ndotl * (Atten *2); - returnHalf4 (Color,1.0f); the }Bayi the ENDCG the } - - //Take this pass out if you don ' t want extra per-pixel lights. the //Just Set the other lights ' Render Mode to ' not Important ', the //And they'll be calculated as spherical harmonics or Vertex Lights in the above pass instead. the the Pass { - theTags {"Lightmode"="Forwardadd"} the the Cgprogram94 the #pragmaMulti_compile_fwdadd the #pragmaVertex vert the #pragmaFragment Frag98 #pragmaFragmentoption Arb_precision_hint_fastest About#include"Unitycg.cginc" -#include"Autolight.cginc"101 102 structInput103 {104 float4 pos:sv_position; the FLOAT3 Lightdir:texcoord1;106 FLOAT3 Vnormal:texcoord2;107 }; 108 109 Input Vert (appdata_full v) the { 111 Input o; theO.pos =Mul (UNITY_MATRIX_MVP, V.vertex);113 the //Calc Normal and light dir. theO.lightdir =Normalize (Objspacelightdir (V.vertex)); theO.vnormal =normalize (v.normal). xyz;117 118 //Don ' t need any ambient or vertex lights in here as the is just a additive pass for each extra light.119 //Shadows won ' t work here, either. - returno;121 }122 123FLOAT4 _lightcolor0;//Contains the light color for this pass.124 the Half4 Frag (Input in): COLOR126 {127In.lightdir =normalize (in.lightdir); -In.vnormal =normalize (in.vnormal);129 the FLOAT3 color;131 floatNdotl =saturate (dot (in.vnormal, in.lightdir)); thecolor = _lightcolor0.rgb *Ndotl;133 returnHalf4 (Color,1.0f); 134 }135 136 ENDCG137 138 }139 } $ 141FallBack"Diffuse"142 143}
When using surface shader, you only need to set the option (Fullforwardshadows) When you declare your surface.
#pragma surface MarmosetSurfMarmosetDirect vertex:MarmosetVert fullforwardshadows
Back to the shader forge plug-in, the scene left using the SF-generated shader,use lightmap, real-time shadow decisively see the left plank for surface shader, the right is Vs+ps shader, the shadow can not be projected on the stone Set shader Forge to Multi-light, and he will automatically generateForwardadd The pass, so the shadow is shown. But the lighting effect is completely different.This issue, in the Shader Forge Forum also mentioned, the author also said that the bug has been modified, but in fact the latest 0.36 is still not fully resolved if the settingsForwardadd After the projection, you can set the light lightmapping to Realtimeonly. Or, you can duplicate a projection's main light source.
conclusion, Shader Forge still use it carefully, and Shader node is far from the sky shop such as Uber Shader to save, in order to project, resulting in the use of lightmap and real time the effect of a great difference, is not worth the candle.
From for notes (Wiz)
About Unity dynamic objects cannot cast shadows to objects using custom shader and Lightmap