Без опису
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

WavingGrassPasses.hlsl 10.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
  5. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl"
  6. struct GrassVertexInput
  7. {
  8. float4 vertex : POSITION;
  9. float3 normal : NORMAL;
  10. float4 tangent : TANGENT;
  11. half4 color : COLOR;
  12. float2 texcoord : TEXCOORD0;
  13. float2 lightmapUV : TEXCOORD1;
  14. UNITY_VERTEX_INPUT_INSTANCE_ID
  15. };
  16. struct GrassVertexOutput
  17. {
  18. float2 uv : TEXCOORD0;
  19. DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
  20. float4 posWSShininess : TEXCOORD2; // xyz: posWS, w: Shininess * 128
  21. half3 normal : TEXCOORD3;
  22. half3 viewDir : TEXCOORD4;
  23. half4 fogFactorAndVertexLight : TEXCOORD5; // x: fogFactor, yzw: vertex light
  24. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  25. float4 shadowCoord : TEXCOORD6;
  26. #endif
  27. half4 color : TEXCOORD7;
  28. #ifdef USE_APV_PROBE_OCCLUSION
  29. float4 probeOcclusion : TEXCOORD8;
  30. #endif
  31. float4 clipPos : SV_POSITION;
  32. UNITY_VERTEX_INPUT_INSTANCE_ID
  33. UNITY_VERTEX_OUTPUT_STEREO
  34. };
  35. void InitializeInputData(GrassVertexOutput input, out InputData inputData)
  36. {
  37. inputData = (InputData)0;
  38. inputData.positionWS = input.posWSShininess.xyz;
  39. half3 viewDirWS = input.viewDir;
  40. viewDirWS = SafeNormalize(viewDirWS);
  41. inputData.normalWS = NormalizeNormalPerPixel(input.normal);
  42. inputData.viewDirectionWS = viewDirWS;
  43. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  44. inputData.shadowCoord = input.shadowCoord;
  45. #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
  46. inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
  47. #else
  48. inputData.shadowCoord = float4(0, 0, 0, 0);
  49. #endif
  50. #if defined(_FOG_FRAGMENT)
  51. float clipZ = input.clipPos.z;
  52. #if !UNITY_REVERSED_Z
  53. clipZ = lerp(UNITY_NEAR_CLIP_VALUE, 1, clipZ); // OpenGL NDC, -1 < z < 1
  54. #endif
  55. clipZ *= input.clipPos.w;
  56. inputData.fogCoord = ComputeFogFactor(clipZ);
  57. #else
  58. inputData.fogCoord = input.fogFactorAndVertexLight.x;
  59. #endif
  60. inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
  61. #if defined(DYNAMICLIGHTMAP_ON)
  62. inputData.bakedGI = SAMPLE_GI(input.lightmapUV, NOT_USED, input.vertexSH, inputData.normalWS);
  63. inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
  64. #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
  65. inputData.bakedGI = SAMPLE_GI(input.vertexSH,
  66. GetAbsolutePositionWS(inputData.positionWS),
  67. inputData.normalWS,
  68. inputData.viewDirectionWS,
  69. input.clipPos.xy,
  70. input.probeOcclusion,
  71. inputData.shadowMask);
  72. #else
  73. inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
  74. inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
  75. #endif
  76. inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
  77. #if defined(DEBUG_DISPLAY)
  78. #if defined(DYNAMICLIGHTMAP_ON)
  79. inputData.staticLightmapUV = input.lightmapUV;
  80. #elif defined(LIGHTMAP_ON)
  81. inputData.staticLightmapUV = input.lightmapUV;
  82. #else
  83. inputData.vertexSH = input.vertexSH;
  84. #endif
  85. #endif
  86. }
  87. void InitializeVertData(GrassVertexInput input, inout GrassVertexOutput vertData)
  88. {
  89. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  90. vertData.uv = input.texcoord;
  91. vertData.posWSShininess.xyz = vertexInput.positionWS;
  92. vertData.posWSShininess.w = 32;
  93. vertData.clipPos = vertexInput.positionCS;
  94. vertData.viewDir = GetCameraPositionWS() - vertexInput.positionWS;
  95. vertData.viewDir = SafeNormalize(vertData.viewDir);
  96. vertData.normal = TransformObjectToWorldNormal(input.normal);
  97. // We either sample GI from lightmap or SH.
  98. // Lightmap UV and vertex SH coefficients use the same interpolator ("float2 lightmapUV" for lightmap or "half3 vertexSH" for SH)
  99. // see DECLARE_LIGHTMAP_OR_SH macro.
  100. // The following funcions initialize the correct variable with correct data
  101. OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, vertData.lightmapUV);
  102. OUTPUT_SH4(vertexInput.positionWS, vertData.normal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), vertData.vertexSH, vertData.probeOcclusion);
  103. half3 vertexLight = VertexLighting(vertexInput.positionWS, vertData.normal.xyz);
  104. #if defined(_FOG_FRAGMENT)
  105. half fogFactor = 0;
  106. #else
  107. half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
  108. #endif
  109. vertData.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
  110. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  111. vertData.shadowCoord = GetShadowCoord(vertexInput);
  112. #endif
  113. }
  114. ///////////////////////////////////////////////////////////////////////////////
  115. // Vertex and Fragment functions //
  116. ///////////////////////////////////////////////////////////////////////////////
  117. // Grass: appdata_full usage
  118. // color - .xyz = color, .w = wave scale
  119. // normal - normal
  120. // tangent.xy - billboard extrusion
  121. // texcoord - UV coords
  122. // texcoord1 - 2nd UV coords
  123. GrassVertexOutput WavingGrassVert(GrassVertexInput v)
  124. {
  125. GrassVertexOutput o = (GrassVertexOutput)0;
  126. UNITY_SETUP_INSTANCE_ID(v);
  127. UNITY_TRANSFER_INSTANCE_ID(v, o);
  128. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  129. // MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
  130. // _WaveAndDistance.z == 0 for MeshLit
  131. float waveAmount = v.color.a * _WaveAndDistance.z;
  132. o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
  133. InitializeVertData(v, o);
  134. return o;
  135. }
  136. GrassVertexOutput WavingGrassBillboardVert(GrassVertexInput v)
  137. {
  138. GrassVertexOutput o = (GrassVertexOutput)0;
  139. UNITY_SETUP_INSTANCE_ID(v);
  140. UNITY_TRANSFER_INSTANCE_ID(v, o);
  141. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  142. TerrainBillboardGrass (v.vertex, v.tangent.xy);
  143. // wave amount defined by the grass height
  144. float waveAmount = v.tangent.y;
  145. o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
  146. InitializeVertData(v, o);
  147. return o;
  148. }
  149. inline void InitializeSimpleLitSurfaceData(GrassVertexOutput input, out SurfaceData outSurfaceData)
  150. {
  151. half4 diffuseAlpha = SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex));
  152. half3 diffuse = diffuseAlpha.rgb * input.color.rgb;
  153. half alpha = diffuseAlpha.a * input.color.a;
  154. alpha = AlphaDiscard(alpha, _Cutoff);
  155. outSurfaceData = (SurfaceData)0;
  156. outSurfaceData.alpha = alpha;
  157. outSurfaceData.albedo = diffuse;
  158. outSurfaceData.metallic = 0.0; // unused
  159. outSurfaceData.specular = 0.1;// SampleSpecularSmoothness(uv, diffuseAlpha.a, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap));
  160. outSurfaceData.smoothness = input.posWSShininess.w;
  161. outSurfaceData.normalTS = 0.0; // unused
  162. outSurfaceData.occlusion = 1.0;
  163. outSurfaceData.emission = 0.0;
  164. }
  165. // Used for StandardSimpleLighting shader
  166. #ifdef TERRAIN_GBUFFER
  167. FragmentOutput LitPassFragmentGrass(GrassVertexOutput input)
  168. #else
  169. half4 LitPassFragmentGrass(GrassVertexOutput input) : SV_Target
  170. #endif
  171. {
  172. UNITY_SETUP_INSTANCE_ID(input);
  173. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  174. SurfaceData surfaceData;
  175. InitializeSimpleLitSurfaceData(input, surfaceData);
  176. InputData inputData;
  177. InitializeInputData(input, inputData);
  178. SETUP_DEBUG_TEXTURE_DATA_FOR_TEX(inputData, input.uv, _MainTex);
  179. #ifdef TERRAIN_GBUFFER
  180. half4 color = half4(inputData.bakedGI * surfaceData.albedo + surfaceData.emission, surfaceData.alpha);
  181. return SurfaceDataToGbuffer(surfaceData, inputData, color.rgb, kLightingSimpleLit);
  182. #else
  183. half4 color = UniversalFragmentBlinnPhong(inputData, surfaceData);
  184. color.rgb = MixFog(color.rgb, inputData.fogCoord);
  185. return half4(color.rgb, OutputAlpha(surfaceData.alpha, IsSurfaceTypeTransparent(_Surface)));
  186. #endif
  187. };
  188. struct GrassVertexDepthOnlyInput
  189. {
  190. float4 vertex : POSITION;
  191. float4 tangent : TANGENT;
  192. half4 color : COLOR;
  193. float2 texcoord : TEXCOORD0;
  194. UNITY_VERTEX_INPUT_INSTANCE_ID
  195. };
  196. struct GrassVertexDepthOnlyOutput
  197. {
  198. float2 uv : TEXCOORD0;
  199. half4 color : TEXCOORD1;
  200. float4 clipPos : SV_POSITION;
  201. UNITY_VERTEX_INPUT_INSTANCE_ID
  202. UNITY_VERTEX_OUTPUT_STEREO
  203. };
  204. void InitializeVertData(GrassVertexDepthOnlyInput input, inout GrassVertexDepthOnlyOutput vertData)
  205. {
  206. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  207. vertData.uv = input.texcoord;
  208. vertData.clipPos = vertexInput.positionCS;
  209. }
  210. GrassVertexDepthOnlyOutput DepthOnlyVertex(GrassVertexDepthOnlyInput v)
  211. {
  212. GrassVertexDepthOnlyOutput o = (GrassVertexDepthOnlyOutput)0;
  213. UNITY_SETUP_INSTANCE_ID(v);
  214. UNITY_TRANSFER_INSTANCE_ID(v, o);
  215. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  216. // MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
  217. // _WaveAndDistance.z == 0 for MeshLit
  218. float waveAmount = v.color.a * _WaveAndDistance.z;
  219. o.color = TerrainWaveGrass(v.vertex, waveAmount, v.color);
  220. InitializeVertData(v, o);
  221. return o;
  222. }
  223. GrassVertexDepthOnlyOutput DepthOnlyBillboardVertex(GrassVertexDepthOnlyInput v)
  224. {
  225. GrassVertexDepthOnlyOutput o = (GrassVertexDepthOnlyOutput) 0;
  226. UNITY_SETUP_INSTANCE_ID(v);
  227. UNITY_TRANSFER_INSTANCE_ID(v, o);
  228. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  229. TerrainBillboardGrass (v.vertex, v.tangent.xy);
  230. // wave amount defined by the grass height
  231. float waveAmount = v.tangent.y;
  232. o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
  233. InitializeVertData(v, o);
  234. return o;
  235. }
  236. half4 DepthOnlyFragment(GrassVertexDepthOnlyOutput input) : SV_TARGET
  237. {
  238. Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, input.color, _Cutoff);
  239. return input.clipPos.z;
  240. }
  241. #endif