WavingGrassPasses.hlsl 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #ifndef UNIVERSAL_WAVING_GRASS_PASSES_INCLUDED
  2. #define UNIVERSAL_WAVING_GRASS_PASSES_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
  4. struct GrassVertexInput
  5. {
  6. float4 vertex : POSITION;
  7. float3 normal : NORMAL;
  8. float4 tangent : TANGENT;
  9. half4 color : COLOR;
  10. float2 texcoord : TEXCOORD0;
  11. float2 lightmapUV : TEXCOORD1;
  12. UNITY_VERTEX_INPUT_INSTANCE_ID
  13. };
  14. struct GrassVertexOutput
  15. {
  16. float2 uv : TEXCOORD0;
  17. DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
  18. float4 posWSShininess : TEXCOORD2; // xyz: posWS, w: Shininess * 128
  19. half3 normal : TEXCOORD3;
  20. half3 viewDir : TEXCOORD4;
  21. half4 fogFactorAndVertexLight : TEXCOORD5; // x: fogFactor, yzw: vertex light
  22. #ifdef _MAIN_LIGHT_SHADOWS
  23. float4 shadowCoord : TEXCOORD6;
  24. #endif
  25. half4 color : TEXCOORD7;
  26. float4 clipPos : SV_POSITION;
  27. UNITY_VERTEX_INPUT_INSTANCE_ID
  28. UNITY_VERTEX_OUTPUT_STEREO
  29. };
  30. void InitializeInputData(GrassVertexOutput input, out InputData inputData)
  31. {
  32. inputData.positionWS = input.posWSShininess.xyz;
  33. half3 viewDirWS = input.viewDir;
  34. #if SHADER_HINT_NICE_QUALITY
  35. viewDirWS = SafeNormalize(viewDirWS);
  36. #endif
  37. inputData.normalWS = NormalizeNormalPerPixel(input.normal);
  38. inputData.viewDirectionWS = viewDirWS;
  39. #ifdef _MAIN_LIGHT_SHADOWS
  40. inputData.shadowCoord = input.shadowCoord;
  41. #else
  42. inputData.shadowCoord = float4(0, 0, 0, 0);
  43. #endif
  44. inputData.fogCoord = input.fogFactorAndVertexLight.x;
  45. inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
  46. inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
  47. }
  48. void InitializeVertData(GrassVertexInput input, inout GrassVertexOutput vertData)
  49. {
  50. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  51. vertData.uv = input.texcoord;
  52. vertData.posWSShininess.xyz = vertexInput.positionWS;
  53. vertData.posWSShininess.w = 32;
  54. vertData.clipPos = vertexInput.positionCS;
  55. vertData.viewDir = GetCameraPositionWS() - vertexInput.positionWS;
  56. #if !SHADER_QUALITY_NICE_HINT
  57. vertData.viewDir = SafeNormalize(vertData.viewDir);
  58. #endif
  59. vertData.normal = TransformObjectToWorldNormal(input.normal);
  60. // We either sample GI from lightmap or SH.
  61. // Lightmap UV and vertex SH coefficients use the same interpolator ("float2 lightmapUV" for lightmap or "half3 vertexSH" for SH)
  62. // see DECLARE_LIGHTMAP_OR_SH macro.
  63. // The following funcions initialize the correct variable with correct data
  64. OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, vertData.lightmapUV);
  65. OUTPUT_SH(vertData.normal, vertData.vertexSH);
  66. half3 vertexLight = VertexLighting(vertexInput.positionWS, vertData.normal.xyz);
  67. half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
  68. vertData.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
  69. #ifdef _MAIN_LIGHT_SHADOWS
  70. vertData.shadowCoord = GetShadowCoord(vertexInput);
  71. #endif
  72. }
  73. ///////////////////////////////////////////////////////////////////////////////
  74. // Vertex and Fragment functions //
  75. ///////////////////////////////////////////////////////////////////////////////
  76. // Grass: appdata_full usage
  77. // color - .xyz = color, .w = wave scale
  78. // normal - normal
  79. // tangent.xy - billboard extrusion
  80. // texcoord - UV coords
  81. // texcoord1 - 2nd UV coords
  82. GrassVertexOutput WavingGrassVert(GrassVertexInput v)
  83. {
  84. GrassVertexOutput o = (GrassVertexOutput)0;
  85. UNITY_SETUP_INSTANCE_ID(v);
  86. UNITY_TRANSFER_INSTANCE_ID(v, o);
  87. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  88. // MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
  89. // _WaveAndDistance.z == 0 for MeshLit
  90. float waveAmount = v.color.a * _WaveAndDistance.z;
  91. o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
  92. InitializeVertData(v, o);
  93. return o;
  94. }
  95. GrassVertexOutput WavingGrassBillboardVert(GrassVertexInput v)
  96. {
  97. GrassVertexOutput o = (GrassVertexOutput)0;
  98. UNITY_SETUP_INSTANCE_ID(v);
  99. UNITY_TRANSFER_INSTANCE_ID(v, o);
  100. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  101. TerrainBillboardGrass (v.vertex, v.tangent.xy);
  102. // wave amount defined by the grass height
  103. float waveAmount = v.tangent.y;
  104. o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
  105. InitializeVertData(v, o);
  106. return o;
  107. }
  108. // Used for StandardSimpleLighting shader
  109. half4 LitPassFragmentGrass(GrassVertexOutput input) : SV_Target
  110. {
  111. UNITY_SETUP_INSTANCE_ID(input);
  112. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  113. float2 uv = input.uv;
  114. half4 diffuseAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex));
  115. half3 diffuse = diffuseAlpha.rgb * input.color.rgb;
  116. half alpha = diffuseAlpha.a;
  117. AlphaDiscard(alpha, _Cutoff);
  118. alpha *= input.color.a;
  119. half3 emission = 0;
  120. half4 specularGloss = 0.1;// SampleSpecularSmoothness(uv, diffuseAlpha.a, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap));
  121. half shininess = input.posWSShininess.w;
  122. InputData inputData;
  123. InitializeInputData(input, inputData);
  124. half4 color = UniversalFragmentBlinnPhong(inputData, diffuse, specularGloss, shininess, emission, alpha);
  125. color.rgb = MixFog(color.rgb, inputData.fogCoord);
  126. return color;
  127. };
  128. struct VertexInput
  129. {
  130. float4 position : POSITION;
  131. half4 color : COLOR;
  132. float2 texcoord : TEXCOORD0;
  133. UNITY_VERTEX_INPUT_INSTANCE_ID
  134. };
  135. struct VertexOutput
  136. {
  137. float2 uv : TEXCOORD0;
  138. half4 color : TEXCOORD1;
  139. float4 clipPos : SV_POSITION;
  140. };
  141. VertexOutput DepthOnlyVertex(VertexInput v)
  142. {
  143. VertexOutput o = (VertexOutput)0;
  144. UNITY_SETUP_INSTANCE_ID(v);
  145. o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
  146. // MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
  147. // _WaveAndDistance.z == 0 for MeshLit
  148. float waveAmount = v.color.a * _WaveAndDistance.z;
  149. o.color = TerrainWaveGrass(v.position, waveAmount, v.color);
  150. o.clipPos = TransformObjectToHClip(v.position.xyz);
  151. return o;
  152. }
  153. half4 DepthOnlyFragment(VertexOutput IN) : SV_TARGET
  154. {
  155. Alpha(SampleAlbedoAlpha(IN.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, IN.color, _Cutoff);
  156. return 0;
  157. }
  158. #endif