YetAnotherProblem

Grass shader

Mar 3rd, 2019
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Shader "Custom/GrassShader"
  2. {
  3.     Properties
  4.     {
  5.         size("Width", Float) = 0.1
  6.         [Header(Height)]
  7.         amplitude ("   Amplitude", Range(0, 1)) = 0.25
  8.         height("   Height", Float) = 1
  9.         [Header(Frequency)]
  10.         chance("   Spawn chance", Range(0, 1)) = 0.75
  11.         subdivisions("   Subdivisions", Int) = 1
  12.         [Header(Wind)]
  13.         flexibility("   Flexibitity", Range(0, 1)) = 0.5
  14.         wind ("   Wind direction", Vector) = (0, 0, 0)
  15.         col ("Color", Color) = (1, 1, 1, 1)
  16.     }
  17.     SubShader
  18.     {
  19.  
  20.         Tags { "LightMode" = "ForwardBase" }
  21.         LOD 100
  22.  
  23.         Pass
  24.         {
  25.             CGPROGRAM
  26.             #pragma target 4.6
  27.             #pragma vertex vert
  28.             #pragma geometry geom
  29.             #pragma fragment frag
  30.             #pragma hull hull
  31.             #pragma domain domain
  32.             #define LEVELS 4
  33.             #define E 2.71828182845904523536
  34.             #include "UnityCG.cginc"
  35.             #include "UnityLightingCommon.cginc"
  36.             #include "Subsurf.cginc"
  37.  
  38.             struct appdata
  39.             {
  40.                 float4 vertex : POSITION;
  41.                 float2 uv : TEXCOORD0;
  42.                 float3 normal : NORMAL;
  43.             };
  44.  
  45.             struct g2f
  46.             {
  47.                 float2 uv : TEXCOORD0;
  48.                 float4 vertex : SV_POSITION;
  49.                 float4 light : COLOR0;
  50.             };
  51.  
  52.             v2h vert(appdata v)
  53.             {
  54.                 v2h o;
  55.                 o.vertex = v.vertex;
  56.                 o.uv = v.uv;
  57.                 o.normal = v.normal;
  58.                 return o;
  59.             }
  60.  
  61.             float fract(float n) {
  62.                 return n - floor(n);
  63.             }
  64.  
  65.             g2f toG2F(v2h inp, float3 pos, float4 diffuse) {
  66.                 g2f o;
  67.                 o.uv = inp.uv;
  68.                 o.vertex = UnityObjectToClipPos(pos);
  69.                 o.light = diffuse;
  70.                 return o;
  71.             }
  72.  
  73.             float size;
  74.             float height;
  75.             float3 wind;
  76.             float chance;
  77.             float flexibility;
  78.             float amplitude;
  79.             float4 col;
  80.  
  81.             float4 diffuse(float3 a, float3 b, float3 c) {
  82.                 float3 normal = UnityObjectToWorldNormal(normalize(cross(b - a, c - a)));
  83.                 float4 o = max(0, dot(normal, _WorldSpaceLightPos0.xyz)) * _LightColor0;
  84.                 return o;
  85.             }
  86.  
  87.             float th(float x) {
  88.                 float a = pow(E, 2 * x);
  89.                 return (a - 1) / (a + 1);
  90.             }
  91.             float rand(float2 co) {
  92.                 return abs(fract(sin(dot(co.xy, float2(12.9898, 78.233))) * 43758.5453));
  93.             }
  94.             float rand2(float rnd) {
  95.                 return fract(sin(rnd)*100000.0);
  96.             }
  97.  
  98.             [maxvertexcount(18*LEVELS)]
  99.             void geom(point v2h inp[1], inout TriangleStream<g2f> tristream) {
  100.                 float rnd = rand(inp[0].vertex.xz);
  101.                 if(rnd > chance)
  102.                     return;
  103.                 rnd /= chance;
  104.                 float3 vec = inp[0].normal;
  105.                 //Ambient calculation. Always returns the same value!
  106.                 float3 ambient = ShadeSH9(float4(UnityObjectToWorldNormal(vec), 1));
  107.                 height = (height+height*(rnd-0.5)*2*amplitude) / (LEVELS - 1);
  108.                 float3 base = inp[0].vertex;
  109.                 float3 root[3] = {
  110.                     float3(0, 0, 0),
  111.                     float3(0, 0, 0),
  112.                     float3(0, 0, 0)
  113.                 };
  114.                 float2 troff[3] = { float2(0, 0), float2(0, 0), float2(0,0) };
  115.                 {
  116.                     float sqr = sqrt(0.75);
  117.                     troff[0] = float2(1, 0);
  118.                     troff[1] = normalize(float2(-0.5, -sqr));
  119.                     troff[2] = normalize(float2(-0.5, sqr));
  120.                 }
  121.                 {
  122.                     rnd = rand2(rnd);
  123.                     float alpha = rnd*UNITY_PI*2;
  124.                     float sina = sin(alpha);
  125.                     float cosa = cos(alpha);
  126.                     float3x3 rotation = {
  127.                         cosa, -sina, 0,
  128.                         sina, cosa, 0,
  129.                         0, 0, 1
  130.                     };
  131.                     for (int i = 0; i < 3; i++)
  132.                         troff[i] = mul(troff[i], rotation);
  133.                     rnd = rand2(rnd);
  134.                     wind = normalize(lerp(vec, wind + mul(float3(rnd, 0, 0), rotation), flexibility));
  135.                 }
  136.                 for (int i = 0; i < LEVELS; i++) {
  137.                     float prog = (i+.5)/LEVELS;
  138.                     float TH = th((prog - 0.5)*2.5) / 2;
  139.                     float3 dir = lerp(vec, wind, prog);
  140.                     float3 nbase = 0;
  141.                     float3 tr[3] = {
  142.                         float3(0, 0, 0),
  143.                         float3(0, 0, 0),
  144.                         float3(0, 0, 0)
  145.                     };
  146.                     bool last = i + 1 == LEVELS;
  147.                     if (last)
  148.                         for(int j = 0; j < 3; j++)
  149.                             tr[j] = base;
  150.                     else {
  151.                         for (int j = 0; j < 3; j++) {
  152.                             float3 vert = float3(
  153.                                 troff[j].x,
  154.                                 -((dir.x*troff[j].x + dir.z*troff[j].y) / dir.y),
  155.                                 troff[j].y
  156.                                 )* size * (0.5-TH) + base;
  157.                             nbase += vert;
  158.                             tr[j] = vert;
  159.                         }
  160.                     }
  161.                     if (i > 0) {
  162.                         for (uint j = 0; j < 3; j++) {
  163.                             int id = (j + 1) % 3;
  164.                             float4 diff = diffuse(tr[j], root[j], root[id]);
  165.                             diff.rgb = ambient; // += ambient
  166.                             tristream.Append(toG2F(inp[0], tr[j], diff));
  167.                             tristream.Append(toG2F(inp[0], root[j], diff));
  168.                             tristream.Append(toG2F(inp[0], root[id], diff));
  169.                             tristream.RestartStrip();
  170.                             id = (j + 2) % 3;
  171.                             diff = diffuse(tr[j], tr[id], root[j]);
  172.                             diff.rgb = ambient; // += ambient
  173.                             tristream.Append(toG2F(inp[0], tr[j], diff));
  174.                             tristream.Append(toG2F(inp[0], tr[id], diff));
  175.                             tristream.Append(toG2F(inp[0], root[j], diff));
  176.                             tristream.RestartStrip();
  177.                         }
  178.                     }
  179.                     root = tr;
  180.                     base = nbase / 3 + dir * height * (pow(prog * 2 - 1, 2) * 0.5 + 0.5);
  181.                 }
  182.             }
  183.  
  184.  
  185.            
  186.             fixed4 frag (g2f i) : SV_Target
  187.             {
  188.                 return i.light;// *col;
  189.             }
  190.             ENDCG
  191.         }
  192.     }
  193. }
Add Comment
Please, Sign In to add comment