SHARE
TWEET

SpeedTree.shader

kritoa Aug 4th, 2017 (edited) 89 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
  2.  
  3. Shader "Nature/SpeedTree"
  4. {
  5.     Properties
  6.     {
  7.         _Color ("Main Color", Color) = (1,1,1,1)
  8.         _HueVariation ("Hue Variation", Color) = (1.0,0.5,0.0,0.1)
  9.         _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
  10.         _DetailTex ("Detail", 2D) = "black" {}
  11.         _BumpMap ("Normal Map", 2D) = "bump" {}
  12.         _Cutoff ("Alpha Cutoff", Range(0,1)) = 0.333
  13.         [MaterialEnum(Off,0,Front,1,Back,2)] _Cull ("Cull", Int) = 2
  14.         [MaterialEnum(None,0,Fastest,1,Fast,2,Better,3,Best,4,Palm,5)] _WindQuality ("Wind Quality", Range(0,5)) = 0
  15.     }
  16.  
  17.     // targeting SM3.0+
  18.     SubShader
  19.     {
  20.         Tags
  21.         {
  22.             "Queue"="Geometry"
  23.             "IgnoreProjector"="True"
  24.             "RenderType"="Opaque"
  25.             "DisableBatching"="LODFading"
  26.         }
  27.         LOD 400
  28.         Cull [_Cull]
  29.  
  30.         CGPROGRAM
  31.             #pragma surface surf Lambert vertex:SpeedTreeVertKritoa nodirlightmap nodynlightmap noshadowmask
  32.             #pragma target 3.0
  33.             #pragma multi_compile __ LOD_FADE_PERCENTAGE LOD_FADE_CROSSFADE
  34.             #pragma instancing_options assumeuniformscaling lodfade maxcount:50
  35.             #pragma shader_feature GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
  36.             #pragma shader_feature EFFECT_BUMP
  37.             #pragma shader_feature EFFECT_HUE_VARIATION
  38.             #define ENABLE_WIND
  39.             #include "SpeedTreeCommon.cginc"
  40.  
  41.             void OffsetSpeedTreeVertexKritoa(inout SpeedTreeVB data, float lodValue)
  42.             {
  43.                 float3 finalPosition = data.vertex.xyz;
  44.  
  45.                 #ifdef ENABLE_WIND
  46.                     half windQuality = _WindQuality * _WindEnabled;
  47.  
  48.                     float3 rotatedWindVector, rotatedBranchAnchor;
  49.                     if (windQuality <= WIND_QUALITY_NONE)
  50.                     {
  51.                         rotatedWindVector = float3(0.0f, 0.0f, 0.0f);
  52.                         rotatedBranchAnchor = float3(0.0f, 0.0f, 0.0f);
  53.                     }
  54.                     else
  55.                     {
  56.                         // compute rotated wind parameters
  57.                         rotatedWindVector = normalize(mul(_ST_WindVector.xyz, (float3x3)unity_ObjectToWorld));
  58.                         rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)unity_ObjectToWorld)) * _ST_WindBranchAnchor.w;
  59.                     }
  60.                 #endif
  61.  
  62.                 #if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_FROND)
  63.  
  64.                     // smooth LOD
  65.                     #ifdef LOD_FADE_PERCENTAGE
  66.                         finalPosition = lerp(finalPosition, data.texcoord1.xyz, lodValue);
  67.                     #endif
  68.  
  69.                     // frond wind, if needed
  70.                     #if defined(ENABLE_WIND) && defined(GEOM_TYPE_FROND)
  71.                         if (windQuality == WIND_QUALITY_PALM)
  72.                             finalPosition = RippleFrond(finalPosition, data.normal, data.texcoord.x, data.texcoord.y, data.texcoord2.x, data.texcoord2.y, data.texcoord2.z);
  73.                     #endif
  74.  
  75.                 #elif defined(GEOM_TYPE_LEAF)
  76.  
  77.                     // remove anchor position
  78.                     finalPosition -= data.texcoord1.xyz;
  79.  
  80.                     bool isFacingLeaf = data.color.a == 0;
  81.                     if (isFacingLeaf)
  82.                     {
  83.                         #ifdef LOD_FADE_PERCENTAGE
  84.                             finalPosition *= lerp(1.0, data.texcoord1.w, lodValue);
  85.                         #endif
  86.  
  87.                         // face camera-facing leaf to camera                
  88. //                      float offsetLen = length(finalPosition);
  89. //                      finalPosition = mul(finalPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * finalPosition    // old camera facing (orients to view matrix, bad!!)
  90.  
  91.                         // KRITOA: can't get this to work - somebody help
  92.  
  93.                         // orient to camera position with up vector instead now
  94. //                      float3 camPos = _WorldSpaceCameraPos.xyz;
  95. //                      float3 objectOrigin = data.texcoord1.xyz;  //mul(unity_ObjectToWorld, float3(0,0,0));
  96. //                      float3 objectForward = normalize(camPos-objectOrigin);
  97. //                      float3 objectRight = normalize(cross(float3(0,1,0),objectForward));
  98. //                      float3 objectUp = normalize(cross(objectForward,objectRight));
  99. //                      finalPosition = mul(float3x3(objectRight, objectUp, objectForward),finalPosition.xyz);
  100. //                      finalPosition = mul(finalPosition.xyz,float3x3(objectRight.x, objectUp.x, objectForward.x,
  101. //                                                                      objectRight.y, objectUp.y, objectForward.y,
  102. //                                                                      objectRight.z, objectUp.z, objectForward.z));
  103. //                      finalPosition = mul(float3x3(objectRight.x, objectUp.x, objectForward.x,
  104. //                                                                      objectRight.y, objectUp.y, objectForward.y,
  105. //                                                                      objectRight.z, objectUp.z, objectForward.z),
  106. //                                                                      finalPosition.xyz);
  107. //                      finalPosition = mul(finalPosition.xyz,float3x3(objectRight.x, objectRight.y, objectRight.z,
  108. //                                                                      objectUp.x, objectUp.y, objectUp.z,
  109. //                                                                      objectForward.x, objectForward.y, objectForward.z));
  110. //                      finalPosition = mul(float3x3(objectRight.x, objectRight.y, objectRight.z,
  111. //                                                                      objectUp.x, objectUp.y, objectUp.z,
  112. //                                                                      objectForward.x, objectForward.y, objectForward.z),
  113. //                                                                      finalPosition.xyz);
  114.  
  115. //                      finalPosition = normalize(finalPosition) * offsetLen; // make sure the offset vector is still scaled
  116.                     }
  117.                     else
  118.                     {
  119.                         #ifdef LOD_FADE_PERCENTAGE
  120.                             float3 lodPosition = float3(data.texcoord1.w, data.texcoord3.x, data.texcoord3.y);
  121.                             finalPosition = lerp(finalPosition, lodPosition, lodValue);
  122.                         #endif
  123.                     }
  124.  
  125.                     #ifdef ENABLE_WIND
  126.                         // leaf wind
  127.                         if (windQuality > WIND_QUALITY_FASTEST && windQuality < WIND_QUALITY_PALM)
  128.                         {
  129.                             float leafWindTrigOffset = data.texcoord1.x + data.texcoord1.y;
  130.                             finalPosition = LeafWind(windQuality == WIND_QUALITY_BEST, data.texcoord2.w > 0.0, finalPosition, data.normal, data.texcoord2.x, float3(0,0,0), data.texcoord2.y, data.texcoord2.z, leafWindTrigOffset, rotatedWindVector);
  131.                         }
  132.                     #endif
  133.  
  134.                     // move back out to anchor
  135.                     finalPosition += data.texcoord1.xyz;
  136.  
  137.                 #endif
  138.  
  139.                 #ifdef ENABLE_WIND
  140.                     float3 treePos = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
  141.  
  142.                     #ifndef GEOM_TYPE_MESH
  143.                         if (windQuality >= WIND_QUALITY_BETTER)
  144.                         {
  145.                             // branch wind (applies to all 3D geometry)
  146.                             finalPosition = BranchWind(windQuality == WIND_QUALITY_PALM, finalPosition, treePos, float4(data.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
  147.                         }
  148.                     #endif
  149.  
  150.                     if (windQuality > WIND_QUALITY_NONE)
  151.                     {
  152.                         // global wind
  153.                         finalPosition = GlobalWind(finalPosition, treePos, true, rotatedWindVector, _ST_WindGlobal.x);
  154.                     }
  155.                 #endif
  156.  
  157.                 data.vertex.xyz = finalPosition;
  158.             }
  159.  
  160.             void SpeedTreeVertKritoa(inout SpeedTreeVB IN, out Input OUT)
  161.             {
  162.                 UNITY_INITIALIZE_OUTPUT(Input, OUT);
  163.  
  164.                 OUT.mainTexUV = IN.texcoord.xy;
  165.                 OUT.color = _Color;
  166.                 OUT.color.rgb *= IN.color.r; // ambient occlusion factor
  167.  
  168.                 #ifdef EFFECT_HUE_VARIATION
  169.                     float hueVariationAmount = frac(unity_ObjectToWorld[0].w + unity_ObjectToWorld[1].w + unity_ObjectToWorld[2].w);
  170.                     hueVariationAmount += frac(IN.vertex.x + IN.normal.y + IN.normal.x) * 0.5 - 0.3;
  171.                     OUT.HueVariationAmount = saturate(hueVariationAmount * _HueVariation.a);
  172.                 #endif
  173.  
  174.                 #ifdef GEOM_TYPE_BRANCH_DETAIL
  175.                     // The two types are always in different sub-range of the mesh so no interpolation (between detail and blend) problem.
  176.                     OUT.Detail.xy = IN.texcoord2.xy;
  177.                     if (IN.color.a == 0) // Blend
  178.                         OUT.Detail.z = IN.texcoord2.z;
  179.                     else // Detail texture
  180.                         OUT.Detail.z = 2.5f; // stay out of Blend's .z range
  181.                 #endif
  182.  
  183.                 OffsetSpeedTreeVertexKritoa(IN, unity_LODFade.x);
  184.  
  185.                 UNITY_TRANSFER_DITHER_CROSSFADE(OUT, IN.vertex)
  186.             }
  187.  
  188.  
  189.             void surf(Input IN, inout SurfaceOutput OUT)
  190.             {
  191.                 SpeedTreeFragOut o;
  192.                 SpeedTreeFrag(IN, o);
  193.                 SPEEDTREE_COPY_FRAG(OUT, o)
  194.             }
  195.         ENDCG
  196.  
  197.         Pass
  198.         {
  199.             Tags { "LightMode" = "ShadowCaster" }
  200.  
  201.             CGPROGRAM
  202.                 #pragma vertex vert
  203.                 #pragma fragment frag
  204.                 #pragma target 3.0
  205.                 #pragma multi_compile __ LOD_FADE_PERCENTAGE LOD_FADE_CROSSFADE
  206.                 #pragma multi_compile_instancing
  207.                 #pragma instancing_options assumeuniformscaling lodfade maxcount:50
  208.                 #pragma shader_feature GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
  209.                 #pragma multi_compile_shadowcaster
  210.                 #define ENABLE_WIND
  211.                 #include "SpeedTreeCommon.cginc"
  212.  
  213.             void OffsetSpeedTreeVertexKritoa(inout SpeedTreeVB data, float lodValue)
  214.             {
  215.                 float3 finalPosition = data.vertex.xyz;
  216.  
  217.                 #ifdef ENABLE_WIND
  218.                     half windQuality = _WindQuality * _WindEnabled;
  219.  
  220.                     float3 rotatedWindVector, rotatedBranchAnchor;
  221.                     if (windQuality <= WIND_QUALITY_NONE)
  222.                     {
  223.                         rotatedWindVector = float3(0.0f, 0.0f, 0.0f);
  224.                         rotatedBranchAnchor = float3(0.0f, 0.0f, 0.0f);
  225.                     }
  226.                     else
  227.                     {
  228.                         // compute rotated wind parameters
  229.                         rotatedWindVector = normalize(mul(_ST_WindVector.xyz, (float3x3)unity_ObjectToWorld));
  230.                         rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)unity_ObjectToWorld)) * _ST_WindBranchAnchor.w;
  231.                     }
  232.                 #endif
  233.  
  234.                 #if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_FROND)
  235.  
  236.                     // smooth LOD
  237.                     #ifdef LOD_FADE_PERCENTAGE
  238.                         finalPosition = lerp(finalPosition, data.texcoord1.xyz, lodValue);
  239.                     #endif
  240.  
  241.                     // frond wind, if needed
  242.                     #if defined(ENABLE_WIND) && defined(GEOM_TYPE_FROND)
  243.                         if (windQuality == WIND_QUALITY_PALM)
  244.                             finalPosition = RippleFrond(finalPosition, data.normal, data.texcoord.x, data.texcoord.y, data.texcoord2.x, data.texcoord2.y, data.texcoord2.z);
  245.                     #endif
  246.  
  247.                 #elif defined(GEOM_TYPE_LEAF)
  248.  
  249.                     // remove anchor position
  250.                     finalPosition -= data.texcoord1.xyz;
  251.  
  252.                     bool isFacingLeaf = data.color.a == 0;
  253.                     if (isFacingLeaf)
  254.                     {
  255.                         #ifdef LOD_FADE_PERCENTAGE
  256.                             finalPosition *= lerp(1.0, data.texcoord1.w, lodValue);
  257.                         #endif
  258.  
  259.                         // face camera-facing leaf to camera
  260. //                      float offsetLen = length(finalPosition);
  261. //                      finalPosition = mul(finalPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * finalPosition    // old camera facing (orients to view matrix, bad!)
  262.  
  263.                         //KRITOA: can't get this to work. Somebody help.
  264.  
  265.                         // orient to camera position with up vector instead now
  266. //                      float3 camPos = _WorldSpaceCameraPos.xyz;
  267. //                      float3 objectOrigin = data.texcoord1.xyz;  //mul(unity_ObjectToWorld, float3(0,0,0));
  268. //                      float3 objectForward = normalize(camPos-objectOrigin);
  269. //                      float3 objectRight = normalize(cross(float3(0,1,0),objectForward));
  270. //                      float3 objectUp = normalize(cross(objectForward,objectRight));
  271. //                      finalPosition = mul(float3x3(objectRight, objectUp, objectForward),finalPosition.xyz);
  272. //                      finalPosition = mul(finalPosition.xyz,float3x3(objectRight.x, objectUp.x, objectForward.x,
  273. //                                                                      objectRight.y, objectUp.y, objectForward.y,
  274. //                                                                      objectRight.z, objectUp.z, objectForward.z));
  275. //                      finalPosition = mul(float3x3(objectRight.x, objectUp.x, objectForward.x,
  276. //                                                                      objectRight.y, objectUp.y, objectForward.y,
  277. //                                                                      objectRight.z, objectUp.z, objectForward.z),
  278. //                                                                      finalPosition.xyz);
  279. //                      finalPosition = mul(finalPosition.xyz,float3x3(objectRight.x, objectRight.y, objectRight.z,
  280. //                                                                      objectUp.x, objectUp.y, objectUp.z,
  281. //                                                                      objectForward.x, objectForward.y, objectForward.z));
  282. //                      finalPosition = mul(float3x3(objectRight.x, objectRight.y, objectRight.z,
  283. //                                                                      objectUp.x, objectUp.y, objectUp.z,
  284. //                                                                      objectForward.x, objectForward.y, objectForward.z),
  285. //                                                                      finalPosition.xyz);
  286.  
  287. //                      finalPosition = normalize(finalPosition) * offsetLen; // make sure the offset vector is still scaled
  288.                     }
  289.                     else
  290.                     {
  291.                         #ifdef LOD_FADE_PERCENTAGE
  292.                             float3 lodPosition = float3(data.texcoord1.w, data.texcoord3.x, data.texcoord3.y);
  293.                             finalPosition = lerp(finalPosition, lodPosition, lodValue);
  294.                         #endif
  295.                     }
  296.  
  297.                     #ifdef ENABLE_WIND
  298.                         // leaf wind
  299.                         if (windQuality > WIND_QUALITY_FASTEST && windQuality < WIND_QUALITY_PALM)
  300.                         {
  301.                             float leafWindTrigOffset = data.texcoord1.x + data.texcoord1.y;
  302.                             finalPosition = LeafWind(windQuality == WIND_QUALITY_BEST, data.texcoord2.w > 0.0, finalPosition, data.normal, data.texcoord2.x, float3(0,0,0), data.texcoord2.y, data.texcoord2.z, leafWindTrigOffset, rotatedWindVector);
  303.                         }
  304.                     #endif
  305.  
  306.                     // move back out to anchor
  307.                     finalPosition += data.texcoord1.xyz;
  308.  
  309.                 #endif
  310.  
  311.                 #ifdef ENABLE_WIND
  312.                     float3 treePos = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
  313.  
  314.                     #ifndef GEOM_TYPE_MESH
  315.                         if (windQuality >= WIND_QUALITY_BETTER)
  316.                         {
  317.                             // branch wind (applies to all 3D geometry)
  318.                             finalPosition = BranchWind(windQuality == WIND_QUALITY_PALM, finalPosition, treePos, float4(data.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
  319.                         }
  320.                     #endif
  321.  
  322.                     if (windQuality > WIND_QUALITY_NONE)
  323.                     {
  324.                         // global wind
  325.                         finalPosition = GlobalWind(finalPosition, treePos, true, rotatedWindVector, _ST_WindGlobal.x);
  326.                     }
  327.                 #endif
  328.  
  329.                 data.vertex.xyz = finalPosition;
  330.             }
  331.  
  332.             void SpeedTreeVertKritoa(inout SpeedTreeVB IN, out Input OUT)
  333.             {
  334.                 UNITY_INITIALIZE_OUTPUT(Input, OUT);
  335.  
  336.                 OUT.mainTexUV = IN.texcoord.xy;
  337.                 OUT.color = _Color;
  338.                 OUT.color.rgb *= IN.color.r; // ambient occlusion factor
  339.  
  340.                 #ifdef EFFECT_HUE_VARIATION
  341.                     float hueVariationAmount = frac(unity_ObjectToWorld[0].w + unity_ObjectToWorld[1].w + unity_ObjectToWorld[2].w);
  342.                     hueVariationAmount += frac(IN.vertex.x + IN.normal.y + IN.normal.x) * 0.5 - 0.3;
  343.                     OUT.HueVariationAmount = saturate(hueVariationAmount * _HueVariation.a);
  344.                 #endif
  345.  
  346.                 #ifdef GEOM_TYPE_BRANCH_DETAIL
  347.                     // The two types are always in different sub-range of the mesh so no interpolation (between detail and blend) problem.
  348.                     OUT.Detail.xy = IN.texcoord2.xy;
  349.                     if (IN.color.a == 0) // Blend
  350.                         OUT.Detail.z = IN.texcoord2.z;
  351.                     else // Detail texture
  352.                         OUT.Detail.z = 2.5f; // stay out of Blend's .z range
  353.                 #endif
  354.  
  355.                 OffsetSpeedTreeVertexKritoa(IN, unity_LODFade.x);
  356.  
  357.                 UNITY_TRANSFER_DITHER_CROSSFADE(OUT, IN.vertex)
  358.             }
  359.  
  360.  
  361.                 struct v2f
  362.                 {
  363.                     V2F_SHADOW_CASTER;
  364.                     #ifdef SPEEDTREE_ALPHATEST
  365.                         float2 uv : TEXCOORD1;
  366.                     #endif
  367.                     UNITY_DITHER_CROSSFADE_COORDS_IDX(2)
  368.                     UNITY_VERTEX_INPUT_INSTANCE_ID
  369.                     UNITY_VERTEX_OUTPUT_STEREO
  370.                 };
  371.  
  372.                 v2f vert(SpeedTreeVB v)
  373.                 {
  374.                     v2f o;
  375.                     UNITY_SETUP_INSTANCE_ID(v);
  376.                     UNITY_TRANSFER_INSTANCE_ID(v, o);
  377.                     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  378.                     #ifdef SPEEDTREE_ALPHATEST
  379.                         o.uv = v.texcoord.xy;
  380.                     #endif
  381.                     OffsetSpeedTreeVertexKritoa(v, unity_LODFade.x);
  382.                     TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
  383.                     UNITY_TRANSFER_DITHER_CROSSFADE_HPOS(o, o.pos)
  384.  
  385.                     return o;
  386.                 }
  387.  
  388.                 float4 frag(v2f i) : SV_Target
  389.                 {
  390.                     UNITY_SETUP_INSTANCE_ID(i);
  391.                     #ifdef SPEEDTREE_ALPHATEST
  392.                         clip(tex2D(_MainTex, i.uv).a * _Color.a - _Cutoff);
  393.                     #endif
  394.                     UNITY_APPLY_DITHER_CROSSFADE(i)
  395.                     SHADOW_CASTER_FRAGMENT(i)
  396.                 }
  397.             ENDCG
  398.         }
  399.  
  400.         Pass
  401.         {
  402.             Tags { "LightMode" = "Vertex" }
  403.  
  404.             CGPROGRAM
  405.                 #pragma vertex vert
  406.                 #pragma fragment frag
  407.                 #pragma target 3.0
  408.                 #pragma multi_compile_fog
  409.                 #pragma multi_compile __ LOD_FADE_PERCENTAGE LOD_FADE_CROSSFADE
  410.                 #pragma multi_compile_instancing
  411.                 #pragma instancing_options assumeuniformscaling lodfade maxcount:50
  412.                 #pragma shader_feature GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
  413.                 #pragma shader_feature EFFECT_HUE_VARIATION
  414.                 #define ENABLE_WIND
  415.                 #include "SpeedTreeCommon.cginc"
  416.  
  417.                 struct v2f
  418.                 {
  419.                     float4 vertex   : SV_POSITION;
  420.                     UNITY_FOG_COORDS(0)
  421.                     Input data      : TEXCOORD1;
  422.                     UNITY_VERTEX_INPUT_INSTANCE_ID
  423.                     UNITY_VERTEX_OUTPUT_STEREO
  424.                 };
  425.  
  426.                 v2f vert(SpeedTreeVB v)
  427.                 {
  428.                     v2f o;
  429.                     UNITY_SETUP_INSTANCE_ID(v);
  430.                     UNITY_TRANSFER_INSTANCE_ID(v, o);
  431.                     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  432.                     SpeedTreeVert(v, o.data);
  433.                     o.data.color.rgb *= ShadeVertexLightsFull(v.vertex, v.normal, 4, true);
  434.                     o.vertex = UnityObjectToClipPos(v.vertex);
  435.                     UNITY_TRANSFER_FOG(o,o.vertex);
  436.                     return o;
  437.                 }
  438.  
  439.                 fixed4 frag(v2f i) : SV_Target
  440.                 {
  441.                     UNITY_SETUP_INSTANCE_ID(i);
  442.                     SpeedTreeFragOut o;
  443.                     SpeedTreeFrag(i.data, o);
  444.                     fixed4 c = fixed4(o.Albedo, o.Alpha);
  445.                     UNITY_APPLY_FOG(i.fogCoord, c);
  446.                     return c;
  447.                 }
  448.             ENDCG
  449.         }
  450.     }
  451.  
  452.     // targeting SM2.0: Cross-fading, Normal-mapping, Hue variation and Wind animation are turned off for less instructions
  453.     SubShader
  454.     {
  455.         Tags
  456.         {
  457.             "Queue"="Geometry"
  458.             "IgnoreProjector"="True"
  459.             "RenderType"="Opaque"
  460.             "DisableBatching"="LODFading"
  461.         }
  462.         LOD 400
  463.         Cull [_Cull]
  464.  
  465.         CGPROGRAM
  466.             #pragma surface surf Lambert vertex:SpeedTreeVertKritoa nodirlightmap nodynlightmap noshadowmask
  467.             #pragma multi_compile __ LOD_FADE_PERCENTAGE
  468.             #pragma shader_feature GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
  469.             #include "SpeedTreeCommon.cginc"
  470.  
  471.                         void OffsetSpeedTreeVertexKritoa(inout SpeedTreeVB data, float lodValue)
  472.             {
  473.                 float3 finalPosition = data.vertex.xyz;
  474.  
  475.                 #ifdef ENABLE_WIND
  476.                     half windQuality = _WindQuality * _WindEnabled;
  477.  
  478.                     float3 rotatedWindVector, rotatedBranchAnchor;
  479.                     if (windQuality <= WIND_QUALITY_NONE)
  480.                     {
  481.                         rotatedWindVector = float3(0.0f, 0.0f, 0.0f);
  482.                         rotatedBranchAnchor = float3(0.0f, 0.0f, 0.0f);
  483.                     }
  484.                     else
  485.                     {
  486.                         // compute rotated wind parameters
  487.                         rotatedWindVector = normalize(mul(_ST_WindVector.xyz, (float3x3)unity_ObjectToWorld));
  488.                         rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)unity_ObjectToWorld)) * _ST_WindBranchAnchor.w;
  489.                     }
  490.                 #endif
  491.  
  492.                 #if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_FROND)
  493.  
  494.                     // smooth LOD
  495.                     #ifdef LOD_FADE_PERCENTAGE
  496.                         finalPosition = lerp(finalPosition, data.texcoord1.xyz, lodValue);
  497.                     #endif
  498.  
  499.                     // frond wind, if needed
  500.                     #if defined(ENABLE_WIND) && defined(GEOM_TYPE_FROND)
  501.                         if (windQuality == WIND_QUALITY_PALM)
  502.                             finalPosition = RippleFrond(finalPosition, data.normal, data.texcoord.x, data.texcoord.y, data.texcoord2.x, data.texcoord2.y, data.texcoord2.z);
  503.                     #endif
  504.  
  505.                 #elif defined(GEOM_TYPE_LEAF)
  506.  
  507.                     // remove anchor position
  508.                     finalPosition -= data.texcoord1.xyz;
  509.  
  510.                     bool isFacingLeaf = data.color.a == 0;
  511.                     if (isFacingLeaf)
  512.                     {
  513.                         #ifdef LOD_FADE_PERCENTAGE
  514.                             finalPosition *= lerp(1.0, data.texcoord1.w, lodValue);
  515.                         #endif
  516.  
  517.                         // face camera-facing leaf to camera
  518. //                      float offsetLen = length(finalPosition);
  519. //                      finalPosition = mul(finalPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * finalPosition    // old camera facing (orients to view matrix, bad!)
  520.  
  521.                         // KRITOA: can't get this to work. Somebody help.
  522.  
  523.                         // orient to camera position with up vector instead now
  524. //                      float3 camPos = _WorldSpaceCameraPos.xyz;
  525. //                      float3 objectOrigin = data.texcoord1.xyz;  //mul(unity_ObjectToWorld, float3(0,0,0));
  526. //                      float3 objectForward = normalize(camPos-objectOrigin);
  527. //                      float3 objectRight = normalize(cross(float3(0,1,0),objectForward));
  528. //                      float3 objectUp = normalize(cross(objectForward,objectRight));
  529. //                      finalPosition = mul(float3x3(objectRight, objectUp, objectForward),finalPosition.xyz);
  530. //                      finalPosition = mul(finalPosition.xyz,float3x3(objectRight.x, objectUp.x, objectForward.x,
  531. //                                                                      objectRight.y, objectUp.y, objectForward.y,
  532. //                                                                      objectRight.z, objectUp.z, objectForward.z));
  533. //                      finalPosition = mul(float3x3(objectRight.x, objectUp.x, objectForward.x,
  534. //                                                                      objectRight.y, objectUp.y, objectForward.y,
  535. //                                                                      objectRight.z, objectUp.z, objectForward.z),
  536. //                                                                      finalPosition.xyz);
  537. //                      finalPosition = mul(finalPosition.xyz,float3x3(objectRight.x, objectRight.y, objectRight.z,
  538. //                                                                      objectUp.x, objectUp.y, objectUp.z,
  539. //                                                                      objectForward.x, objectForward.y, objectForward.z));
  540. //                      finalPosition = mul(float3x3(objectRight.x, objectRight.y, objectRight.z,
  541. //                                                                      objectUp.x, objectUp.y, objectUp.z,
  542. //                                                                      objectForward.x, objectForward.y, objectForward.z),
  543. //                                                                      finalPosition.xyz);
  544.  
  545. //                      finalPosition = normalize(finalPosition) * offsetLen; // make sure the offset vector is still scaled
  546.                     }
  547.                     else
  548.                     {
  549.                         #ifdef LOD_FADE_PERCENTAGE
  550.                             float3 lodPosition = float3(data.texcoord1.w, data.texcoord3.x, data.texcoord3.y);
  551.                             finalPosition = lerp(finalPosition, lodPosition, lodValue);
  552.                         #endif
  553.                     }
  554.  
  555.                     #ifdef ENABLE_WIND
  556.                         // leaf wind
  557.                         if (windQuality > WIND_QUALITY_FASTEST && windQuality < WIND_QUALITY_PALM)
  558.                         {
  559.                             float leafWindTrigOffset = data.texcoord1.x + data.texcoord1.y;
  560.                             finalPosition = LeafWind(windQuality == WIND_QUALITY_BEST, data.texcoord2.w > 0.0, finalPosition, data.normal, data.texcoord2.x, float3(0,0,0), data.texcoord2.y, data.texcoord2.z, leafWindTrigOffset, rotatedWindVector);
  561.                         }
  562.                     #endif
  563.  
  564.                     // move back out to anchor
  565.                     finalPosition += data.texcoord1.xyz;
  566.  
  567.                 #endif
  568.  
  569.                 #ifdef ENABLE_WIND
  570.                     float3 treePos = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
  571.  
  572.                     #ifndef GEOM_TYPE_MESH
  573.                         if (windQuality >= WIND_QUALITY_BETTER)
  574.                         {
  575.                             // branch wind (applies to all 3D geometry)
  576.                             finalPosition = BranchWind(windQuality == WIND_QUALITY_PALM, finalPosition, treePos, float4(data.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
  577.                         }
  578.                     #endif
  579.  
  580.                     if (windQuality > WIND_QUALITY_NONE)
  581.                     {
  582.                         // global wind
  583.                         finalPosition = GlobalWind(finalPosition, treePos, true, rotatedWindVector, _ST_WindGlobal.x);
  584.                     }
  585.                 #endif
  586.  
  587.                 data.vertex.xyz = finalPosition;
  588.             }
  589.  
  590.             void SpeedTreeVertKritoa(inout SpeedTreeVB IN, out Input OUT)
  591.             {
  592.                 UNITY_INITIALIZE_OUTPUT(Input, OUT);
  593.  
  594.                 OUT.mainTexUV = IN.texcoord.xy;
  595.                 OUT.color = _Color;
  596.                 OUT.color.rgb *= IN.color.r; // ambient occlusion factor
  597.  
  598.                 #ifdef EFFECT_HUE_VARIATION
  599.                     float hueVariationAmount = frac(unity_ObjectToWorld[0].w + unity_ObjectToWorld[1].w + unity_ObjectToWorld[2].w);
  600.                     hueVariationAmount += frac(IN.vertex.x + IN.normal.y + IN.normal.x) * 0.5 - 0.3;
  601.                     OUT.HueVariationAmount = saturate(hueVariationAmount * _HueVariation.a);
  602.                 #endif
  603.  
  604.                 #ifdef GEOM_TYPE_BRANCH_DETAIL
  605.                     // The two types are always in different sub-range of the mesh so no interpolation (between detail and blend) problem.
  606.                     OUT.Detail.xy = IN.texcoord2.xy;
  607.                     if (IN.color.a == 0) // Blend
  608.                         OUT.Detail.z = IN.texcoord2.z;
  609.                     else // Detail texture
  610.                         OUT.Detail.z = 2.5f; // stay out of Blend's .z range
  611.                 #endif
  612.  
  613.                 OffsetSpeedTreeVertexKritoa(IN, unity_LODFade.x);
  614.  
  615.                 UNITY_TRANSFER_DITHER_CROSSFADE(OUT, IN.vertex)
  616.             }
  617.  
  618.             void surf(Input IN, inout SurfaceOutput OUT)
  619.             {
  620.                 SpeedTreeFragOut o;
  621.                 SpeedTreeFrag(IN, o);
  622.                 SPEEDTREE_COPY_FRAG(OUT, o)
  623.             }
  624.         ENDCG
  625.  
  626.         Pass
  627.         {
  628.             Tags { "LightMode" = "ShadowCaster" }
  629.  
  630.             CGPROGRAM
  631.                 #pragma vertex vert
  632.                 #pragma fragment frag
  633.                 #pragma multi_compile __ LOD_FADE_PERCENTAGE
  634.                 #pragma shader_feature GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
  635.                 #pragma multi_compile_shadowcaster
  636.                 #include "SpeedTreeCommon.cginc"
  637.  
  638.                             void OffsetSpeedTreeVertexKritoa(inout SpeedTreeVB data, float lodValue)
  639.             {
  640.                 float3 finalPosition = data.vertex.xyz;
  641.  
  642.                 #ifdef ENABLE_WIND
  643.                     half windQuality = _WindQuality * _WindEnabled;
  644.  
  645.                     float3 rotatedWindVector, rotatedBranchAnchor;
  646.                     if (windQuality <= WIND_QUALITY_NONE)
  647.                     {
  648.                         rotatedWindVector = float3(0.0f, 0.0f, 0.0f);
  649.                         rotatedBranchAnchor = float3(0.0f, 0.0f, 0.0f);
  650.                     }
  651.                     else
  652.                     {
  653.                         // compute rotated wind parameters
  654.                         rotatedWindVector = normalize(mul(_ST_WindVector.xyz, (float3x3)unity_ObjectToWorld));
  655.                         rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)unity_ObjectToWorld)) * _ST_WindBranchAnchor.w;
  656.                     }
  657.                 #endif
  658.  
  659.                 #if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_FROND)
  660.  
  661.                     // smooth LOD
  662.                     #ifdef LOD_FADE_PERCENTAGE
  663.                         finalPosition = lerp(finalPosition, data.texcoord1.xyz, lodValue);
  664.                     #endif
  665.  
  666.                     // frond wind, if needed
  667.                     #if defined(ENABLE_WIND) && defined(GEOM_TYPE_FROND)
  668.                         if (windQuality == WIND_QUALITY_PALM)
  669.                             finalPosition = RippleFrond(finalPosition, data.normal, data.texcoord.x, data.texcoord.y, data.texcoord2.x, data.texcoord2.y, data.texcoord2.z);
  670.                     #endif
  671.  
  672.                 #elif defined(GEOM_TYPE_LEAF)
  673.  
  674.                     // remove anchor position
  675.                     finalPosition -= data.texcoord1.xyz;
  676.  
  677.                     bool isFacingLeaf = data.color.a == 0;
  678.                     if (isFacingLeaf)
  679.                     {
  680.                         #ifdef LOD_FADE_PERCENTAGE
  681.                             finalPosition *= lerp(1.0, data.texcoord1.w, lodValue);
  682.                         #endif
  683.  
  684.                         // face camera-facing leaf to camera
  685. //                      float offsetLen = length(finalPosition);
  686. //                      finalPosition = mul(finalPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * finalPosition    // old camera facing (orients to view matrix, bad!)
  687.  
  688.                         //KRITOA: Can't get this to work. Somebody help.
  689.  
  690.                         // orient to camera position with up vector instead now
  691. //                      float3 camPos = _WorldSpaceCameraPos.xyz;
  692. //                      float3 objectOrigin = data.texcoord1.xyz;  //mul(unity_ObjectToWorld, float3(0,0,0));
  693. //                      float3 objectForward = normalize(camPos-objectOrigin);
  694. //                      float3 objectRight = normalize(cross(float3(0,1,0),objectForward));
  695. //                      float3 objectUp = normalize(cross(objectForward,objectRight));
  696. //                      finalPosition = mul(float3x3(objectRight, objectUp, objectForward),finalPosition.xyz);
  697. //                      finalPosition = mul(finalPosition.xyz,float3x3(objectRight.x, objectUp.x, objectForward.x,
  698. //                                                                      objectRight.y, objectUp.y, objectForward.y,
  699. //                                                                      objectRight.z, objectUp.z, objectForward.z));
  700. //                      finalPosition = mul(float3x3(objectRight.x, objectUp.x, objectForward.x,
  701. //                                                                      objectRight.y, objectUp.y, objectForward.y,
  702. //                                                                      objectRight.z, objectUp.z, objectForward.z),
  703. //                                                                      finalPosition.xyz);
  704. //                      finalPosition = mul(finalPosition.xyz,float3x3(objectRight.x, objectRight.y, objectRight.z,
  705. //                                                                      objectUp.x, objectUp.y, objectUp.z,
  706. //                                                                      objectForward.x, objectForward.y, objectForward.z));
  707. //                      finalPosition = mul(float3x3(objectRight.x, objectRight.y, objectRight.z,
  708. //                                                                      objectUp.x, objectUp.y, objectUp.z,
  709. //                                                                      objectForward.x, objectForward.y, objectForward.z),
  710. //                                                                      finalPosition.xyz);
  711.  
  712. //                      finalPosition = normalize(finalPosition) * offsetLen; // make sure the offset vector is still scaled
  713.                     }
  714.                     else
  715.                     {
  716.                         #ifdef LOD_FADE_PERCENTAGE
  717.                             float3 lodPosition = float3(data.texcoord1.w, data.texcoord3.x, data.texcoord3.y);
  718.                             finalPosition = lerp(finalPosition, lodPosition, lodValue);
  719.                         #endif
  720.                     }
  721.  
  722.                     #ifdef ENABLE_WIND
  723.                         // leaf wind
  724.                         if (windQuality > WIND_QUALITY_FASTEST && windQuality < WIND_QUALITY_PALM)
  725.                         {
  726.                             float leafWindTrigOffset = data.texcoord1.x + data.texcoord1.y;
  727.                             finalPosition = LeafWind(windQuality == WIND_QUALITY_BEST, data.texcoord2.w > 0.0, finalPosition, data.normal, data.texcoord2.x, float3(0,0,0), data.texcoord2.y, data.texcoord2.z, leafWindTrigOffset, rotatedWindVector);
  728.                         }
  729.                     #endif
  730.  
  731.                     // move back out to anchor
  732.                     finalPosition += data.texcoord1.xyz;
  733.  
  734.                 #endif
  735.  
  736.                 #ifdef ENABLE_WIND
  737.                     float3 treePos = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
  738.  
  739.                     #ifndef GEOM_TYPE_MESH
  740.                         if (windQuality >= WIND_QUALITY_BETTER)
  741.                         {
  742.                             // branch wind (applies to all 3D geometry)
  743.                             finalPosition = BranchWind(windQuality == WIND_QUALITY_PALM, finalPosition, treePos, float4(data.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
  744.                         }
  745.                     #endif
  746.  
  747.                     if (windQuality > WIND_QUALITY_NONE)
  748.                     {
  749.                         // global wind
  750.                         finalPosition = GlobalWind(finalPosition, treePos, true, rotatedWindVector, _ST_WindGlobal.x);
  751.                     }
  752.                 #endif
  753.  
  754.                 data.vertex.xyz = finalPosition;
  755.             }
  756.  
  757.             void SpeedTreeVertKritoa(inout SpeedTreeVB IN, out Input OUT)
  758.             {
  759.                 UNITY_INITIALIZE_OUTPUT(Input, OUT);
  760.  
  761.                 OUT.mainTexUV = IN.texcoord.xy;
  762.                 OUT.color = _Color;
  763.                 OUT.color.rgb *= IN.color.r; // ambient occlusion factor
  764.  
  765.                 #ifdef EFFECT_HUE_VARIATION
  766.                     float hueVariationAmount = frac(unity_ObjectToWorld[0].w + unity_ObjectToWorld[1].w + unity_ObjectToWorld[2].w);
  767.                     hueVariationAmount += frac(IN.vertex.x + IN.normal.y + IN.normal.x) * 0.5 - 0.3;
  768.                     OUT.HueVariationAmount = saturate(hueVariationAmount * _HueVariation.a);
  769.                 #endif
  770.  
  771.                 #ifdef GEOM_TYPE_BRANCH_DETAIL
  772.                     // The two types are always in different sub-range of the mesh so no interpolation (between detail and blend) problem.
  773.                     OUT.Detail.xy = IN.texcoord2.xy;
  774.                     if (IN.color.a == 0) // Blend
  775.                         OUT.Detail.z = IN.texcoord2.z;
  776.                     else // Detail texture
  777.                         OUT.Detail.z = 2.5f; // stay out of Blend's .z range
  778.                 #endif
  779.  
  780.                 OffsetSpeedTreeVertexKritoa(IN, unity_LODFade.x);
  781.  
  782.                 UNITY_TRANSFER_DITHER_CROSSFADE(OUT, IN.vertex)
  783.             }
  784.  
  785.                 struct v2f
  786.                 {
  787.                     V2F_SHADOW_CASTER;
  788.                     #ifdef SPEEDTREE_ALPHATEST
  789.                         float2 uv : TEXCOORD1;
  790.                     #endif
  791.                 };
  792.  
  793.                 v2f vert(SpeedTreeVB v)
  794.                 {
  795.                     v2f o;
  796.                     #ifdef SPEEDTREE_ALPHATEST
  797.                         o.uv = v.texcoord.xy;
  798.                     #endif
  799.                     OffsetSpeedTreeVertexKritoa(v, unity_LODFade.x);
  800.                     TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
  801.                     return o;
  802.                 }
  803.  
  804.                 float4 frag(v2f i) : SV_Target
  805.                 {
  806.                     #ifdef SPEEDTREE_ALPHATEST
  807.                         clip(tex2D(_MainTex, i.uv).a * _Color.a - _Cutoff);
  808.                     #endif
  809.                     SHADOW_CASTER_FRAGMENT(i)
  810.                 }
  811.             ENDCG
  812.         }
  813.  
  814.         Pass
  815.         {
  816.             Tags { "LightMode" = "Vertex" }
  817.  
  818.             CGPROGRAM
  819.                 #pragma vertex vert
  820.                 #pragma fragment frag
  821.                 #pragma multi_compile_fog
  822.                 #pragma multi_compile __ LOD_FADE_PERCENTAGE
  823.                 #pragma shader_feature GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
  824.                 #include "SpeedTreeCommon.cginc"
  825.  
  826.                 struct v2f
  827.                 {
  828.                     float4 vertex   : SV_POSITION;
  829.                     UNITY_FOG_COORDS(0)
  830.                     Input data      : TEXCOORD1;
  831.                     UNITY_VERTEX_OUTPUT_STEREO
  832.                 };
  833.  
  834.                 v2f vert(SpeedTreeVB v)
  835.                 {
  836.                     v2f o;
  837.                     UNITY_SETUP_INSTANCE_ID(v);
  838.                     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  839.                     SpeedTreeVert(v, o.data);
  840.                     o.data.color.rgb *= ShadeVertexLightsFull(v.vertex, v.normal, 2, false);
  841.                     o.vertex = UnityObjectToClipPos(v.vertex);
  842.                     UNITY_TRANSFER_FOG(o,o.vertex);
  843.                     return o;
  844.                 }
  845.  
  846.                 fixed4 frag(v2f i) : SV_Target
  847.                 {
  848.                     SpeedTreeFragOut o;
  849.                     SpeedTreeFrag(i.data, o);
  850.                     fixed4 c = fixed4(o.Albedo, o.Alpha);
  851.                     UNITY_APPLY_FOG(i.fogCoord, c);
  852.                     return c;
  853.                 }
  854.             ENDCG
  855.         }
  856.     }
  857.  
  858.     FallBack "Transparent/Cutout/VertexLit"
  859.     CustomEditor "SpeedTreeMaterialInspector"
  860. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top