foliage.hlsl 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. // CornerId corresponds to this arrangement
  23. // from the perspective of the camera.
  24. //
  25. // 3 ---- 2
  26. // | |
  27. // 0 ---- 1
  28. //
  29. #define MAX_COVERTYPES 8
  30. uniform float2 gc_fadeParams;
  31. uniform float2 gc_windDir;
  32. uniform float3 gc_camRight;
  33. uniform float3 gc_camUp;
  34. uniform float4 gc_typeRects[MAX_COVERTYPES];
  35. // .x = gust length
  36. // .y = premultiplied simulation time and gust frequency
  37. // .z = gust strength
  38. uniform float3 gc_gustInfo;
  39. // .x = premultiplied simulation time and turbulance frequency
  40. // .y = turbulance strength
  41. uniform float2 gc_turbInfo;
  42. static float sCornerRight[4] = { -0.5, 0.5, 0.5, -0.5 };
  43. static float sCornerUp[4] = { 0, 0, 1, 1 };
  44. static float sMovableCorner[4] = { 0, 0, 1, 1 };
  45. static float2 sUVCornerExtent[4] =
  46. {
  47. float2( 0, 1 ),
  48. float2( 1, 1 ),
  49. float2( 1, 0 ),
  50. float2( 0, 0 )
  51. };
  52. ///////////////////////////////////////////////////////////////////////////////
  53. // The following wind effect was derived from the GPU Gems 3 chapter...
  54. //
  55. // "Vegetation Procedural Animation and Shading in Crysis"
  56. // by Tiago Sousa, Crytek
  57. //
  58. float2 smoothCurve( float2 x )
  59. {
  60. return x * x * ( 3.0 - 2.0 * x );
  61. }
  62. float2 triangleWave( float2 x )
  63. {
  64. return abs( frac( x + 0.5 ) * 2.0 - 1.0 );
  65. }
  66. float2 smoothTriangleWave( float2 x )
  67. {
  68. return smoothCurve( triangleWave( x ) );
  69. }
  70. float windTurbulence( float bbPhase, float frequency, float strength )
  71. {
  72. // We create the input value for wave generation from the frequency and phase.
  73. float2 waveIn = bbPhase.xx + frequency.xx;
  74. // We use two square waves to generate the effect which
  75. // is then scaled by the overall strength.
  76. float2 waves = ( frac( waveIn.xy * float2( 1.975, 0.793 ) ) * 2.0 - 1.0 );
  77. waves = smoothTriangleWave( waves );
  78. // Sum up the two waves into a single wave.
  79. return ( waves.x + waves.y ) * strength;
  80. }
  81. float2 windEffect( float bbPhase,
  82. float2 windDirection,
  83. float gustLength,
  84. float gustFrequency,
  85. float gustStrength,
  86. float turbFrequency,
  87. float turbStrength )
  88. {
  89. // Calculate the ambient wind turbulence.
  90. float turbulence = windTurbulence( bbPhase, turbFrequency, turbStrength );
  91. // We simulate the overall gust via a sine wave.
  92. float gustPhase = clamp( sin( ( bbPhase - gustFrequency ) / gustLength ) , 0, 1 );
  93. float gustOffset = ( gustPhase * gustStrength ) + ( ( 0.2 + gustPhase ) * turbulence );
  94. // Return the final directional wind effect.
  95. return gustOffset.xx * windDirection.xy;
  96. }
  97. void foliageProcessVert( inout float3 position,
  98. inout float4 diffuse,
  99. inout float4 texCoord,
  100. inout float3 normal,
  101. inout float3 T,
  102. in float3 eyePos )
  103. {
  104. // Assign the normal and tagent values.
  105. //normal = float3( 0, 0, 1 );//cross( gc_camUp, gc_camRight );
  106. T = gc_camRight;
  107. // Pull out local vars we need for work.
  108. int corner = ( diffuse.a * 255.0f ) + 0.5f;
  109. float2 size = texCoord.xy;
  110. int type = texCoord.z;
  111. // The billboarding is based on the camera direction.
  112. float3 rightVec = gc_camRight * sCornerRight[corner];
  113. float3 upVec = gc_camUp * sCornerUp[corner];
  114. // Figure out the corner position.
  115. float3 outPos = ( upVec * size.y ) + ( rightVec * size.x );
  116. float len = length( outPos.xyz );
  117. // We derive the billboard phase used for wind calculations from its position.
  118. float bbPhase = dot( position.xyz, 1 );
  119. // Get the overall wind gust and turbulence effects.
  120. float3 wind;
  121. wind.xy = windEffect( bbPhase,
  122. gc_windDir,
  123. gc_gustInfo.x, gc_gustInfo.y, gc_gustInfo.z,
  124. gc_turbInfo.x, gc_turbInfo.y );
  125. wind.z = 0;
  126. // Add the summed wind effect into the point.
  127. outPos.xyz += wind.xyz * texCoord.w;
  128. // Do a simple spherical clamp to keep the foliage
  129. // from stretching too much by wind effect.
  130. outPos.xyz = normalize( outPos.xyz ) * len;
  131. // Move the point into world space.
  132. position += outPos;
  133. // Grab the uv set and setup the texture coord.
  134. float4 uvSet = gc_typeRects[type];
  135. texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
  136. texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
  137. // Animate the normal to get lighting changes
  138. // across the the wind swept foliage.
  139. //
  140. // TODO: Expose the 10x as a factor to control
  141. // how much the wind effects the lighting on the grass.
  142. //
  143. normal.xy += wind.xy * ( 10.0 * texCoord.w );
  144. normal = normalize( normal );
  145. // Get the alpha fade value.
  146. float fadeStart = gc_fadeParams.x;
  147. float fadeEnd = gc_fadeParams.y;
  148. const float fadeRange = fadeEnd - fadeStart;
  149. float dist = distance( eyePos, position.xyz ) - fadeStart;
  150. diffuse.a = 1 - clamp( dist / fadeRange, 0, 1 );
  151. }