MuzzleFlash.fx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. //////////////////////////////////////////////////////////////////////////////
  2. // ©2005 Electronic Arts Inc
  3. //
  4. // FX Shader for Muzzle Flash
  5. // NOTE: This is using Vertex Alpha as a Material ID to render multiple
  6. // materials in one draw call, eg. tag all verts as 0-3 vertex alpha
  7. //////////////////////////////////////////////////////////////////////////////
  8. #define SUPPORT_FOG 1
  9. #include "Common.fxh"
  10. #include "Gamma.fxh"
  11. #if defined(EA_PLATFORM_WINDOWS)
  12. // ----------------------------------------------------------------------------
  13. // SAMPLER : nhendricks : had to pull these in here for MAX to compile
  14. // ----------------------------------------------------------------------------
  15. #define SAMPLER_2D_BEGIN(samplerName, annotations) \
  16. texture samplerName \
  17. < \
  18. annotations \
  19. >; \
  20. sampler2D samplerName##Sampler = sampler_state \
  21. { \
  22. Texture = < samplerName >;
  23. #define SAMPLER_2D_END };
  24. #define SAMPLER( samplerName ) samplerName##Sampler
  25. #define SAMPLER_CUBE_BEGIN(samplerName, annotations) \
  26. texture samplerName \
  27. < \
  28. annotations \
  29. >; \
  30. samplerCUBE samplerName##Sampler = sampler_state \
  31. { \
  32. Texture = < samplerName >;
  33. #define SAMPLER_CUBE_END };
  34. #endif
  35. // ----------------------------------------------------------------------------
  36. // Skinning
  37. // ----------------------------------------------------------------------------
  38. #define MaxSkinningBonesPerVertex 2
  39. #include "Skinning.fxh"
  40. // ----------------------------------------------------------------------------
  41. // Material parameters
  42. // ----------------------------------------------------------------------------
  43. float3 ColorEmissive
  44. <
  45. string UIName = "Emissive Material Color";
  46. string UIWidget = "Color";
  47. > = float3(1.0, 1.0, 1.0);
  48. SAMPLER_2D_BEGIN( Texture_0,
  49. string UIName = "Diffuse Texture";
  50. )
  51. MinFilter = MinFilterBest;
  52. MagFilter = MagFilterBest;
  53. MipFilter = MipFilterBest;
  54. // AddressU = Clamp;
  55. // AddressV = Clamp;
  56. SAMPLER_2D_END
  57. bool MultiTextureEnable
  58. <
  59. string UIName = "Multi Texture Enable";
  60. > = false;
  61. float TexCoordTransformAngle_0 // Note all rotation matricies ues this number
  62. <
  63. string UIName = "Radian Delta Rate per Frame";
  64. string UIWidget = "Slider";
  65. float UIMin = -100;
  66. float UIMax = 100;
  67. > = float(1.0);
  68. float TexCoordTransformU_0
  69. <
  70. string UIName = "Vertex ID 0 Rotation Center in U";
  71. string UIWidget = "Slider";
  72. float UIMin = 0;
  73. float UIMax = 1;
  74. > = float(.5);
  75. float TexCoordTransformV_0
  76. <
  77. string UIName = "Vertex ID 0 Rotation Center in V";
  78. string UIWidget = "Slider";
  79. float UIMin = 0;
  80. float UIMax = 1;
  81. > = float(.5);
  82. float TexCoordTransformU_1
  83. <
  84. string UIName = "Vertex ID 1 Rotation Center in U";
  85. string UIWidget = "Slider";
  86. float UIMin = 0;
  87. float UIMax = 1;
  88. > = float(.5);
  89. float TexCoordTransformV_1
  90. <
  91. string UIName = "Vertex ID 1 Rotation Center in V";
  92. string UIWidget = "Slider";
  93. float UIMin = 0;
  94. float UIMax = 1;
  95. > = float(.5);
  96. float TexCoordTransformU_2
  97. <
  98. string UIName = "Vertex ID 2 Rotation Center in U";
  99. string UIWidget = "Slider";
  100. float UIMin = 0;
  101. float UIMax = 1;
  102. > = float(.5);
  103. float TexCoordTransformV_2
  104. <
  105. string UIName = "Vertex ID 2 Rotation Center in V";
  106. string UIWidget = "Slider";
  107. float UIMin = 0;
  108. float UIMax = 1;
  109. > = float(.5);
  110. // ----------------------------------------------------------------------------
  111. // Shroud
  112. // ----------------------------------------------------------------------------
  113. ShroudSetup Shroud
  114. <
  115. string UIWidget = "None";
  116. #if !defined(_W3DVIEW_)
  117. string SasBindAddress = "Terrain.Shroud";
  118. #endif
  119. > = DEFAULT_SHROUD;
  120. SAMPLER_2D_BEGIN( ShroudTexture,
  121. string UIWidget = "None";
  122. string SasBindAddress = "Terrain.Shroud.Texture";
  123. )
  124. MinFilter = Linear;
  125. MagFilter = Linear;
  126. MipFilter = Linear;
  127. AddressU = Clamp;
  128. AddressV = Clamp;
  129. SAMPLER_2D_END
  130. // Variations for handling belnd mode differences in the pixel shader
  131. static const int BlendMode_Additive = 0;
  132. static const int BlendMode_Multiplicative = 1;
  133. #if defined(_WW3D_)
  134. #if !defined(USE_INDIRECT_CONSTANT)
  135. float4x4 ViewProjection
  136. <
  137. string UIWidget = "None";
  138. string SasBindAddress = "Sas.Camera.WorldToProjection";
  139. >;
  140. float3 EyePosition
  141. <
  142. string UIWidget = "None";
  143. string SasBindAddress = "Sas.Camera.Position";
  144. >;
  145. #endif // #if !defined(USE_INDIRECT_CONSTANT)
  146. float4x4 GetViewProjection()
  147. {
  148. return ViewProjection;
  149. }
  150. float3 GetEyePosition()
  151. {
  152. return EyePosition;
  153. }
  154. #else
  155. float4x4 View : View;
  156. float4x3 ViewI : ViewInverse;
  157. float4x4 Projection : Projection;
  158. float4x4 GetViewProjection()
  159. {
  160. return mul(View, Projection);
  161. }
  162. float3 GetEyePosition()
  163. {
  164. return ViewI[3];
  165. }
  166. #endif
  167. half Time : Time;
  168. // ----------------------------------------------------------------------------
  169. struct VSOutput
  170. {
  171. float4 Position : POSITION;
  172. float3 DiffuseColor : COLOR0;
  173. float Fog : COLOR1;
  174. float2 TexCoord0 : TEXCOORD0;
  175. float2 TexCoord1 : TEXCOORD1;
  176. float2 ShroudTexCoord : TEXCOORD2;
  177. };
  178. // ----------------------------------------------------------------------------
  179. VSOutput VS(VSInputSkinningMultipleBones InSkin,
  180. float4 VertexColor : COLOR0,
  181. float2 TexCoord0 : TEXCOORD0,
  182. uniform int numJointsPerVertex)
  183. {
  184. VSOutput Out;
  185. float3 worldPosition = 0;
  186. float3 worldNormal = 0;
  187. CalculatePositionAndNormal(InSkin, numJointsPerVertex, worldPosition, worldNormal);
  188. Out.Position = mul(float4(worldPosition, 1), GetViewProjection());
  189. // --------------------- Unlit colorization -----------------------
  190. #if defined(_3DSMAX_)
  191. // Default vertex color is 0 in Max, that's bad.
  192. VertexColor = 1.0;
  193. #endif
  194. // ----- Rotate with animated offset on texture coordinate 0 -----
  195. //Collapse MAX UI spinners to something useful
  196. float angle = TexCoordTransformAngle_0 * Time;
  197. float2 UVPivot0 = float2(TexCoordTransformU_0, TexCoordTransformV_0);
  198. float2 UVPivot1 = float2(TexCoordTransformU_1, TexCoordTransformV_1);
  199. float2 UVPivot2 = float2(TexCoordTransformU_2, TexCoordTransformV_2);
  200. float cosAngle, sinAngle;
  201. sincos (angle, sinAngle, cosAngle);
  202. float2x2 uvCoordRotate = { 1.0f, 0.0f, 1.0f, 0.0f };
  203. uvCoordRotate[0][0] = cosAngle;
  204. uvCoordRotate[0][1] = -sinAngle;
  205. uvCoordRotate[1][1] = uvCoordRotate[0][0];
  206. uvCoordRotate[1][0] = -uvCoordRotate[0][1];
  207. float2 texCoord0 = TexCoord0;
  208. float2 texCoord1 = TexCoord0;
  209. // Vertex alpha can be 0, 1 or 2 (in percent)
  210. VertexColor.w *= 100;
  211. // VertexColor.w = 2.4; //Debug for MAX as it does not read Vertex Color
  212. if (VertexColor.w < 0.5)
  213. {
  214. float2 texCoordCentered = TexCoord0 - UVPivot0;
  215. texCoord0 = mul(texCoordCentered, uvCoordRotate) + UVPivot0;
  216. if (MultiTextureEnable == true )
  217. {
  218. texCoord1 = mul(texCoordCentered, transpose(uvCoordRotate)) + UVPivot0;
  219. }
  220. else
  221. {
  222. texCoord1 = mul(texCoordCentered, uvCoordRotate) + UVPivot0;
  223. }
  224. }
  225. else if (VertexColor.w < 1.5)
  226. {
  227. float2 texCoordCentered = TexCoord0 - UVPivot1;
  228. texCoord0 = mul(texCoordCentered, uvCoordRotate) + UVPivot1;
  229. if (MultiTextureEnable == true )
  230. {
  231. texCoord1 = mul(texCoordCentered, transpose(uvCoordRotate)) + UVPivot1;
  232. }
  233. else
  234. {
  235. texCoord1 = mul(texCoordCentered, uvCoordRotate) + UVPivot1;
  236. }
  237. }
  238. else if (VertexColor.w < 2.5)
  239. {
  240. float2 texCoordCentered = TexCoord0 - UVPivot2;
  241. texCoord0 = mul(texCoordCentered, uvCoordRotate) + UVPivot2;
  242. if (MultiTextureEnable == true )
  243. {
  244. texCoord1 = mul(texCoordCentered, transpose(uvCoordRotate)) + UVPivot2;
  245. }
  246. else
  247. {
  248. texCoord1 = mul(texCoordCentered, uvCoordRotate) + UVPivot2;
  249. }
  250. }
  251. Out.TexCoord0 = texCoord0;
  252. Out.TexCoord1 = texCoord1;
  253. Out.DiffuseColor = VertexColor * ColorEmissive;
  254. // Calculate shroud texture coordinates
  255. Out.ShroudTexCoord = CalculateShroudTexCoord(Shroud, worldPosition);
  256. // Calculate fog
  257. Out.Fog = CalculateFog(Fog, worldPosition, GetEyePosition());
  258. return Out;
  259. }
  260. VSOutput VS_Xenon(VSInputSkinningMultipleBones InSkin,
  261. float4 VertexColor : COLOR0,
  262. float2 TexCoord0 : TEXCOORD0)
  263. {
  264. return VS(InSkin, VertexColor, TexCoord0, NumJointsPerVertex);
  265. }
  266. // ----------------------------------------------------------------------------
  267. float4 PS(VSOutput In, uniform int blendMode, uniform bool applyGammaCorrection) : COLOR0
  268. {
  269. // Get vertex color
  270. float4 texture0 = tex2D(SAMPLER(Texture_0), In.TexCoord0);
  271. float4 texture1 = tex2D(SAMPLER(Texture_0), In.TexCoord1);
  272. if (applyGammaCorrection)
  273. {
  274. texture0.xyz = GammaToLinear(texture0.xyz);
  275. texture1.xyz = GammaToLinear(texture1.xyz);
  276. }
  277. float4 color = float4(In.DiffuseColor, 1.0) * texture0 * texture1;
  278. // Apply shroud
  279. #if defined(_WW3D_) && !defined(_W3DVIEW_)
  280. float3 shroud = tex2D(SAMPLER(ShroudTexture), In.ShroudTexCoord);
  281. if (blendMode == BlendMode_Additive)
  282. {
  283. color.xyz *= shroud;
  284. }
  285. else if (blendMode == BlendMode_Multiplicative)
  286. {
  287. color.xyz = lerp(1.0.xxx, color.xyz, shroud);
  288. }
  289. #endif
  290. return color;
  291. }
  292. // ----------------------------------------------------------------------------
  293. // Arrays
  294. // ----------------------------------------------------------------------------
  295. #define VS_NumJointsPerVertex \
  296. compile VS_2_0 VS(0), \
  297. compile VS_2_0 VS(1), \
  298. compile VS_2_0 VS(2)
  299. DEFINE_ARRAY_MULTIPLIER( VS_Multiplier_Final = 3 );
  300. #if SUPPORTS_SHADER_ARRAYS
  301. vertexshader VS_Array[VS_Multiplier_Final] =
  302. {
  303. VS_NumJointsPerVertex
  304. };
  305. #endif
  306. // ----------------------------------------------------------------------------
  307. // Techniques: High LOD
  308. // ----------------------------------------------------------------------------
  309. technique Additive
  310. {
  311. pass P0
  312. {
  313. VertexShader = ARRAY_EXPRESSION_DIRECT_VS(VS_Array,
  314. min(NumJointsPerVertex, 2),
  315. compile VS_VERSION VS_Xenon()
  316. );
  317. PixelShader = compile PS_2_0 PS(BlendMode_Additive, true);
  318. ZEnable = true;
  319. ZFunc = ZFUNC_INFRONT;
  320. ZWriteEnable = false;
  321. CullMode = none;
  322. AlphaBlendEnable = true;
  323. SrcBlend = One;
  324. DestBlend = One;
  325. AlphaTestEnable = false;
  326. }
  327. }
  328. // ----------------------------------------------------------------------------
  329. technique Multiply
  330. {
  331. pass P0
  332. {
  333. VertexShader = ARRAY_EXPRESSION_DIRECT_VS(VS_Array,
  334. min(NumJointsPerVertex, 2),
  335. compile VS_VERSION VS_Xenon()
  336. );
  337. PixelShader = compile PS_2_0 PS(BlendMode_Multiplicative, true);
  338. ZEnable = true;
  339. ZFunc = ZFUNC_INFRONT;
  340. ZWriteEnable = false;
  341. CullMode = none;
  342. AlphaBlendEnable = true;
  343. SrcBlend = DestColor;
  344. DestBlend = Zero;
  345. AlphaTestEnable = false;
  346. }
  347. }
  348. #if ENABLE_LOD
  349. // ----------------------------------------------------------------------------
  350. // Techniques: Medium LOD
  351. // ----------------------------------------------------------------------------
  352. technique Additive_M
  353. {
  354. pass P0
  355. {
  356. VertexShader = ARRAY_EXPRESSION_DIRECT_VS(VS_Array,
  357. min(NumJointsPerVertex, 2),
  358. compile VS_VERSION VS_Xenon()
  359. );
  360. PixelShader = compile PS_2_0 PS(BlendMode_Additive, false);
  361. ZEnable = true;
  362. ZFunc = ZFUNC_INFRONT;
  363. ZWriteEnable = false;
  364. CullMode = none;
  365. AlphaBlendEnable = true;
  366. SrcBlend = One;
  367. DestBlend = One;
  368. AlphaTestEnable = false;
  369. }
  370. }
  371. // ----------------------------------------------------------------------------
  372. technique Multiply_M
  373. {
  374. pass P0
  375. {
  376. VertexShader = ARRAY_EXPRESSION_DIRECT_VS(VS_Array,
  377. min(NumJointsPerVertex, 2),
  378. compile VS_VERSION VS_Xenon()
  379. );
  380. PixelShader = compile PS_2_0 PS(BlendMode_Multiplicative, false);
  381. ZEnable = true;
  382. ZFunc = ZFUNC_INFRONT;
  383. ZWriteEnable = false;
  384. CullMode = none;
  385. AlphaBlendEnable = true;
  386. SrcBlend = DestColor;
  387. DestBlend = Zero;
  388. AlphaTestEnable = false;
  389. }
  390. }
  391. #endif // if ENABLE_LOD