Advertisement
remo9211

L3 URP Grass With Tess

May 20th, 2024
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Godot GLSL 13.33 KB | Source Code | 0 0
  1. Shader "L02_URP/Grass"{
  2.     Properties{
  3.  
  4.         _TopColor("Top Color", Color) = (1,1,1,1)
  5.         _BottomColor("Bottom Color", Color) = (1,1,1,1)
  6.         _TranslucentGain("Translucent Gain", Range(0,1)) = 0.5
  7.  
  8.         _BendRotationRandom("Bend Rotation Random", Range(0, 1)) = 0.2
  9.  
  10.         _BladeWidth("Blade Width", Float) = 0.05
  11.         _BladeWidthRandom("Blade Width Random", Float) = 0.02
  12.         _BladeHeight("Blade Height", Float) = 0.5
  13.         _BladeHeightRandom("Blade Height Random", Float) = 0.3
  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.         _WindDistortionMap("Wind Distortion Map", 2D) = "white" {}
  22.         _WindFrequency("Wind Frequency", Vector) = (0.05, 0.05, 0, 0)
  23.  
  24.         _WindStrength("Wind Strength", Float) = 1
  25.  
  26.         _BladeForward("Blade Forward Amount", Float) = 0.38
  27.         _BladeCurve("Blade Curvature Amount", Range(1, 4)) = 2
  28.  
  29.         [KeywordEnum(TRUE, FALSE)] _CUTTESS("Cut Tess", Int) = 0
  30.     }
  31.     SubShader{
  32.         Tags{
  33.             "RenderType" = "Opaque"
  34.             "Queue" = "Geometry"
  35.             "RenderPipeline" = "UniversalPipeline"
  36.         }
  37.         LOD 100
  38.         Cull Off
  39.  
  40.         HLSLINCLUDE
  41.             #pragma require geometry
  42.             #pragma require tessellation tessHW
  43.             #pragma vertex vert
  44.             #pragma fragment frag
  45.             #pragma hull hull
  46.             #pragma domain domain
  47.             #pragma geometry geo
  48.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  49.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
  50.             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"
  51.  
  52.             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
  53.             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
  54.             #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
  55.             #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
  56.             #pragma multi_compile _ _SHADOWS_SOFT
  57.  
  58.             #pragma shader_feature_local _PARTITIONING_INTEGER _PARTITIONING_FRAC_EVEN _PARTITIONING_FRAC_ODD _PARTITIONING_POW2
  59.             #pragma shader_feature_local _CUTTESS_TRUE _CUTTESS_FALSE
  60.             #pragma shader_feature_local _DYNAMIC_FIXED _DYNAMIC_SCREEN_BASE _DYNAMIC_WORLD_BASE
  61.  
  62.             #define UNITY_PI 3.14159265359f
  63.             #define UNITY_TWO_PI 6.28318530718f
  64.             #define BLADE_SEGMENTS 3
  65.  
  66.             CBUFFER_START(UnityPerMaterial)
  67.                 float4 _BaseColor;
  68.                 float4 _BaseMap_ST;
  69.                 float _BendRotationRandom;
  70.  
  71.                 float _BladeHeight;
  72.                 float _BladeHeightRandom;  
  73.                 float _BladeWidth;
  74.                 float _BladeWidthRandom;
  75.  
  76.                 sampler2D _WindDistortionMap;
  77.                 float4 _WindDistortionMap_ST;
  78.  
  79.                 float2 _WindFrequency;
  80.                 float _WindStrength;
  81.  
  82.                 float _BladeForward;
  83.                 float _BladeCurve;
  84.  
  85.                 float4 _TopColor;
  86.                 float4 _BottomColor;
  87.  
  88.                 float _TessellationFactor_FIXED;
  89.                 float _TessellationFactor_SCREEN_BASE;
  90.                 float _TessellationFactor_WORLD_BASE;
  91.  
  92.             float _TranslucentGain;
  93.  
  94.             CBUFFER_END
  95.             TEXTURE2D (_BaseMap);SAMPLER(sampler_BaseMap);
  96.  
  97.  
  98.             struct Attributes
  99.             {
  100.                 float4 posOS : POSITION;
  101.                 float3 normalOS : NORMAL;
  102.                 float4 tangentOS : TANGENT;
  103.             };
  104.             struct TessellationControlPoint
  105.             {
  106.                 float4 posOS : INTERNALTESSPOS;
  107.                 float3 normalOS : NORMAL;
  108.                 float4 tangentOS : TANGENT;
  109.                 float4 positionCS : TEXCOORD0;
  110.             };
  111.             struct Interpolators
  112.             {
  113.                 float4 posOS : POSITION;
  114.                 float3 normalOS : NORMAL;
  115.                 float4 tangentOS : TANGENT;
  116.             };
  117.             struct TessellationFactors
  118.             {
  119.                 float edge[3] : SV_TessFactor;
  120.                 float inside : SV_InsideTessFactor;
  121.             };
  122.             struct geometryOutput{
  123.                 float4 pos : SV_POSITION;
  124.                 float2 uv : TEXCOORD0;
  125.                 float4 shadowCoord : TEXCOORD1;
  126.                 float3 norWS : TEXCOORD2;
  127.                 // float3 normal : NORMAL;
  128.             };
  129.  
  130.             /*
  131.                 Tools Function
  132.             */
  133.             float rand(float3 co){
  134.                 return frac(sin(dot(co.xyz, float3(12.9898, 78.233, 53.539))) * 43758.5453);
  135.             }
  136.             float3x3 AngleAxis3x3(float angle, float3 axis){
  137.                 float c, s;
  138.                 sincos(angle, s, c);
  139.  
  140.                 float t = 1 - c;
  141.                 float x = axis.x;
  142.                 float y = axis.y;
  143.                 float z = axis.z;
  144.  
  145.                 return float3x3(
  146.                     t * x * x + c, t * x * y - s * z, t * x * z + s * y,
  147.                     t * x * y + s * z, t * y * y + c, t * y * z - s * x,
  148.                     t * x * z - s * y, t * y * z + s * x, t * z * z + c
  149.                     );
  150.             }
  151.             bool IsOutOfBounds(float3 p, float3 lower, float3 higher) { //给定矩形判断
  152.                 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;
  153.             }
  154.             bool IsPointOutOfFrustum(float4 positionCS) { //视锥体判断
  155.                 float3 culling = positionCS.xyz;
  156.                 float w = positionCS.w;
  157.                 float3 lowerBounds = float3(-w, -w, -w * _ProjectionParams.z);
  158.                 float3 higherBounds = float3(w, w, w);
  159.                 return IsOutOfBounds(culling, lowerBounds, higherBounds);
  160.             }
  161.             bool ShouldClipPatch(float4 p0PositionCS, float4 p1PositionCS, float4 p2PositionCS) {
  162.                 bool allOutside = IsPointOutOfFrustum(p0PositionCS) &&
  163.                     IsPointOutOfFrustum(p1PositionCS) &&
  164.                     IsPointOutOfFrustum(p2PositionCS);
  165.                 return allOutside;
  166.             }
  167.             // 生成草的具體座標, 草的寬度, 草的高度, 草的朝向, uv傳遞, 變換矩陣
  168.             geometryOutput GenerateGrassVertex(float3 vertexPosition, float width, float height, float forward, float2 uv, float3x3 transformMatrix) {
  169.                 float3 tangentPoint = float3(width, forward, height);
  170.                 float3 localPosition = vertexPosition + mul(transformMatrix, tangentPoint);
  171.                 float3 tangentNormal = normalize(float3(0, -1, forward));
  172.                 float3 localNormal = mul(transformMatrix, tangentNormal);
  173.                 float3 posWS = TransformObjectToWorld(localPosition.xyz);
  174.                 float3 norWS = TransformObjectToWorldNormal(localNormal);
  175.                 geometryOutput o;
  176.                 o.pos = TransformObjectToHClip(localPosition);
  177.                 o.uv = uv;
  178.                 o.norWS = norWS;
  179.                 o.shadowCoord = TransformWorldToShadowCoord(posWS);
  180.                 #if UNITY_PASS_SHADOWCASTER
  181.                     // o.pos = UnityApplyLinearShadowBias(o.pos);
  182.                     o.shadowCoord = TransformWorldToShadowCoord(ApplyShadowBias(posWS, norWS, 0));
  183.                 #endif
  184.                 return o;
  185.             }
  186.             float EdgeTessellationFactor_ScreenBase(float scale, float4 p0PositionCS, float4 p1PositionCS) {
  187.                 float factor = distance(p0PositionCS.xyz / p0PositionCS.w, p1PositionCS.xyz / p1PositionCS.w);
  188.                 return max(1, factor / scale);
  189.             }
  190.             float EdgeTessellationFactor_WorldBase(float scale, float3 p0PositionWS, float3 p1PositionWS) {
  191.                 float length = distance(p0PositionWS, p1PositionWS);
  192.                 float distanceToCamera = distance(_WorldSpaceCameraPos, (p0PositionWS + p1PositionWS) * 0.5);
  193.                 // 使用平方根函数调整距离的影响,使中距离的镶嵌因子变化更平滑
  194.                 float adjustedDistance = sqrt(distanceToCamera);
  195.                 float factor = length / (scale * adjustedDistance);
  196.                 return max(1, factor);
  197.             }
  198.  
  199.  
  200.             /*
  201.                 Vertex Shader
  202.             */
  203.             TessellationControlPoint vert(Attributes v){
  204.                 TessellationControlPoint o;
  205.                 o.posOS         = v.posOS;
  206.                 o.normalOS      = v.normalOS;
  207.                 o.tangentOS     = v.tangentOS;
  208.                 o.positionCS    = TransformObjectToHClip(v.posOS);
  209.                 return o;
  210.             }
  211.             /*
  212.                 Tesselation Shader
  213.             */
  214.             TessellationFactors patchConstantFunction (InputPatch<TessellationControlPoint, 3> patch){
  215.                 TessellationFactors f;
  216.                 #if defined(_DYNAMIC_FIXED)
  217.                     f.edge[0] = _TessellationFactor_FIXED;
  218.                     f.edge[1] = _TessellationFactor_FIXED;
  219.                     f.edge[2] = _TessellationFactor_FIXED;
  220.                     f.inside = _TessellationFactor_FIXED;
  221.                 #elif defined(_DYNAMIC_SCREEN_BASE)
  222.                     f.edge[0] = EdgeTessellationFactor_ScreenBase(_TessellationFactor_SCREEN_BASE,
  223.                         patch[1].positionCS, patch[2].positionCS);
  224.                     f.edge[1] = EdgeTessellationFactor_ScreenBase(_TessellationFactor_SCREEN_BASE,
  225.                         patch[2].positionCS, patch[0].positionCS);
  226.                     f.edge[2] = EdgeTessellationFactor_ScreenBase(_TessellationFactor_SCREEN_BASE,
  227.                         patch[0].positionCS, patch[1].positionCS);
  228.                     f.inside = (f.edge[0] + f.edge[1] + f.edge[2]) / 3.0;
  229.                 #elif defined(_DYNAMIC_WORLD_BASE)
  230.                     f.edge[0] = EdgeTessellationFactor_WorldBase(_TessellationFactor_WORLD_BASE,
  231.                         patch[1].posOS, patch[2].posOS);
  232.                     f.edge[1] = EdgeTessellationFactor_WorldBase(_TessellationFactor_WORLD_BASE,
  233.                         patch[2].posOS, patch[0].posOS);
  234.                     f.edge[2] = EdgeTessellationFactor_WorldBase(_TessellationFactor_WORLD_BASE,
  235.                         patch[0].posOS, patch[1].posOS);
  236.                     f.inside = (f.edge[0] + f.edge[1] + f.edge[2]) / 3.0;
  237.                 #else
  238.                     f.edge[0] = _TessellationFactor_FIXED;
  239.                     f.edge[1] = _TessellationFactor_FIXED;
  240.                     f.edge[2] = _TessellationFactor_FIXED;
  241.                     f.inside = _TessellationFactor_FIXED;
  242.                 #endif
  243.  
  244.                 #if defined(_CUTTESS_TRUE)
  245.                     if(ShouldClipPatch(patch[0].positionCS, patch[1].positionCS, patch[2].positionCS))
  246.                         f.edge[0] = f.edge[1] = f.edge[2] = f.inside = 0;
  247.                 #endif
  248.  
  249.                 return f;
  250.             }
  251.             [patchconstantfunc("patchConstantFunction")]
  252.             [domain("tri")][outputcontrolpoints(3)]
  253.             [outputtopology("triangle_cw")]
  254.             #if defined(_PARTITIONING_INTEGER)
  255.                 [partitioning("integer")]
  256.             #elif defined(_PARTITIONING_FRAC_EVEN)
  257.                 [partitioning("fractional_even")]
  258.             #elif defined(_PARTITIONING_FRAC_ODD)
  259.                 [partitioning("fractional_odd")]
  260.             #elif defined(_PARTITIONING_POW2)
  261.                 [partitioning("pow2")]
  262.             #else
  263.                 [partitioning("integer")]
  264.             #endif
  265.             TessellationControlPoint hull (InputPatch<TessellationControlPoint, 3> patch, uint id : SV_OutputControlPointID){
  266.                 return patch[id];
  267.             }
  268.  
  269.             [domain("tri")]
  270.             Interpolators domain(TessellationFactors factors, OutputPatch<TessellationControlPoint, 3> patch,
  271.                 float3 barycentricCoordinates : SV_DomainLocation)
  272.                 {
  273.                 Interpolators v;
  274.                 #define MY_DOMAIN_PROGRAM_INTERPOLATE(fieldName) v.fieldName = \
  275.                     patch[0].fieldName * barycentricCoordinates.x + \
  276.                     patch[1].fieldName * barycentricCoordinates.y + \
  277.                     patch[2].fieldName * barycentricCoordinates.z;
  278.                 MY_DOMAIN_PROGRAM_INTERPOLATE(posOS)
  279.                 MY_DOMAIN_PROGRAM_INTERPOLATE(normalOS)
  280.                 MY_DOMAIN_PROGRAM_INTERPOLATE(tangentOS)
  281.                 return v;
  282.             }
  283.             [maxvertexcount(BLADE_SEGMENTS * 2 + 1)]
  284.             void geo(triangle Interpolators IN[3], inout TriangleStream<geometryOutput> triStream){
  285.                 float3 vNormal = IN[0].normalOS;
  286.                 float4 vTangent = IN[0].tangentOS;
  287.                 float3 vBinormal = cross(vNormal, vTangent) * vTangent.w;
  288.  
  289.                 float3x3 tangentToLocal = float3x3(
  290.                     vTangent.x, vBinormal.x, vNormal.x,
  291.                     vTangent.y, vBinormal.y, vNormal.y,
  292.                     vTangent.z, vBinormal.z, vNormal.z
  293.                     );
  294.                 float3 pos = IN[0].posOS;
  295.  
  296.                 float3x3 facingRotationMatrix = AngleAxis3x3(rand(pos) * UNITY_TWO_PI, float3(0, 0, 1));
  297.                 float3x3 bendRotationMatrix = AngleAxis3x3(rand(pos.zzx) * _BendRotationRandom * UNITY_PI * 0.2, float3(-1, 0, 0));
  298.  
  299.                 float2 uv = pos.xz * _WindDistortionMap_ST.xy + _WindDistortionMap_ST.zw + _WindFrequency * _Time.y;
  300.  
  301.                 float2 windSample = (tex2Dlod(_WindDistortionMap, float4(uv, 0, 0)).xy * 2 - 1) * _WindStrength;
  302.  
  303.                 float3 wind = normalize(float3(windSample.x, windSample.y, 0));
  304.  
  305.                 float3x3 windRotation = AngleAxis3x3(UNITY_PI * windSample * 0.2, wind);
  306.  
  307.                 float3x3 transformationMatrix = mul(mul(mul(tangentToLocal, windRotation), facingRotationMatrix), bendRotationMatrix);
  308.  
  309.                 float height = (rand(pos.zyx) * 2 - 1) * _BladeHeightRandom + _BladeHeight;
  310.                 float width = (rand(pos.xzy) * 2 - 1) * _BladeWidthRandom + _BladeWidth;
  311.  
  312.                 float forward = rand(pos.yyz) * _BladeForward;
  313.  
  314.                 float3x3 transformationMatrixFacing = mul(tangentToLocal, facingRotationMatrix);
  315.  
  316.                 for (int i = 0; i < BLADE_SEGMENTS; i++){
  317.                     float t = i / (float)BLADE_SEGMENTS;
  318.                     float segmentHeight = height * t;
  319.                     float segmentWidth = width * (1 - t);
  320.                     float segmentForward = pow(t, _BladeCurve) * forward;
  321.                     float3x3 transformMatrix = i == 0 ? transformationMatrixFacing : transformationMatrix;
  322.                     triStream.Append(GenerateGrassVertex(pos, segmentWidth, segmentHeight, segmentForward, float2(0, t), transformMatrix));
  323.                     triStream.Append(GenerateGrassVertex(pos, -segmentWidth, segmentHeight, segmentForward, float2(1, t), transformMatrix));
  324.                 }
  325.  
  326.                 triStream.Append(GenerateGrassVertex(pos, 0, height, forward, float2(0.5, 1), transformationMatrix));
  327.             }
  328.         ENDHLSL
  329.  
  330.         Pass{
  331.             Name "GrassPass"
  332.             Tags{ "LightMode" = "UniversalForward" }
  333.  
  334.             HLSLPROGRAM
  335.  
  336.                 float4 frag (geometryOutput IN, float facing : VFACE) : SV_Target {
  337.                     Light mainLight = GetMainLight(IN.shadowCoord);
  338.  
  339.                     float3 normal = facing > 0 ? IN.norWS : -IN.norWS;
  340.  
  341.                     float shadow = lerp(0.0, 1.0, mainLight.shadowAttenuation + 0.25f);
  342.                     float NdotL = saturate(saturate(dot(normal, mainLight.direction)) + _TranslucentGain) * shadow;
  343.  
  344.                     float3 ambient = SampleSH(float4(normal, 1));
  345.                     float4 lightIntensity = float4(ambient + NdotL * _MainLightColor.rgb, 1.0);
  346.                     float4 col = lerp(_BottomColor, _TopColor * lightIntensity, IN.uv.y);
  347.  
  348.                     return col;
  349.                 }
  350.             ENDHLSL
  351.         }
  352.  
  353.  
  354.         Pass{
  355.             Name "ShadowCaster"
  356.             Tags{ "RenderType" = "Opaque" "LightMode" = "ShadowCaster" }
  357.    
  358.             ZWrite On
  359.             ZTest LEqual
  360.    
  361.             HLSLPROGRAM
  362.                 half4 frag(geometryOutput input) : SV_TARGET{
  363.                     return 1;
  364.                 }
  365.    
  366.             ENDHLSL
  367.         }
  368.     }
  369. }
Tags: grass URP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement