Guest User

XNA Shader

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