Guest User

Monogame Shader

a guest
Jan 22nd, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.42 KB | None | 0 0
  1. //-----------------------------------------------------------------------------
  2. // ParticleEffect.fx
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7.  
  8.  
  9. // Camera parameters.
  10. float4x4 View;
  11. float4x4 Projection;
  12. float2 ViewportScale;
  13.  
  14.  
  15. // The current time, in seconds.
  16. float CurrentTime;
  17.  
  18.  
  19. // Parameters describing how the particles animate.
  20. float Duration;
  21. float DurationRandomness;
  22. float3 Gravity;
  23. float EndVelocity;
  24. float4 MinColor;
  25. float4 MaxColor;
  26.  
  27.  
  28. // These float2 parameters describe the min and max of a range.
  29. // The actual value is chosen differently for each particle,
  30. // interpolating between x and y by some random amount.
  31. float2 RotateSpeed;
  32. float2 StartSize;
  33. float2 EndSize;
  34.  
  35.  
  36. // Particle texture and sampler.
  37. Texture2D Texture;
  38.  
  39. SamplerState Sampler
  40. {
  41. Texture = (Texture);
  42.  
  43. MinFilter = Linear;
  44. MagFilter = Linear;
  45. MipFilter = Point;
  46.  
  47. AddressU = Clamp;
  48. AddressV = Clamp;
  49. };
  50.  
  51. // Vertex shader input structure describes the start position and
  52. // velocity of the particle, and the time at which it was created,
  53. // along with some random values that affect its size and rotation.
  54. struct VertexShaderInput
  55. {
  56. float3 Position : SV_POSITION; //POSITION
  57. float2 Corner : TEXCOORD0;
  58. float3 Velocity : NORMAL0;
  59. float4 Random : COLOR0;
  60. float Time : TEXCOORD1; //POSITION
  61. };
  62.  
  63.  
  64. // Vertex shader output structure specifies the position and color of the particle.
  65. struct VertexShaderOutput
  66. {
  67. float4 Position : SV_POSITION; //POSITION
  68. float4 Color : COLOR0;
  69. float2 TextureCoordinate : TEXCOORD0; //COLOR1
  70. };
  71.  
  72.  
  73. // Vertex shader helper for computing the position of a particle.
  74. float4 ComputeParticlePosition(float3 position, float3 velocity,
  75. float age, float normalizedAge)
  76. {
  77. float startVelocity = length(velocity);
  78.  
  79. // Work out how fast the particle should be moving at the end of its life,
  80. // by applying a constant scaling factor to its starting velocity.
  81. float endVelocity = startVelocity * EndVelocity;
  82.  
  83. // Our particles have constant acceleration, so given a starting velocity
  84. // S and ending velocity E, at time T their velocity should be S + (E-S)*T.
  85. // The particle position is the sum of this velocity over the range 0 to T.
  86. // To compute the position directly, we must integrate the velocity
  87. // equation. Integrating S + (E-S)*T for T produces S*T + (E-S)*T*T/2.
  88.  
  89. float velocityIntegral = startVelocity * normalizedAge +
  90. (endVelocity - startVelocity) * normalizedAge *
  91. normalizedAge / 2;
  92.  
  93. position += normalize(velocity) * velocityIntegral * Duration;
  94.  
  95. // Apply the gravitational force.
  96. position += Gravity * age * normalizedAge;
  97.  
  98. // Apply the camera view and projection transforms.
  99. return mul(mul(float4(position, 1), View), Projection);
  100. }
  101.  
  102.  
  103. // Vertex shader helper for computing the size of a particle.
  104. float ComputeParticleSize(float randomValue, float normalizedAge)
  105. {
  106. // Apply a random factor to make each particle a slightly different size.
  107. float startSize = lerp(StartSize.x, StartSize.y, randomValue);
  108. float endSize = lerp(EndSize.x, EndSize.y, randomValue);
  109.  
  110. // Compute the actual size based on the age of the particle.
  111. float size = lerp(startSize, endSize, normalizedAge);
  112.  
  113. // Project the size into screen coordinates.
  114. return size * Projection._m11;
  115. }
  116.  
  117.  
  118. // Vertex shader helper for computing the color of a particle.
  119. float4 ComputeParticleColor(float4 projectedPosition,
  120. float randomValue, float normalizedAge)
  121. {
  122. // Apply a random factor to make each particle a slightly different color.
  123. float4 color = lerp(MinColor, MaxColor, randomValue);
  124.  
  125. // Fade the alpha based on the age of the particle. This curve is hard coded
  126. // to make the particle fade in fairly quickly, then fade out more slowly:
  127. // plot x*(1-x)*(1-x) for x=0:1 in a graphing program if you want to see what
  128. // this looks like. The 6.7 scaling factor normalizes the curve so the alpha
  129. // will reach all the way up to fully solid.
  130.  
  131. color.a *= normalizedAge * (1-normalizedAge) * (1-normalizedAge) * 6.7;
  132.  
  133. return color;
  134. }
  135.  
  136.  
  137. // Vertex shader helper for computing the rotation of a particle.
  138. float2x2 ComputeParticleRotation(float randomValue, float age)
  139. {
  140. // Apply a random factor to make each particle rotate at a different speed.
  141. float rotateSpeed = lerp(RotateSpeed.x, RotateSpeed.y, randomValue);
  142.  
  143. float rotation = rotateSpeed * age;
  144.  
  145. // Compute a 2x2 rotation matrix.
  146. float c = cos(rotation);
  147. float s = sin(rotation);
  148.  
  149. return float2x2(c, -s, s, c);
  150. }
  151.  
  152.  
  153. // Custom vertex shader animates particles entirely on the GPU.
  154. VertexShaderOutput ParticleVertexShader(VertexShaderInput input)
  155. {
  156. VertexShaderOutput output;
  157.  
  158. // Compute the age of the particle.
  159. float age = CurrentTime - input.Time;
  160.  
  161. // Apply a random factor to make different particles age at different rates.
  162. age *= 1 + input.Random.x * DurationRandomness;
  163.  
  164. // Normalize the age into the range zero to one.
  165. float normalizedAge = saturate(age / Duration);
  166.  
  167. // Compute the particle position, size, color, and rotation.
  168. output.Position = ComputeParticlePosition(input.Position, input.Velocity,
  169. age, normalizedAge);
  170.  
  171. float size = ComputeParticleSize(input.Random.y, normalizedAge);
  172. float2x2 rotation = ComputeParticleRotation(input.Random.w, age);
  173.  
  174. output.Position.xy += mul(input.Corner, rotation) * size * ViewportScale;
  175.  
  176. output.Color = ComputeParticleColor(output.Position, input.Random.z, normalizedAge);
  177. output.TextureCoordinate = (input.Corner + 1) / 2;
  178.  
  179. return output;
  180. }
  181.  
  182.  
  183. // Pixel shader for drawing particles.
  184. float4 ParticlePixelShader(VertexShaderOutput input) : COLOR0
  185. {
  186. return Texture.Sample(Sampler, input.TextureCoordinate) * input.Color;
  187. }
  188.  
  189.  
  190. // Effect technique for drawing particles.
  191. technique Particles
  192. {
  193. pass P0
  194. {
  195. VertexShader = compile vs_5_0 ParticleVertexShader();
  196. PixelShader = compile ps_5_0 ParticlePixelShader();
  197. }
  198. }
Add Comment
Please, Sign In to add comment