ShatterEffect.fx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // MonoGame - Copyright (C) The MonoGame Team
  2. // This file is subject to the terms and conditions defined in
  3. // file 'LICENSE.txt', which is part of this source code package.
  4. #include "Macros.hlsl"
  5. float4x4 WorldViewProjection;
  6. float4x4 World : World;
  7. float RotationAmount;
  8. float TranslationAmount;
  9. float time;
  10. Texture2D modelTexture : register(t0);
  11. SamplerState TextureSampler : register(s0);
  12. // Lighting Data
  13. float3 eyePosition;
  14. float3 lightPosition;
  15. float4 ambientColor;
  16. float4 diffuseColor;
  17. float4 specularColor;
  18. float specularPower;
  19. struct VertexShaderOutput
  20. {
  21. float4 Position : SV_POSITION;
  22. float3 WorldNormal : TEXCOORD0;
  23. float3 WorldPosition : TEXCOORD1;
  24. float2 texCoords : TEXCOORD2;
  25. float4 Color : COLOR0;
  26. };
  27. struct PixelShaderInput
  28. {
  29. float3 WorldNormal : TEXCOORD0;
  30. float3 WorldPosition : TEXCOORD1;
  31. float2 TexCoords : TEXCOORD2;
  32. float4 Color: TEXCOORD3;
  33. };
  34. struct InputVS
  35. {
  36. float3 Position : POSITION;
  37. float3 Normal : NORMAL;
  38. float2 TexCoords : TEXCOORD0;
  39. float3 TriangleCenter : TEXCOORD1;
  40. float3 RotationalVelocity : TEXCOORD2;
  41. };
  42. // Helper function to create a YawPitchRoll Matrix.
  43. // Used to rotate the verticies by the random rotational values generated in the
  44. // processor.
  45. float4x4 CreateYawPitchRollMatrix(float x, float y, float z)
  46. {
  47. float4x4 result;
  48. result[0][0] = cos(z)*cos(y) + sin(z)*sin(x)*sin(y);
  49. result[0][1] = -sin(z)*cos(y) + cos(z)*sin(x)*sin(y);
  50. result[0][2] = cos(x)*sin(y);
  51. result[0][3] = 0;
  52. result[1][0] = sin(z)*cos(x);
  53. result[1][1] = cos(z)*cos(x);
  54. result[1][2] = -sin(x);
  55. result[1][3] = 0;
  56. result[2][0] = cos(z)*-sin(y) + sin(z)*sin(x)*cos(y);
  57. result[2][1] = sin(z)*sin(y) + cos(z)*sin(x)*cos(y);
  58. result[2][2] = cos(x)*cos(y);
  59. result[2][3] = 0;
  60. result[3][0] = 0;
  61. result[3][1] = 0;
  62. result[3][2] = 0;
  63. result[3][3] = 1;
  64. return result;
  65. }
  66. VertexShaderOutput ShatterVS(InputVS input)
  67. {
  68. VertexShaderOutput output = (VertexShaderOutput)0;
  69. // Shattering Calculations
  70. //
  71. // The shatter effect is pretty simple. First we create a YawPitchRoll Matrix based
  72. // on the random values we generated in the processor.
  73. // Second, we transform the vertex position by rotating it around it's center using
  74. // the rotation Matrix. Third, we translate the vertex along it's normal to have it
  75. // move outwards. Last, we drop the vertex along it's Y axis as a function of
  76. // time^2 to give a falling effect.
  77. // Create a rotation matrix
  78. input.RotationalVelocity *= RotationAmount;
  79. float4x4 rotMatrix = CreateYawPitchRollMatrix(input.RotationalVelocity.x,
  80. input.RotationalVelocity.y,
  81. input.RotationalVelocity.z);
  82. // Rotate the vertex around its triangle's center
  83. float3 position = input.TriangleCenter + mul(input.Position - input.TriangleCenter, rotMatrix);
  84. // Displace the vertex along its normal
  85. position += input.Normal * TranslationAmount;
  86. // Move the vertex downward as a function of time^2 to give a nice curvy falling
  87. // effect.
  88. position.y -= time*time * 200;
  89. // Proceed as usual
  90. output.Position = mul(float4(position,1.0),WorldViewProjection);
  91. // We must rotate the Normal as well for accurate lighting calculations.
  92. output.WorldNormal = mul(mul(input.Normal, rotMatrix), World);
  93. float4 worldPosition = mul(float4(position,1.0),World);
  94. output.WorldPosition = worldPosition / worldPosition.w;
  95. output.texCoords = input.TexCoords;
  96. //calculate diffuse component
  97. float3 directionToLight = normalize(lightPosition - output.WorldPosition);
  98. float diffuseIntensity = saturate( dot(directionToLight, output.WorldNormal));
  99. float4 diffuse = diffuseColor * diffuseIntensity;
  100. output.Color = diffuse + ambientColor;
  101. return output;
  102. }
  103. float4 PhongPS(PixelShaderInput input) : SV_Target
  104. {
  105. float3 directionToLight = normalize(lightPosition - input.WorldPosition);
  106. float3 reflectionVector = normalize(reflect(-directionToLight, input.WorldNormal));
  107. float3 directionToCamera = normalize(eyePosition - input.WorldPosition);
  108. float4 specular = specularColor *
  109. pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
  110. float4 TextureColor = modelTexture.Sample(TextureSampler, input.TexCoords);
  111. float4 color = TextureColor * input.Color + specular;
  112. color.a = 1.0;
  113. return color;
  114. }
  115. technique
  116. {
  117. pass
  118. {
  119. VertexShader = compile VS_SHADERMODEL ShatterVS();
  120. PixelShader = compile PS_SHADERMODEL PhongPS();
  121. }
  122. }