Advertisement
remo9211

L2 BIRP Grass

May 20th, 2024
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Godot GLSL 12.08 KB | Source Code | 0 0
  1. Shader "BIRP/Grass_TesUpgrade"{
  2.     Properties{
  3.         [Header(Shading)]
  4.         _TopColor("Top Color", Color) = (0.1261,1,0,1)
  5.         _BottomColor("Bottom Color", Color) = (0.1544,0.4404,0.0429,1)
  6.         _TranslucentGain("Translucent Gain", Range(0,1)) = 0.5
  7.  
  8.         _BendRotationRandom("Bend Rotation Random", Range(0, 1)) = 0.4
  9.  
  10.         _BladeWidth("Blade Width", Float) = 0.07
  11.         _BladeWidthRandom("Blade Width Random", Float) = 0.02
  12.         _BladeHeight("Blade Height", Float) = 1.2
  13.         _BladeHeightRandom("Blade Height Random", Float) = 0.09
  14.  
  15.         [KeywordEnum(INTEGER, FRAC_EVEN, FRAC_ODD, POW2)] _PARTITIONING("Partition algoritm", Int) = 0
  16.         [KeywordEnum(FIXED, SCREEN_BASE, WORLD_BASE)] _DYNAMIC("Dynamic Partition Mode", Int) = 0
  17.         _TessellationFactor_FIXED("Tessellation FIXED", Range(1, 8)) = 1
  18.         _TessellationFactor_SCREEN_BASE("Tessellation SCREEN_BASE", Range(0.01, 8)) = 0.05
  19.         _TessellationFactor_WORLD_BASE("Tessellation WORLD_BASE", Range(0.01, 8)) = 0.08
  20.  
  21.  
  22.         _WindDistortionMap("Wind Distortion Map", 2D) = "white" {}
  23.         _WindFrequency("Wind Frequency", Vector) = (0.05, 0.05, 0, 0)
  24.  
  25.         _WindStrength("Wind Strength", Float) = 1
  26.  
  27.         _BladeForward("Blade Forward Amount", Float) = 0.38
  28.         _BladeCurve("Blade Curvature Amount", Range(1, 4)) = 2
  29.  
  30.         [KeywordEnum(TRUE, FALSE)] _CUTTESS("Cut Tess", Int) = 0
  31.     }
  32.  
  33.     SubShader{
  34.         Cull Off
  35.         CGINCLUDE
  36.             #pragma vertex vert
  37.             #pragma fragment frag
  38.             #pragma hull hull
  39.             #pragma domain domain
  40.             #pragma geometry geo
  41.             #pragma target 5.0
  42.             #pragma multi_compile_fwdbase
  43.                    
  44.             #pragma shader_feature_local _PARTITIONING_INTEGER _PARTITIONING_FRAC_EVEN _PARTITIONING_FRAC_ODD _PARTITIONING_POW2
  45.             #pragma shader_feature_local _CUTTESS_TRUE _CUTTESS_FALSE
  46.             #pragma shader_feature_local _DYNAMIC_FIXED _DYNAMIC_SCREEN_BASE _DYNAMIC_WORLD_BASE
  47.             #include "UnityCG.cginc"
  48.             #include "Autolight.cginc"
  49.  
  50.             #define BLADE_SEGMENTS 3
  51.  
  52.             float _BendRotationRandom;
  53.  
  54.             float _BladeHeight;
  55.             float _BladeHeightRandom;  
  56.             float _BladeWidth;
  57.             float _BladeWidthRandom;
  58.  
  59.             sampler2D _WindDistortionMap;
  60.             float4 _WindDistortionMap_ST;
  61.  
  62.             float2 _WindFrequency;
  63.             float _WindStrength;
  64.  
  65.             float _BladeForward;
  66.             float _BladeCurve;
  67.  
  68.             float _TessellationFactor_FIXED;
  69.             float _TessellationFactor_SCREEN_BASE;
  70.             float _TessellationFactor_WORLD_BASE;
  71.  
  72.             struct Attributes
  73.             {
  74.                 float4 vertex : POSITION;
  75.                 float3 normal : NORMAL;
  76.                 float4 tangent : TANGENT;
  77.             };
  78.             struct TessellationControlPoint
  79.             {
  80.                 float4 vertex : INTERNALTESSPOS;
  81.                 float3 normal : NORMAL;
  82.                 float4 tangent : TANGENT;
  83.                 float4 positionCS : SV_POSITION;
  84.             };
  85.             struct Interpolators
  86.             {
  87.                 float4 vertex : POSITION;
  88.                 float3 normal : NORMAL;
  89.                 float4 tangent : TANGENT;
  90.             };
  91.             struct TessellationFactors
  92.             {
  93.                 float edge[3] : SV_TessFactor;
  94.                 float inside : SV_InsideTessFactor;
  95.             };
  96.             struct geometryOutput{
  97.                 float4 pos : SV_POSITION;
  98.                 float2 uv : TEXCOORD0;
  99.                 unityShadowCoord4 _ShadowCoord : TEXCOORD1;
  100.                 float3 normal : NORMAL;
  101.             };
  102.  
  103.             float rand(float3 co){
  104.                 return frac(sin(dot(co.xyz, float3(12.9898, 78.233, 53.539))) * 43758.5453);
  105.             }
  106.             float3x3 AngleAxis3x3(float angle, float3 axis){
  107.                 float c, s;
  108.                 sincos(angle, s, c);
  109.                 float t = 1 - c;  float x = axis.x;
  110.                 float y = axis.y; float z = axis.z;
  111.                 return float3x3(
  112.                     t * x * x + c, t * x * y - s * z, t * x * z + s * y,
  113.                     t * x * y + s * z, t * y * y + c, t * y * z - s * x,
  114.                     t * x * z - s * y, t * y * z + s * x, t * z * z + c
  115.                     );
  116.             }
  117.             bool IsOutOfBounds(float3 p, float3 lower, float3 higher) { //给定矩形判断
  118.                 return p.x < lower.x || p.x > higher.x || p.y < lower.y || p.y > higher.y || p.z < lower.z || p.z > higher.z;
  119.             }
  120.             bool IsPointOutOfFrustum(float4 positionCS) { //视锥体判断
  121.                 float3 culling = positionCS.xyz;
  122.                 float w = positionCS.w;
  123.                 float3 lowerBounds = float3(-w, -w, -w * _ProjectionParams.z);
  124.                 float3 higherBounds = float3(w, w, w);
  125.                 return IsOutOfBounds(culling, lowerBounds, higherBounds);
  126.             }
  127.             bool ShouldClipPatch(float4 p0PositionCS, float4 p1PositionCS, float4 p2PositionCS) {
  128.                 bool allOutside = IsPointOutOfFrustum(p0PositionCS) &&
  129.                     IsPointOutOfFrustum(p1PositionCS) &&
  130.                     IsPointOutOfFrustum(p2PositionCS);
  131.                 return allOutside;
  132.             }
  133.             // 生成草的具體座標, 草的寬度, 草的高度, 草的朝向, uv傳遞, 變換矩陣
  134.             geometryOutput GenerateGrassVertex(float3 vertexPosition, float width, float height, float forward, float2 uv, float3x3 transformMatrix) {
  135.                 float3 tangentPoint = float3(width, forward, height);
  136.                 float3 localPosition = vertexPosition + mul(transformMatrix, tangentPoint);
  137.                 float3 tangentNormal = normalize(float3(0, -1, forward));
  138.                 float3 localNormal = mul(transformMatrix, tangentNormal);
  139.                 geometryOutput o;
  140.                 o.pos = UnityObjectToClipPos(localPosition);
  141.                 #if UNITY_PASS_SHADOWCASTER
  142.                     o.pos = UnityApplyLinearShadowBias(o.pos);
  143.                 #endif
  144.                 o.uv = uv;
  145.                 o._ShadowCoord = ComputeScreenPos(o.pos);
  146.                 o.normal = UnityObjectToWorldNormal(localNormal);
  147.                 return o;
  148.             }
  149.             float EdgeTessellationFactor_ScreenBase(float scale, float4 p0PositionCS, float4 p1PositionCS) {
  150.                 float factor = distance(p0PositionCS.xyz / p0PositionCS.w, p1PositionCS.xyz / p1PositionCS.w);
  151.                 return max(1, factor / scale);
  152.             }
  153.             float EdgeTessellationFactor_WorldBase(float scale, float3 p0PositionWS, float3 p1PositionWS) {
  154.                 float length = distance(p0PositionWS, p1PositionWS);
  155.                 float distanceToCamera = distance(_WorldSpaceCameraPos, (p0PositionWS + p1PositionWS) * 0.5);
  156.                 // 使用平方根函数调整距离的影响,使中距离的镶嵌因子变化更平滑
  157.                 float adjustedDistance = sqrt(distanceToCamera);
  158.                 float factor = length / (scale * adjustedDistance);
  159.                 return max(1, factor);
  160.             }
  161.  
  162.  
  163.             TessellationControlPoint vert(Attributes v)
  164.             {
  165.                 TessellationControlPoint o;
  166.                 o.vertex        = v.vertex;
  167.                 o.normal        = v.normal;
  168.                 o.tangent       = v.tangent;
  169.                 o.positionCS = UnityObjectToClipPos(v.vertex);
  170.                 return o;
  171.             }
  172.  
  173.             TessellationFactors patchConstantFunction (InputPatch<TessellationControlPoint, 3> patch)
  174.             {
  175.                 TessellationFactors f;
  176.                 #if defined(_DYNAMIC_FIXED)
  177.                     f.edge[0] = _TessellationFactor_FIXED;
  178.                     f.edge[1] = _TessellationFactor_FIXED;
  179.                     f.edge[2] = _TessellationFactor_FIXED;
  180.                     f.inside = _TessellationFactor_FIXED;
  181.                 #elif defined(_DYNAMIC_SCREEN_BASE)
  182.                     f.edge[0] = EdgeTessellationFactor_ScreenBase(_TessellationFactor_SCREEN_BASE,
  183.                         patch[1].positionCS, patch[2].positionCS);
  184.                     f.edge[1] = EdgeTessellationFactor_ScreenBase(_TessellationFactor_SCREEN_BASE,
  185.                         patch[2].positionCS, patch[0].positionCS);
  186.                     f.edge[2] = EdgeTessellationFactor_ScreenBase(_TessellationFactor_SCREEN_BASE,
  187.                         patch[0].positionCS, patch[1].positionCS);
  188.                     f.inside = (f.edge[0] + f.edge[1] + f.edge[2]) / 3.0;
  189.                 #elif defined(_DYNAMIC_WORLD_BASE)
  190.                     f.edge[0] = EdgeTessellationFactor_WorldBase(_TessellationFactor_WORLD_BASE,
  191.                         patch[1].vertex, patch[2].vertex);
  192.                     f.edge[1] = EdgeTessellationFactor_WorldBase(_TessellationFactor_WORLD_BASE,
  193.                         patch[2].vertex, patch[0].vertex);
  194.                     f.edge[2] = EdgeTessellationFactor_WorldBase(_TessellationFactor_WORLD_BASE,
  195.                         patch[0].vertex, patch[1].vertex);
  196.                     f.inside = (f.edge[0] + f.edge[1] + f.edge[2]) / 3.0;
  197.                 #else
  198.                     f.edge[0] = _TessellationFactor_FIXED;
  199.                     f.edge[1] = _TessellationFactor_FIXED;
  200.                     f.edge[2] = _TessellationFactor_FIXED;
  201.                     f.inside = _TessellationFactor_FIXED;
  202.                 #endif
  203.  
  204.                 #if defined(_CUTTESS_TRUE)
  205.                     if(ShouldClipPatch(patch[0].positionCS, patch[1].positionCS, patch[2].positionCS))
  206.                         f.edge[0] = f.edge[1] = f.edge[2] = f.inside = 0;
  207.                 #endif
  208.  
  209.                 return f;
  210.             }
  211.  
  212.             [UNITY_patchconstantfunc("patchConstantFunction")]
  213.             [UNITY_domain("tri")][UNITY_outputcontrolpoints(3)]
  214.             [UNITY_outputtopology("triangle_cw")]
  215.             #if defined(_PARTITIONING_INTEGER)
  216.                 [partitioning("integer")]
  217.             #elif defined(_PARTITIONING_FRAC_EVEN)
  218.                 [partitioning("fractional_even")]
  219.             #elif defined(_PARTITIONING_FRAC_ODD)
  220.                 [partitioning("fractional_odd")]
  221.             #elif defined(_PARTITIONING_POW2)
  222.                 [partitioning("pow2")]
  223.             #else
  224.                 [partitioning("integer")]
  225.             #endif
  226.             TessellationControlPoint hull (InputPatch<TessellationControlPoint, 3> patch, uint id : SV_OutputControlPointID)
  227.             {
  228.                 return patch[id];
  229.             }
  230.  
  231.             [UNITY_domain("tri")]
  232.             Interpolators domain(TessellationFactors factors, OutputPatch<TessellationControlPoint, 3> patch,
  233.                 float3 barycentricCoordinates : SV_DomainLocation)
  234.             {
  235.                 Interpolators v;
  236.                 #define MY_DOMAIN_PROGRAM_INTERPOLATE(fieldName) v.fieldName = \
  237.                     patch[0].fieldName * barycentricCoordinates.x + \
  238.                     patch[1].fieldName * barycentricCoordinates.y + \
  239.                     patch[2].fieldName * barycentricCoordinates.z;
  240.                 MY_DOMAIN_PROGRAM_INTERPOLATE(vertex)
  241.                 MY_DOMAIN_PROGRAM_INTERPOLATE(normal)
  242.                 MY_DOMAIN_PROGRAM_INTERPOLATE(tangent)
  243.                 return v;
  244.             }
  245.  
  246.             [maxvertexcount(BLADE_SEGMENTS * 2 + 1)]
  247.             void geo(triangle Interpolators IN[3], inout TriangleStream<geometryOutput> triStream){
  248.                 float3 vNormal = IN[0].normal;
  249.                 float4 vTangent = IN[0].tangent;
  250.                 float3 vBinormal = cross(vNormal, vTangent) * vTangent.w;
  251.  
  252.                 float3x3 tangentToLocal = float3x3(
  253.                     vTangent.x, vBinormal.x, vNormal.x,
  254.                     vTangent.y, vBinormal.y, vNormal.y,
  255.                     vTangent.z, vBinormal.z, vNormal.z
  256.                     );
  257.                 float3 pos = IN[0].vertex;
  258.  
  259.                 float3x3 facingRotationMatrix = AngleAxis3x3(rand(pos) * UNITY_TWO_PI, float3(0, 0, 1));
  260.                 float3x3 bendRotationMatrix = AngleAxis3x3(rand(pos.zzx) * _BendRotationRandom * UNITY_PI * 0.2, float3(-1, 0, 0));
  261.  
  262.                 float2 uv = pos.xz * _WindDistortionMap_ST.xy + _WindDistortionMap_ST.zw + _WindFrequency * _Time.y;
  263.  
  264.                 float2 windSample = (tex2Dlod(_WindDistortionMap, float4(uv, 0, 0)).xy * 2 - 1) * _WindStrength;
  265.  
  266.                 float3 wind = normalize(float3(windSample.x, windSample.y, 0));
  267.  
  268.                 float3x3 windRotation = AngleAxis3x3(UNITY_PI * windSample * 0.2, wind);
  269.  
  270.                 float3x3 transformationMatrix = mul(mul(mul(tangentToLocal, windRotation), facingRotationMatrix), bendRotationMatrix);
  271.  
  272.                 float height = (rand(pos.zyx) * 2 - 1) * _BladeHeightRandom + _BladeHeight;
  273.                 float width = (rand(pos.xzy) * 2 - 1) * _BladeWidthRandom + _BladeWidth;
  274.  
  275.                 float forward = rand(pos.yyz) * _BladeForward;
  276.  
  277.                 float3x3 transformationMatrixFacing = mul(tangentToLocal, facingRotationMatrix);
  278.  
  279.                 for (int i = 0; i < BLADE_SEGMENTS; i++){
  280.                     float t = i / (float)BLADE_SEGMENTS;
  281.                     float segmentHeight = height * t;
  282.                     float segmentWidth = width * (1 - t);
  283.                     float segmentForward = pow(t, _BladeCurve) * forward;
  284.                     float3x3 transformMatrix = i == 0 ? transformationMatrixFacing : transformationMatrix;
  285.                     triStream.Append(GenerateGrassVertex(pos, segmentWidth, segmentHeight, segmentForward, float2(0, t), transformMatrix));
  286.                     triStream.Append(GenerateGrassVertex(pos, -segmentWidth, segmentHeight, segmentForward, float2(1, t), transformMatrix));
  287.                 }
  288.  
  289.                 triStream.Append(GenerateGrassVertex(pos, 0, height, forward, float2(0.5, 1), transformationMatrix));
  290.             }
  291.         ENDCG
  292.  
  293.         Pass{
  294.             Tags{ "RenderType" = "Opaque" "LightMode" = "ForwardBase" }
  295.  
  296.             CGPROGRAM
  297.             #include "Lighting.cginc"
  298.  
  299.             float4 _TopColor;
  300.             float4 _BottomColor;
  301.             float _TranslucentGain;
  302.  
  303.             float4 frag (geometryOutput IN, fixed facing : VFACE) : SV_Target{ 
  304.                 float3 normal = facing > 0 ? IN.normal : -IN.normal;
  305.  
  306.                 float shadow = SHADOW_ATTENUATION(IN);
  307.                 float NdotL = saturate(saturate(dot(normal, _WorldSpaceLightPos0)) + _TranslucentGain) * shadow;
  308.  
  309.                 float3 ambient = ShadeSH9(float4(normal, 1));
  310.                 float4 lightIntensity = NdotL * _LightColor0 + float4(ambient, 1);
  311.                 float4 col = lerp(_BottomColor, _TopColor * lightIntensity, IN.uv.y);
  312.  
  313.                 return col;
  314.             }
  315.             ENDCG
  316.         }
  317.  
  318.         Pass{
  319.             Tags{ "RenderType" = "Opaque" "LightMode" = "ShadowCaster"}
  320.             CGPROGRAM
  321.             float4 frag(geometryOutput IN) : SV_Target{
  322.                 SHADOW_CASTER_FRAGMENT(IN)
  323.             }
  324.             ENDCG
  325.         }
  326.  
  327.     }
  328. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement