GPUParticleDistortion.fx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. //////////////////////////////////////////////////////////////////////////////
  2. // ©2005 Electronic Arts Inc
  3. //
  4. // GPU vertex particle FX Shader
  5. //////////////////////////////////////////////////////////////////////////////
  6. #include "Common.fxh"
  7. #include "CommonParticle.fxh"
  8. int _GlobalInfo : SasGlobal
  9. <
  10. string UIWidget = "None";
  11. int3 SasVersion = int3(1, 0, 0);
  12. int SortLevel = SortLevel_Distorter;
  13. > = 0;
  14. SAMPLER_2D_BEGIN( NormalTexture,
  15. string UIWidget = "None";
  16. string SasBindAddress = "Particle.Draw.Texture";
  17. )
  18. MinFilter = Linear;
  19. MagFilter = Linear;
  20. MipFilter = Linear;
  21. AddressU = Wrap;
  22. AddressV = Wrap;
  23. SAMPLER_2D_END
  24. //--------------------------------- GENERAL STUFF --------------------------------------
  25. // Transformations
  26. float4x4 WorldViewProjection : WorldViewProjection;
  27. float4x3 View : View;
  28. float4x3 ViewI : ViewInverse;
  29. float4x3 World : World;
  30. // Time (ie. material is animated)
  31. float Time : Time;
  32. // ----------------------------------------------------------------------------
  33. // SHADER: Default
  34. // ----------------------------------------------------------------------------
  35. struct ParticleVSOutput
  36. {
  37. float4 Position : POSITION;
  38. float2 ParticleTexCoord : TEXCOORD0;
  39. float4 Color : TEXCOORD1; // Not in color register to have increased range from -1 to 1
  40. float3x3 TangentToViewSpace : TEXCOORD2;
  41. };
  42. // ----------------------------------------------------------------------------
  43. ParticleVSOutput ParticleVertexShader(
  44. float4 StartPositionLifeInFrames : POSITION,
  45. float4 StartVelocityCreationFrame : TEXCOORD0,
  46. float2 SeedAndIndex : TEXCOORD1)
  47. {
  48. ParticleVSOutput Out;
  49. // decode vertex data
  50. float3 StartPosition = StartPositionLifeInFrames.xyz;
  51. float LifeInFrames = StartPositionLifeInFrames.w;
  52. float3 StartVelocity = StartVelocityCreationFrame.xyz;
  53. float CreationFrame = StartVelocityCreationFrame.w;
  54. float Seed = SeedAndIndex.x;
  55. float Index = SeedAndIndex.y;
  56. // particle system works with frames, so first convert time to frame
  57. // rather than converting everything else to time
  58. float age = (Time * CLIENT_FRAMES_PER_SECOND - CreationFrame);
  59. // first eliminate dead particles
  60. if (age > LifeInFrames)
  61. {
  62. Index = 0;
  63. }
  64. float relativeAge = age / LifeInFrames;
  65. float3 particlePosition;
  66. float size;
  67. float2x2 zRotationMatrix;
  68. Particle_ComputePhysics(particlePosition, size, zRotationMatrix,
  69. age, StartPosition, StartVelocity, Seed);
  70. // Calculate vertex position
  71. float2 vertexCorner = VertexCorners[Index];
  72. float2 relativeCornerPos = mul(vertexCorner, zRotationMatrix);
  73. float3 xVector = float3( View[0][0], View[1][0], View[2][0] );
  74. float3 zVector = float3( View[0][1], View[1][1], View[2][1] );
  75. float3 cornerPosition = particlePosition + size * (relativeCornerPos.x * xVector + relativeCornerPos.y * zVector);
  76. Out.Position = mul(float4(cornerPosition, 1), WorldViewProjection);
  77. //zVector = -zVector;
  78. float3 Normal = cross(xVector, zVector);
  79. float3 worldNormal = normalize(mul(Normal, (float3x3)World));
  80. float3 worldTangent = -zVector;
  81. float3 worldBinormal = -xVector; // This is inverted to what the normal mapping particles do as screen space xy is upside down otherwise
  82. float3x3 zRotation3D = float3x3(float3(zRotationMatrix[0], 0), float3(zRotationMatrix[1], 0), float3(0, 0, 1));
  83. // Build 3x3 tranform from tangent to world space
  84. float3x3 tangentToWorldSpace = mul(transpose(zRotation3D), float3x3(-worldBinormal, -worldTangent, worldNormal));
  85. Out.TangentToViewSpace = mul(tangentToWorldSpace, (float3x3)View);
  86. // Texture coordinate
  87. float randomIndex = GetRandomFloatValue(float2(0.0f, 1.0f), Seed, 7) * Draw.VideoTexture_NumPerRow_LastFrame.y;
  88. randomIndex -= frac(randomIndex);
  89. float currentTexFrame = age * Draw.SpeedMultiplier + randomIndex;
  90. float2 texCoord = GetVertexTexCoord(vertexCorner);
  91. Out.ParticleTexCoord = Particle_ComputeVideoTexture(currentTexFrame, texCoord);
  92. // compute color
  93. float4 color = Particle_ComputeColor(relativeAge, Seed, true);
  94. color.xyz = color.xyz * 2.0 - 1.0; // Unpack to treat the color as normal
  95. Out.Color = color;
  96. return Out;
  97. }
  98. // ----------------------------------------------------------------------------
  99. float4 ParticlePixelShader(ParticleVSOutput In) : COLOR
  100. {
  101. float2 texCoord0 = In.ParticleTexCoord;
  102. float4 normalMapSample = tex2D( SAMPLER( NormalTexture ), texCoord0);
  103. // Get bump map normal
  104. float3 bumpNormal = normalMapSample.xyz * 2.0 - 1.0;
  105. // Scale normal to increase/decrease bump effect
  106. //bumpNormal.xy *= BumpScale;
  107. bumpNormal = normalize(bumpNormal);
  108. float3 normal = mul(bumpNormal, In.TangentToViewSpace);
  109. float4 color = float4(In.Color.xyz * normal * 0.5 + 0.5, In.Color.w * normalMapSample.w);
  110. return color;
  111. }
  112. // ----------------------------------------------------------------------------
  113. // TECHNIQUE: Default (Medium and up)
  114. // ----------------------------------------------------------------------------
  115. technique Default_M
  116. {
  117. pass P0
  118. <
  119. USE_EXPRESSION_EVALUATOR("Particle")
  120. >
  121. {
  122. VertexShader = compile VS_VERSION_HIGH ParticleVertexShader();
  123. PixelShader = compile PS_VERSION_HIGH ParticlePixelShader();
  124. ZEnable = true;
  125. ZFunc = ZFUNC_INFRONT;
  126. ZWriteEnable = false;
  127. CullMode = None;
  128. SETUP_ALPHA_BLEND_AND_TEST(Draw.ShaderType);
  129. #if !defined( _NO_FIXED_FUNCTION_ )
  130. FogEnable = false;
  131. #endif
  132. }
  133. }
  134. // ----------------------------------------------------------------------------
  135. // TECHNIQUE: LowQuality
  136. // ----------------------------------------------------------------------------
  137. technique Default_L
  138. {
  139. // Disabled
  140. }