Advertisement
Guest User

Untitled

a guest
Jun 13th, 2019
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
  2.  
  3. Shader "Roystan/Grass"
  4. {
  5.     Properties
  6.     {
  7.         [Header(Shading)]
  8.         _TopColor("Top Color", Color) = (1,1,1,1)
  9.         _BottomColor("Bottom Color", Color) = (1,1,1,1)
  10.         _ColorMap("Color Map", 2D) = "white" {}
  11.         _TranslucentGain("Translucent Gain", Range(0,1)) = 0.5
  12.         [Space]
  13.         _TessellationUniform ("Tessellation Uniform", Range(1, 64)) = 1
  14.         [Header(Blades)]
  15.         _BladeWidth("Blade Width", Float) = 0.05
  16.         _BladeWidthRandom("Blade Width Random", Float) = 0.02
  17.         _BladeHeight("Blade Height", Float) = 0.5
  18.         _BladeHeightRandom("Blade Height Random", Float) = 0.3
  19.         _BladeForward("Blade Forward Amount", Float) = 0.38
  20.         _BladeCurve("Blade Curvature Amount", Range(1, 4)) = 2
  21.         _BendRotationRandom("Bend Rotation Random", Range(0, 1)) = 0.2
  22.         [Header(Wind)]
  23.         _WindDistortionMap("Wind Distortion Map", 2D) = "white" {}
  24.         _WindStrength("Wind Strength", Float) = 1
  25.         _WindFrequency("Wind Frequency", Vector) = (0.05, 0.05, 0, 0)
  26.     }
  27.  
  28.     CGINCLUDE
  29.     #include "UnityCG.cginc"
  30.     #include "Autolight.cginc"
  31.     #include "CustomTessellation.cginc"
  32.    
  33.     struct geometryOutput
  34.     {
  35.         float4 pos : SV_POSITION;
  36.     #if UNITY_PASS_FORWARDBASE     
  37.         float3 normal : NORMAL;
  38.         float2 uv : TEXCOORD0;
  39.         // unityShadowCoord4 is defined as a float4 in UnityShadowLibrary.cginc.
  40.         unityShadowCoord4 _ShadowCoord : TEXCOORD1;
  41.     #endif
  42.     };
  43.  
  44.     struct secondGeometryOutput {
  45.         float4 wPos : POSITION2;
  46.     };
  47.  
  48.     // Simple noise function, sourced from http://answers.unity.com/answers/624136/view.html
  49.     // Extended discussion on this function can be found at the following link:
  50.     // https://forum.unity.com/threads/am-i-over-complicating-this-random-function.454887/#post-2949326
  51.     // Returns a number in the 0...1 range.
  52.     float rand(float3 co)
  53.     {
  54.         return frac(sin(dot(co.xyz, float3(12.9898, 78.233, 53.539))) * 43758.5453);
  55.     }
  56.  
  57.     // Construct a rotation matrix that rotates around the provided axis, sourced from:
  58.     // https://gist.github.com/keijiro/ee439d5e7388f3aafc5296005c8c3f33
  59.     float3x3 AngleAxis3x3(float angle, float3 axis)
  60.     {
  61.         float c, s;
  62.         sincos(angle, s, c);
  63.  
  64.         float t = 1 - c;
  65.         float x = axis.x;
  66.         float y = axis.y;
  67.         float z = axis.z;
  68.  
  69.         return float3x3(
  70.             t * x * x + c, t * x * y - s * z, t * x * z + s * y,
  71.             t * x * y + s * z, t * y * y + c, t * y * z - s * x,
  72.             t * x * z - s * y, t * y * z + s * x, t * z * z + c
  73.             );
  74.     }
  75.  
  76.     geometryOutput VertexOutput(float3 pos, float3 normal, float2 uv)
  77.     {
  78.         geometryOutput o;
  79.  
  80.         o.pos = UnityObjectToClipPos(pos);
  81.  
  82.     #if UNITY_PASS_FORWARDBASE
  83.         o.normal = UnityObjectToWorldNormal(normal);
  84.         o.uv = uv;
  85.         // Shadows are sampled from a screen-space shadow map texture.
  86.         o._ShadowCoord = ComputeScreenPos(o.pos);
  87.     #elif UNITY_PASS_SHADOWCASTER
  88.         // Applying the bias prevents artifacts from appearing on the surface.
  89.         o.pos = UnityApplyLinearShadowBias(o.pos);
  90.     #endif
  91.  
  92.         return o;
  93.     }
  94.  
  95.     geometryOutput GenerateGrassVertex(float3 vertexPosition, float width, float height, float forward, float2 uv, float3x3 transformMatrix)
  96.     {
  97.         float3 tangentPoint = float3(width, forward, height);
  98.  
  99.         float3 tangentNormal = normalize(float3(0, -1, forward));
  100.  
  101.         float3 localPosition = vertexPosition + mul(transformMatrix, tangentPoint);
  102.         float3 localNormal = mul(transformMatrix, tangentNormal);
  103.         return VertexOutput(localPosition, localNormal, uv);
  104.     }
  105.  
  106.     secondGeometryOutput GetVertexPositionInFrag(float3 vertexPosition) {
  107.         secondGeometryOutput o;
  108.         o.wPos = float4(vertexPosition, 0);
  109.         return o;
  110.     }
  111.  
  112.     float _BladeHeight;
  113.     float _BladeHeightRandom;
  114.  
  115.     float _BladeWidthRandom;
  116.     float _BladeWidth;
  117.  
  118.     float _BladeForward;
  119.     float _BladeCurve;
  120.  
  121.     float _BendRotationRandom;
  122.  
  123.     sampler2D _WindDistortionMap;
  124.     float4 _WindDistortionMap_ST;
  125.  
  126.     float _WindStrength;
  127.     float2 _WindFrequency;
  128.  
  129.     #define BLADE_SEGMENTS 3
  130.  
  131.     // Geometry program that takes in a single vertex and outputs a blade
  132.     // of grass at that vertex's position, aligned to the vertex's normal.
  133.     [maxvertexcount(BLADE_SEGMENTS * 2 + 1)]
  134.     void geo(point vertexOutput IN[1], inout TriangleStream<geometryOutput> triStream)
  135.     {
  136.         float3 pos = IN[0].vertex.xyz;
  137.  
  138.         // Each blade of grass is constructed in tangent space with respect
  139.         // to the emitting vertex's normal and tangent vectors, where the width
  140.         // lies along the X axis and the height along Z.
  141.  
  142.         // Construct random rotations to point the blade in a direction.
  143.         float3x3 facingRotationMatrix = AngleAxis3x3(rand(pos) * UNITY_TWO_PI, float3(0, 0, 1));
  144.         // Matrix to bend the blade in the direction it's facing.
  145.         float3x3 bendRotationMatrix = AngleAxis3x3(rand(pos.zzx) * _BendRotationRandom * UNITY_PI * 0.5, float3(-1, 0, 0));
  146.  
  147.         // Sample the wind distortion map, and construct a normalized vector of its direction.
  148.         float2 uv = pos.xz * _WindDistortionMap_ST.xy + _WindDistortionMap_ST.zw + _WindFrequency * _Time.y;
  149.         float2 windSample = (tex2Dlod(_WindDistortionMap, float4(uv, 0, 0)).xy * 2 - 1) * _WindStrength;
  150.         float3 wind = normalize(float3(windSample.x, windSample.y, 0));
  151.  
  152.         float3x3 windRotation = AngleAxis3x3(UNITY_PI * windSample, wind);
  153.  
  154.         // Construct a matrix to transform our blade from tangent space
  155.         // to local space; this is the same process used when sampling normal maps.
  156.         float3 vNormal = IN[0].normal;
  157.         float4 vTangent = IN[0].tangent;
  158.         float3 vBinormal = cross(vNormal, vTangent) * vTangent.w;
  159.  
  160.         float3x3 tangentToLocal = float3x3(
  161.             vTangent.x, vBinormal.x, vNormal.x,
  162.             vTangent.y, vBinormal.y, vNormal.y,
  163.             vTangent.z, vBinormal.z, vNormal.z
  164.             );
  165.  
  166.         // Construct full tangent to local matrix, including our rotations.
  167.         // Construct a second matrix with only the facing rotation; this will be used
  168.         // for the root of the blade, to ensure it always faces the correct direction.
  169.         float3x3 transformationMatrix = mul(mul(mul(tangentToLocal, windRotation), facingRotationMatrix), bendRotationMatrix);
  170.         float3x3 transformationMatrixFacing = mul(tangentToLocal, facingRotationMatrix);
  171.  
  172.         float height = (rand(pos.zyx) * 2 - 1) * _BladeHeightRandom + _BladeHeight;
  173.         float width = (rand(pos.xzy) * 2 - 1) * _BladeWidthRandom + _BladeWidth;
  174.         float forward = rand(pos.yyz) * _BladeForward;
  175.  
  176.         for (int i = 0; i < BLADE_SEGMENTS; i++)
  177.         {
  178.             float t = i / (float)BLADE_SEGMENTS;
  179.  
  180.             float segmentHeight = height * t;
  181.             float segmentWidth = width * (1 - t);
  182.             float segmentForward = pow(t, _BladeCurve) * forward;
  183.  
  184.             // Select the facing-only transformation matrix for the root of the blade.
  185.             float3x3 transformMatrix = i == 0 ? transformationMatrixFacing : transformationMatrix;
  186.  
  187.             triStream.Append(GenerateGrassVertex(pos, segmentWidth, segmentHeight, segmentForward, float2(0, t), transformMatrix));
  188.             triStream.Append(GenerateGrassVertex(pos, -segmentWidth, segmentHeight, segmentForward, float2(1, t), transformMatrix));
  189.             GetVertexPositionInFrag(IN[0].vertex.xyz);
  190.         }
  191.  
  192.         // Add the final vertex as the tip.
  193.         triStream.Append(GenerateGrassVertex(pos, 0, height, forward, float2(0.5, 1), transformationMatrix));
  194.     }
  195.     ENDCG
  196.  
  197.     SubShader
  198.     {
  199.         Cull Off
  200.  
  201.         Pass
  202.         {
  203.             Tags
  204.             {
  205.                 "RenderType" = "Opaque"
  206.                 "LightMode" = "ForwardBase"
  207.             }
  208.  
  209.             CGPROGRAM
  210.             #pragma vertex vert
  211.             #pragma geometry geo
  212.             #pragma fragment frag
  213.             #pragma hull hull
  214.             #pragma domain domain
  215.             #pragma target 4.6
  216.             #pragma multi_compile_fwdbase
  217.            
  218.             #include "Lighting.cginc"
  219.  
  220.             float4 _TopColor;
  221.             float4 _BottomColor;
  222.             float _TranslucentGain;
  223.             sampler2D _ColorMap;
  224.             uniform float4 _ColorMap_ST;
  225.  
  226.             float4 frag (geometryOutput i, secondGeometryOutput o,  fixed facing : VFACE) : SV_Target
  227.             {          
  228.                 float3 normal = facing > 0 ? i.normal : -i.normal;
  229.  
  230.                 float shadow = SHADOW_ATTENUATION(i);
  231.                 float NdotL = saturate(saturate(dot(normal, _WorldSpaceLightPos0)) + _TranslucentGain) * shadow;
  232.  
  233.                 float3 ambient = ShadeSH9(float4(normal, 1));
  234.                 float4 lightIntensity = NdotL * _LightColor0 + float4(ambient, 1);
  235.                 float3 verPos = mul (unity_ObjectToWorld, o.wPos).xyz;
  236.                 //float4 col = lerp(_BottomColor, _TopColor * lightIntensity, i.uv.y) * tex2D(_ColorMap, verPos.xz/_ColorMap_ST.xy);
  237.                 float4 col = lerp(_BottomColor, _TopColor * lightIntensity, i.uv.y) * tex2D(_ColorMap, float2(fmod(verPos.x * _ColorMap_ST.x, 1), fmod(verPos.z * _ColorMap_ST.y, 1)));
  238.  
  239.                 return col;
  240.             }
  241.             ENDCG
  242.         }
  243.  
  244.         Pass
  245.         {
  246.             Tags
  247.             {
  248.                 "LightMode" = "ShadowCaster"
  249.             }
  250.  
  251.             CGPROGRAM
  252.             #pragma vertex vert
  253.             #pragma geometry geo
  254.             #pragma fragment frag
  255.             #pragma hull hull
  256.             #pragma domain domain
  257.             #pragma target 4.6
  258.             #pragma multi_compile_shadowcaster
  259.  
  260.             float4 frag(geometryOutput i) : SV_Target
  261.             {
  262.                 SHADOW_CASTER_FRAGMENT(i)
  263.             }
  264.  
  265.             ENDCG
  266.         }
  267.     }
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement