Facebook
From Crippled Marten, 5 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 339
  1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
  2.  
  3. #ifndef UNITY_STANDARD_CORE_INCLUDED
  4. #define UNITY_STANDARD_CORE_INCLUDED
  5.  
  6. #include "UnityCG.cginc"
  7. #include "../UnityShaderVariables.cginc"
  8. #include "../UnityInstancing.cginc"
  9. #include "../UnityStandardConfig.cginc"
  10. #include "../UnityStandardInput.cginc"
  11. #include "../UnityPBSLighting.cginc"
  12. #include "../UnityStandardUtils.cginc"
  13. #include "../UnityGBuffer.cginc"
  14. #include "../UnityStandardBRDF.cginc"
  15. #include "../FogOfWarMath.cginc"
  16.  
  17. #include "AutoLight.cginc"
  18. //-------------------------------------------------------------------------------------
  19. // counterpart for NormalizePerPixelNormal
  20. // skips normalization per-vertex and expects normalization to happen per-pixel
  21. half3 NormalizePerVertexNormal (float3 n) // takes float to avoid overflow
  22. {
  23.     #if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
  24.         return normalize(n);
  25.     #else
  26.         return n; // will normalize per-pixel instead
  27.     #endif
  28. }
  29.  
  30. half3 NormalizePerPixelNormal (half3 n)
  31. {
  32.     #if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
  33.         return n;
  34.     #else
  35.         return normalize(n);
  36.     #endif
  37. }
  38.  
  39. //-------------------------------------------------------------------------------------
  40. UnityLight MainLight ()
  41. {
  42.     UnityLight l;
  43.  
  44.     l.color = _LightColor0.rgb;
  45.     l.dir = _WorldSpaceLightPos0.xyz;
  46.     return l;
  47. }
  48.  
  49. UnityLight AdditiveLight (half3 lightDir, half atten)
  50. {
  51.     UnityLight l;
  52.  
  53.     l.color = _LightColor0.rgb;
  54.     l.dir = lightDir;
  55.     #ifndef USING_DIRECTIONAL_LIGHT
  56.         l.dir = NormalizePerPixelNormal(l.dir);
  57.     #endif
  58.  
  59.     // shadow the light
  60.     l.color *= atten;
  61.     return l;
  62. }
  63.  
  64. UnityLight DummyLight ()
  65. {
  66.     UnityLight l;
  67.     l.color = 0;
  68.     l.dir = half3 (0,1,0);
  69.     return l;
  70. }
  71.  
  72. UnityIndirect ZeroIndirect ()
  73. {
  74.     UnityIndirect ind;
  75.     ind.diffuse = 0;
  76.     ind.specular = 0;
  77.     return ind;
  78. }
  79.  
  80. //-------------------------------------------------------------------------------------
  81. // Common fragment setup
  82.  
  83. // deprecated
  84. half3 WorldNormal(half4 tan2world[3])
  85. {
  86.     return normalize(tan2world[2].xyz);
  87. }
  88.  
  89. // deprecated
  90. #ifdef _TANGENT_TO_WORLD
  91.     half3x3 ExtractTangentToWorldPerPixel(half4 tan2world[3])
  92.     {
  93.         half3 t = tan2world[0].xyz;
  94.         half3 b = tan2world[1].xyz;
  95.         half3 n = tan2world[2].xyz;
  96.  
  97.     #if UNITY_TANGENT_ORTHONORMALIZE
  98.         n = NormalizePerPixelNormal(n);
  99.  
  100.         // ortho-normalize Tangent
  101.         t = normalize (t - n * dot(t, n));
  102.  
  103.         // recalculate Binormal
  104.         half3 newB = cross(n, t);
  105.         b = newB * sign (dot (newB, b));
  106.     #endif
  107.  
  108.         return half3x3(t, b, n);
  109.     }
  110. #else
  111.     half3x3 ExtractTangentToWorldPerPixel(half4 tan2world[3])
  112.     {
  113.         return half3x3(0,0,0,0,0,0,0,0,0);
  114.     }
  115. #endif
  116.  
  117. half3 PerPixelWorldNormal(float4 i_tex, half4 tangentToWorld[3])
  118. {
  119. #ifdef _NORMALMAP
  120.     half3 tangent = tangentToWorld[0].xyz;
  121.     half3 binormal = tangentToWorld[1].xyz;
  122.     half3 normal = tangentToWorld[2].xyz;
  123.  
  124.     #if UNITY_TANGENT_ORTHONORMALIZE
  125.         normal = NormalizePerPixelNormal(normal);
  126.  
  127.         // ortho-normalize Tangent
  128.         tangent = normalize (tangent - normal * dot(tangent, normal));
  129.  
  130.         // recalculate Binormal
  131.         half3 newB = cross(normal, tangent);
  132.         binormal = newB * sign (dot (newB, binormal));
  133.     #endif
  134.  
  135.     half3 normalTangent = NormalInTangentSpace(i_tex);
  136.     half3 normalWorld = NormalizePerPixelNormal(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z); // @TODO: see if we can squeeze this normalize on SM2.0 as well
  137. #else
  138.     half3 normalWorld = normalize(tangentToWorld[2].xyz);
  139. #endif
  140.     return normalWorld;
  141. }
  142.  
  143. #ifdef _PARALLAXMAP
  144.     #define IN_VIEWDIR4PARALLAX(i) NormalizePerPixelNormal(half3(i.tangentToWorldAndPackedData[0].w,i.tangentToWorldAndPackedData[1].w,i.tangentToWorldAndPackedData[2].w))
  145.     #define IN_VIEWDIR4PARALLAX_FWDADD(i) NormalizePerPixelNormal(i.viewDirForParallax.xyz)
  146. #else
  147.     #define IN_VIEWDIR4PARALLAX(i) half3(0,0,0)
  148.     #define IN_VIEWDIR4PARALLAX_FWDADD(i) half3(0,0,0)
  149. #endif
  150.  
  151. #if UNITY_REQUIRE_FRAG_WORLDPOS
  152.     #if UNITY_PACK_WORLDPOS_WITH_TANGENT
  153.         #define IN_WORLDPOS(i) half3(i.tangentToWorldAndPackedData[0].w,i.tangentToWorldAndPackedData[1].w,i.tangentToWorldAndPackedData[2].w)
  154.     #else
  155.         #define IN_WORLDPOS(i) i.posWorld
  156.     #endif
  157.     #define IN_WORLDPOS_FWDADD(i) i.posWorld
  158. #else
  159.     #define IN_WORLDPOS(i) half3(0,0,0)
  160.     #define IN_WORLDPOS_FWDADD(i) half3(0,0,0)
  161. #endif
  162.  
  163. #define IN_LIGHTDIR_FWDADD(i) half3(i.tangentToWorldAndLightDir[0].w, i.tangentToWorldAndLightDir[1].w, i.tangentToWorldAndLightDir[2].w)
  164.  
  165. #define FRAGMENT_SETUP(x) FragmentCommonData x = \
  166.     FragmentSetup(i.tex, i.eyeVec, IN_VIEWDIR4PARALLAX(i), i.tangentToWorldAndPackedData, IN_WORLDPOS(i));
  167.  
  168. #define FRAGMENT_SETUP_FWDADD(x) FragmentCommonData x = \
  169.     FragmentSetup(i.tex, i.eyeVec, IN_VIEWDIR4PARALLAX_FWDADD(i), i.tangentToWorldAndLightDir, IN_WORLDPOS_FWDADD(i));
  170.  
  171. struct FragmentCommonData
  172. {
  173.     half3 diffColor, specColor;
  174.     // Note: smoothness & oneMinusReflectivity for optimization purposes, mostly for DX9 SM2.0 level.
  175.     // Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots.
  176.     half oneMinusReflectivity, smoothness;
  177.     half3 normalWorld, eyeVec, posWorld;
  178.     half alpha;
  179.  
  180. #if UNITY_STANDARD_SIMPLE
  181.     half3 reflUVW;
  182. #endif
  183.  
  184. #if UNITY_STANDARD_SIMPLE
  185.     half3 tangentSpaceNormal;
  186. #endif
  187. };
  188.  
  189. #ifndef UNITY_SETUP_BRDF_INPUT
  190.     #define UNITY_SETUP_BRDF_INPUT SpecularSetup
  191. #endif
  192.  
  193. inline FragmentCommonData SpecularSetup (float4 i_tex)
  194. {
  195.     half4 specGloss = SpecularGloss(i_tex.xy);
  196.     half3 specColor = specGloss.rgb;
  197.     half smoothness = specGloss.a;
  198.  
  199.     half oneMinusReflectivity;
  200.     half3 diffColor = EnergyConservationBetweenDiffuseAndSpecular (Albedo(i_tex), specColor, /*out*/ oneMinusReflectivity);
  201.  
  202.     FragmentCommonData o = (FragmentCommonData)0;
  203.     o.diffColor = diffColor;
  204.     o.specColor = specColor;
  205.     o.oneMinusReflectivity = oneMinusReflectivity;
  206.     o.smoothness = smoothness;
  207.     return o;
  208. }
  209.  
  210. inline FragmentCommonData MetallicSetup (float4 i_tex)
  211. {
  212.     half2 metallicGloss = MetallicGloss(i_tex.xy);
  213.     half metallic = metallicGloss.x;
  214.     half smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.
  215.  
  216.     half oneMinusReflectivity;
  217.     half3 specColor;
  218.     half3 diffColor = DiffuseAndSpecularFromMetallic (Albedo(i_tex), metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
  219.  
  220.     FragmentCommonData o = (FragmentCommonData)0;
  221.     o.diffColor = diffColor;
  222.     o.specColor = specColor;
  223.     o.oneMinusReflectivity = oneMinusReflectivity;
  224.     o.smoothness = smoothness;
  225.     return o;
  226. }
  227.  
  228. // parallax transformed texcoord is used to sample occlusion
  229. inline FragmentCommonData FragmentSetup (inout float4 i_tex, half3 i_eyeVec, half3 i_viewDirForParallax, half4 tangentToWorld[3], half3 i_posWorld)
  230. {
  231.     i_tex = Parallax(i_tex, i_viewDirForParallax);
  232.  
  233.     half alpha = Alpha(i_tex.xy);
  234.     #if defined(_ALPHATEST_ON)
  235.         clip (alpha - _Cutoff);
  236.     #endif
  237.  
  238.     FragmentCommonData o = UNITY_SETUP_BRDF_INPUT (i_tex);
  239.     o.normalWorld = PerPixelWorldNormal(i_tex, tangentToWorld);
  240.     o.eyeVec = NormalizePerPixelNormal(i_eyeVec);
  241.     o.posWorld = i_posWorld;
  242.  
  243.     // NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
  244.     o.diffColor = PreMultiplyAlpha (o.diffColor, alpha, o.oneMinusReflectivity, /*out*/ o.alpha);
  245.     return o;
  246. }
  247.  
  248. inline UnityGI FragmentGI (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light, bool reflections)
  249. {
  250.     UnityGIInput d;
  251.     d.light = light;
  252.     d.worldPos = s.posWorld;
  253.     d.worldViewDir = -s.eyeVec;
  254.     d.atten = atten;
  255.     #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
  256.         d.ambient = 0;
  257.         d.lightmapUV = i_ambientOrLightmapUV;
  258.     #else
  259.         d.ambient = i_ambientOrLightmapUV.rgb;
  260.         d.lightmapUV = 0;
  261.     #endif
  262.  
  263.     d.probeHDR[0] = unity_SpecCube0_HDR;
  264.     d.probeHDR[1] = unity_SpecCube1_HDR;
  265.     #if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION)
  266.       d.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending
  267.     #endif
  268.     #ifdef UNITY_SPECCUBE_BOX_PROJECTION
  269.       d.boxMax[0] = unity_SpecCube0_BoxMax;
  270.       d.probePosition[0] = unity_SpecCube0_ProbePosition;
  271.       d.boxMax[1] = unity_SpecCube1_BoxMax;
  272.       d.boxMin[1] = unity_SpecCube1_BoxMin;
  273.       d.probePosition[1] = unity_SpecCube1_ProbePosition;
  274.     #endif
  275.  
  276.     if(reflections)
  277.     {
  278.         Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.smoothness, -s.eyeVec, s.normalWorld, s.specColor);
  279.         // Replace the reflUVW if it has been compute in Vertex shader. Note: the compiler will optimize the calcul in UnityGlossyEnvironmentSetup itself
  280.         #if UNITY_STANDARD_SIMPLE
  281.             g.reflUVW = s.reflUVW;
  282.         #endif
  283.  
  284.         return UnityGlobalIllumination (d, occlusion, s.normalWorld, g);
  285.     }
  286.     else
  287.     {
  288.         return UnityGlobalIllumination (d, occlusion, s.normalWorld);
  289.     }
  290. }
  291.  
  292. inline UnityGI FragmentGI (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light)
  293. {
  294.     return FragmentGI(s, occlusion, i_ambientOrLightmapUV, atten, light, true);
  295. }
  296.  
  297.  
  298. //-------------------------------------------------------------------------------------
  299. half4 OutputForward (half4 output, half alphaFromSurface)
  300. {
  301.     #if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON)
  302.         output.a = alphaFromSurface;
  303.     #else
  304.         UNITY_OPAQUE_ALPHA(output.a);
  305.     #endif
  306.     return output;
  307. }
  308.  
  309. inline half4 VertexGIForward(VertexInput v, float3 posWorld, half3 normalWorld)
  310. {
  311.     half4 ambientOrLightmapUV = 0;
  312.     // Static lightmaps
  313.     #ifdef LIGHTMAP_ON
  314.         ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
  315.         ambientOrLightmapUV.zw = 0;
  316.     // Sample light probe for Dynamic objects only (no static or dynamic lightmaps)
  317.     #elif UNITY_SHOULD_SAMPLE_SH
  318.         #ifdef VERTEXLIGHT_ON
  319.             // Approximated illumination from non-important point lights
  320.             ambientOrLightmapUV.rgb = Shade4PointLights (
  321.                 unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
  322.                 unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
  323.                 unity_4LightAtten0, posWorld, normalWorld);
  324.         #endif
  325.  
  326.         ambientOrLightmapUV.rgb = ShadeSHPerVertex (normalWorld, ambientOrLightmapUV.rgb);
  327.     #endif
  328.  
  329.     #ifdef DYNAMICLIGHTMAP_ON
  330.         ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
  331.     #endif
  332.  
  333.     return ambientOrLightmapUV;
  334. }
  335.  
  336. // ------------------------------------------------------------------
  337. //  Base forward pass (directional light, emission, lightmaps, ...)
  338.  
  339. struct VertexOutputForwardBase
  340. {
  341.     UNITY_POSITION(pos);
  342.     float4 tex                          : TEXCOORD0;
  343.     half3 eyeVec                        : TEXCOORD1;
  344.     half4 tangentToWorldAndPackedData[3]    : TEXCOORD2;    // [3x3:tangentToWorld | 1x3:viewDirForParallax or worldPos]
  345.     half4 ambientOrLightmapUV           : TEXCOORD5;    // SH or Lightmap UV
  346.     UNITY_SHADOW_COORDS(6)
  347.     UNITY_FOG_COORDS(7)
  348.  
  349.     // next ones would not fit into SM2.0 limits, but they are always for SM3.0+
  350.     #if UNITY_REQUIRE_FRAG_WORLDPOS && !UNITY_PACK_WORLDPOS_WITH_TANGENT  || _FOG_OF_WAR
  351.         float3 posWorld                 : TEXCOORD8;
  352.     #endif
  353.  
  354.     UNITY_VERTEX_INPUT_INSTANCE_ID
  355.     UNITY_VERTEX_OUTPUT_STEREO
  356. };
  357.  
  358. VertexOutputForwardBase vertForwardBase (VertexInput v)
  359. {
  360.     UNITY_SETUP_INSTANCE_ID(v);
  361.     VertexOutputForwardBase o;
  362.     UNITY_INITIALIZE_OUTPUT(VertexOutputForwardBase, o);
  363.     UNITY_TRANSFER_INSTANCE_ID(v, o);
  364.     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  365.  
  366.     float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
  367.     #if UNITY_REQUIRE_FRAG_WORLDPOS
  368.         #if UNITY_PACK_WORLDPOS_WITH_TANGENT
  369.             o.tangentToWorldAndPackedData[0].w = posWorld.x;
  370.             o.tangentToWorldAndPackedData[1].w = posWorld.y;
  371.             o.tangentToWorldAndPackedData[2].w = posWorld.z;
  372.         #else
  373.             o.posWorld = posWorld.xyz;
  374.         #endif
  375.     #endif
  376.     o.pos = UnityObjectToClipPos(v.vertex);
  377.  
  378.     o.tex = TexCoords(v);
  379.     o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
  380.     float3 normalWorld = UnityObjectToWorldNormal(v.normal);
  381.     #ifdef _TANGENT_TO_WORLD
  382.         float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
  383.  
  384.         float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
  385.         o.tangentToWorldAndPackedData[0].xyz = tangentToWorld[0];
  386.         o.tangentToWorldAndPackedData[1].xyz = tangentToWorld[1];
  387.         o.tangentToWorldAndPackedData[2].xyz = tangentToWorld[2];
  388.     #else
  389.         o.tangentToWorldAndPackedData[0].xyz = 0;
  390.         o.tangentToWorldAndPackedData[1].xyz = 0;
  391.         o.tangentToWorldAndPackedData[2].xyz = normalWorld;
  392.     #endif
  393.  
  394.     //We need this for shadow receving
  395.     UNITY_TRANSFER_SHADOW(o, v.uv1);
  396.  
  397.     o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld);
  398.  
  399.     #ifdef _PARALLAXMAP
  400.         TANGENT_SPACE_ROTATION;
  401.         half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
  402.         o.tangentToWorldAndPackedData[0].w = viewDirForParallax.x;
  403.         o.tangentToWorldAndPackedData[1].w = viewDirForParallax.y;
  404.         o.tangentToWorldAndPackedData[2].w = viewDirForParallax.z;
  405.     #endif
  406.  
  407.     UNITY_TRANSFER_FOG(o,o.pos);
  408.     return o;
  409. }
  410.  
  411. half4 fragForwardBaseInternal (VertexOutputForwardBase i)
  412. {
  413.     UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
  414.  
  415.     FRAGMENT_SETUP(s)
  416.  
  417.     UNITY_SETUP_INSTANCE_ID(i);
  418.     UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
  419.  
  420.     UnityLight mainLight = MainLight ();
  421.     UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld);
  422.  
  423.     half occlusion = Occlusion(i.tex.xy);
  424.     UnityGI gi = FragmentGI (s, occlusion, i.ambientOrLightmapUV, atten, mainLight);
  425.  
  426.     half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect);
  427.  
  428.         fixed4 FoW = FoWIntensity(s.posWorld);
  429.     c.rgb += Emission(i.tex.xy) /** FoW.rgb*/;
  430.  
  431.     UNITY_APPLY_FOG(i.fogCoord, c.rgb);
  432.  
  433.         c.rgb *= FoW.rgb;
  434.  
  435.     return OutputForward (c, s.alpha);
  436. }
  437.  
  438. half4 fragForwardBase (VertexOutputForwardBase i) : SV_Target   // backward compatibility (this used to be the fragment entry function)
  439. {
  440.     return fragForwardBaseInternal(i);
  441. }
  442.  
  443. // ------------------------------------------------------------------
  444. //  Additive forward pass (one light per pass)
  445.  
  446. struct VertexOutputForwardAdd
  447. {
  448.     UNITY_POSITION(pos);
  449.     float4 tex                          : TEXCOORD0;
  450.     half3 eyeVec                        : TEXCOORD1;
  451.     half4 tangentToWorldAndLightDir[3]  : TEXCOORD2;    // [3x3:tangentToWorld | 1x3:lightDir]
  452.     float3 posWorld                     : TEXCOORD5;
  453.     UNITY_SHADOW_COORDS(6)
  454.     UNITY_FOG_COORDS(7)
  455.  
  456.     // next ones would not fit into SM2.0 limits, but they are always for SM3.0+
  457. #if defined(_PARALLAXMAP)
  458.     half3 viewDirForParallax            : TEXCOORD8;
  459. #endif
  460.  
  461.     UNITY_VERTEX_OUTPUT_STEREO
  462. };
  463.  
  464. VertexOutputForwardAdd vertForwardAdd (VertexInput v)
  465. {
  466.     UNITY_SETUP_INSTANCE_ID(v);
  467.     VertexOutputForwardAdd o;
  468.     UNITY_INITIALIZE_OUTPUT(VertexOutputForwardAdd, o);
  469.     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  470.  
  471.     float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
  472.     o.pos = UnityObjectToClipPos(v.vertex);
  473.  
  474.     o.tex = TexCoords(v);
  475.     o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
  476.     o.posWorld = posWorld.xyz;
  477.     float3 normalWorld = UnityObjectToWorldNormal(v.normal);
  478.     #ifdef _TANGENT_TO_WORLD
  479.         float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
  480.  
  481.         float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
  482.         o.tangentToWorldAndLightDir[0].xyz = tangentToWorld[0];
  483.         o.tangentToWorldAndLightDir[1].xyz = tangentToWorld[1];
  484.         o.tangentToWorldAndLightDir[2].xyz = tangentToWorld[2];
  485.     #else
  486.         o.tangentToWorldAndLightDir[0].xyz = 0;
  487.         o.tangentToWorldAndLightDir[1].xyz = 0;
  488.         o.tangentToWorldAndLightDir[2].xyz = normalWorld;
  489.     #endif
  490.     //We need this for shadow receiving
  491.     UNITY_TRANSFER_SHADOW(o, v.uv1);
  492.  
  493.     float3 lightDir = _WorldSpaceLightPos0.xyz - posWorld.xyz * _WorldSpaceLightPos0.w;
  494.     #ifndef USING_DIRECTIONAL_LIGHT
  495.         lightDir = NormalizePerVertexNormal(lightDir);
  496.     #endif
  497.     o.tangentToWorldAndLightDir[0].w = lightDir.x;
  498.     o.tangentToWorldAndLightDir[1].w = lightDir.y;
  499.     o.tangentToWorldAndLightDir[2].w = lightDir.z;
  500.  
  501.     #ifdef _PARALLAXMAP
  502.         TANGENT_SPACE_ROTATION;
  503.         o.viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
  504.     #endif
  505.  
  506.     UNITY_TRANSFER_FOG(o,o.pos);
  507.     return o;
  508. }
  509.  
  510. half4 fragForwardAddInternal (VertexOutputForwardAdd i)
  511. {
  512.     UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
  513.  
  514.     FRAGMENT_SETUP_FWDADD(s)
  515.  
  516.     UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld)
  517.     UnityLight light = AdditiveLight (IN_LIGHTDIR_FWDADD(i), atten);
  518.     UnityIndirect noIndirect = ZeroIndirect ();
  519.  
  520.     half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, light, noIndirect);
  521.  
  522.     UNITY_APPLY_FOG_COLOR(i.fogCoord, c.rgb, half4(0,0,0,0)); // fog towards black in additive pass
  523.  
  524.         fixed4 FoW = FoWIntensity(s.posWorld);
  525.         c.rgb *= FoW.rgb;
  526.  
  527.     return OutputForward (c, s.alpha);
  528. }
  529.  
  530. half4 fragForwardAdd (VertexOutputForwardAdd i) : SV_Target     // backward compatibility (this used to be the fragment entry function)
  531. {
  532.     return fragForwardAddInternal(i);
  533. }
  534.  
  535. // ------------------------------------------------------------------
  536. //  Deferred pass
  537.  
  538. struct VertexOutputDeferred
  539. {
  540.     UNITY_POSITION(pos);
  541.     float4 tex                          : TEXCOORD0;
  542.     half3 eyeVec                        : TEXCOORD1;
  543.     half4 tangentToWorldAndPackedData[3]: TEXCOORD2;    // [3x3:tangentToWorld | 1x3:viewDirForParallax or worldPos]
  544.     half4 ambientOrLightmapUV           : TEXCOORD5;    // SH or Lightmap UVs
  545.  
  546.     #if UNITY_REQUIRE_FRAG_WORLDPOS && !UNITY_PACK_WORLDPOS_WITH_TANGENT
  547.         float3 posWorld                     : TEXCOORD6;
  548.     #endif
  549.  
  550.         float3 worldPos                     : TEXCOORD7;
  551.  
  552.     UNITY_VERTEX_OUTPUT_STEREO
  553. };
  554.  
  555.  
  556. VertexOutputDeferred vertDeferred (VertexInput v)
  557. {
  558.     UNITY_SETUP_INSTANCE_ID(v);
  559.     VertexOutputDeferred o;
  560.     UNITY_INITIALIZE_OUTPUT(VertexOutputDeferred, o);
  561.     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  562.  
  563.     float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
  564.         o.worldPos = posWorld.xyz;
  565.  
  566.     #if UNITY_REQUIRE_FRAG_WORLDPOS
  567.         #if UNITY_PACK_WORLDPOS_WITH_TANGENT
  568.             o.tangentToWorldAndPackedData[0].w = posWorld.x;
  569.             o.tangentToWorldAndPackedData[1].w = posWorld.y;
  570.             o.tangentToWorldAndPackedData[2].w = posWorld.z;
  571.         #else
  572.             o.posWorld = posWorld.xyz;
  573.         #endif
  574.     #endif
  575.     o.pos = UnityObjectToClipPos(v.vertex);
  576.  
  577.     o.tex = TexCoords(v);
  578.     o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
  579.     float3 normalWorld = UnityObjectToWorldNormal(v.normal);
  580.     #ifdef _TANGENT_TO_WORLD
  581.         float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
  582.  
  583.         float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
  584.         o.tangentToWorldAndPackedData[0].xyz = tangentToWorld[0];
  585.         o.tangentToWorldAndPackedData[1].xyz = tangentToWorld[1];
  586.         o.tangentToWorldAndPackedData[2].xyz = tangentToWorld[2];
  587.     #else
  588.         o.tangentToWorldAndPackedData[0].xyz = 0;
  589.         o.tangentToWorldAndPackedData[1].xyz = 0;
  590.         o.tangentToWorldAndPackedData[2].xyz = normalWorld;
  591.     #endif
  592.  
  593.     o.ambientOrLightmapUV = 0;
  594.     #ifdef LIGHTMAP_ON
  595.         o.ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
  596.     #elif UNITY_SHOULD_SAMPLE_SH
  597.         o.ambientOrLightmapUV.rgb = ShadeSHPerVertex (normalWorld, o.ambientOrLightmapUV.rgb);
  598.     #endif
  599.     #ifdef DYNAMICLIGHTMAP_ON
  600.         o.ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
  601.     #endif
  602.  
  603.     #ifdef _PARALLAXMAP
  604.         TANGENT_SPACE_ROTATION;
  605.         half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
  606.         o.tangentToWorldAndPackedData[0].w = viewDirForParallax.x;
  607.         o.tangentToWorldAndPackedData[1].w = viewDirForParallax.y;
  608.         o.tangentToWorldAndPackedData[2].w = viewDirForParallax.z;
  609.     #endif
  610.  
  611.     return o;
  612. }
  613.  
  614. void fragDeferred (
  615.     VertexOutputDeferred i,
  616.     out half4 outGBuffer0 : SV_Target0,
  617.     out half4 outGBuffer1 : SV_Target1,
  618.     out half4 outGBuffer2 : SV_Target2,
  619.     out half4 outEmission : SV_Target3          // RT3: emission (rgb), --unused-- (a)
  620. #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)
  621.     ,out half4 outShadowMask : SV_Target4       // RT4: shadowmask (rgba)
  622. #endif
  623. )
  624. {
  625.     #if (SHADER_TARGET < 30)
  626.         outGBuffer0 = 1;
  627.         outGBuffer1 = 1;
  628.         outGBuffer2 = 0;
  629.         outEmission = 0;
  630.         #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)
  631.             outShadowMask = 1;
  632.         #endif
  633.         return;
  634.     #endif
  635.  
  636.     UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
  637.  
  638.     FRAGMENT_SETUP(s)
  639.  
  640.     // no analytic lights in this pass
  641.     UnityLight dummyLight = DummyLight ();
  642.     half atten = 1;
  643.  
  644.     // only GI
  645.     half occlusion = Occlusion(i.tex.xy);
  646. #if UNITY_ENABLE_REFLECTION_BUFFERS
  647.     bool sampleReflectionsInDeferred = false;
  648. #else
  649.     bool sampleReflectionsInDeferred = true;
  650. #endif
  651.  
  652.     UnityGI gi = FragmentGI (s, occlusion, i.ambientOrLightmapUV, atten, dummyLight, sampleReflectionsInDeferred);
  653.  
  654.         fixed4 FoW = FoWIntensity(i.worldPos);
  655.         s.diffColor *= FoW.rgb;
  656.         s.specColor *= FoW.rgb;
  657.         occlusion *= FoW.rgb;
  658.         s.smoothness *= FoW.rgb;
  659.  
  660.     half3 emissiveColor = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect).rgb;
  661.        
  662.     #ifdef _EMISSION
  663.         emissiveColor += Emission (i.tex.xy) * FoW.rgb;
  664.                 //if(FoW.r>0 && FoW.r<0.5f)
  665.                 //      emissiveColor[2] = -2;
  666.     #endif
  667.  
  668.     #ifndef UNITY_HDR_ON
  669.                 emissiveColor.rgb = exp2(-emissiveColor.rgb);
  670.     #endif
  671.  
  672.     UnityStandardData data;
  673.     data.diffuseColor   = s.diffColor;
  674.     data.occlusion      = occlusion;
  675.     data.specularColor  = s.specColor;
  676.     data.smoothness     = s.smoothness;
  677.     data.normalWorld    = s.normalWorld;
  678.  
  679.     UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2);
  680.  
  681.     emissiveColor = emissiveColor ;
  682.     // Emissive lighting buffer
  683.     outEmission = half4(emissiveColor, 1);
  684.  
  685.     // Baked direct lighting occlusion if any
  686.     #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)
  687.         outShadowMask = UnityGetRawBakedOcclusions(i.ambientOrLightmapUV.xy, IN_WORLDPOS(i));
  688.     #endif
  689. }
  690.  
  691. //
  692. // Old FragmentGI signature. Kept only for backward compatibility and will be removed soon
  693. //
  694.  
  695. inline UnityGI FragmentGI(
  696.     float3 posWorld,
  697.     half occlusion, half4 i_ambientOrLightmapUV, half atten, half smoothness, half3 normalWorld, half3 eyeVec,
  698.     UnityLight light,
  699.     bool reflections)
  700. {
  701.     // we init only fields actually used
  702.     FragmentCommonData s = (FragmentCommonData)0;
  703.     s.smoothness = smoothness;
  704.     s.normalWorld = normalWorld;
  705.     s.eyeVec = eyeVec;
  706.     s.posWorld = posWorld;
  707.     return FragmentGI(s, occlusion, i_ambientOrLightmapUV, atten, light, reflections);
  708. }
  709. inline UnityGI FragmentGI (
  710.     float3 posWorld,
  711.     half occlusion, half4 i_ambientOrLightmapUV, half atten, half smoothness, half3 normalWorld, half3 eyeVec,
  712.     UnityLight light)
  713. {
  714.     return FragmentGI (posWorld, occlusion, i_ambientOrLightmapUV, atten, smoothness, normalWorld, eyeVec, light, true);
  715. }
  716.  
  717. #endif // UNITY_STANDARD_CORE_INCLUDED
  718.