FXShield.fx 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. //////////////////////////////////////////////////////////////////////////////
  2. // ©2008 Electronic Arts Inc
  3. //
  4. // FX Shader for Shield FX (unlit, 2 texture solution, assumed additive)
  5. //////////////////////////////////////////////////////////////////////////////
  6. #define SUPPORT_FOG 1
  7. #include "Common.fxh"
  8. #include "Gamma.fxh"
  9. #include "Random.fxh"
  10. #if defined(EA_PLATFORM_WINDOWS) && defined(_3DSMAX_)
  11. // ----------------------------------------------------------------------------
  12. // SAMPLER : nhendricks : had to pull these in here for MAX to compile
  13. // ----------------------------------------------------------------------------
  14. #define SAMPLER_2D_BEGIN(samplerName, annotations) \
  15. texture samplerName \
  16. < \
  17. annotations \
  18. >; \
  19. sampler2D samplerName##Sampler = sampler_state \
  20. { \
  21. Texture = < samplerName >;
  22. #define SAMPLER_2D_END };
  23. #define SAMPLER( samplerName ) samplerName##Sampler
  24. #define SAMPLER_CUBE_BEGIN(samplerName, annotations) \
  25. texture samplerName \
  26. < \
  27. annotations \
  28. >; \
  29. samplerCUBE samplerName##Sampler = sampler_state \
  30. { \
  31. Texture = < samplerName >;
  32. #define SAMPLER_CUBE_END };
  33. #endif
  34. // ----------------------------------------------------------------------------
  35. // Skinning
  36. // ----------------------------------------------------------------------------
  37. static const int MaxSkinningBonesPerVertex = 2;
  38. #include "Skinning.fxh"
  39. // ----------------------------------------------------------------------------
  40. // Transformations
  41. // ----------------------------------------------------------------------------
  42. float4x4 Projection : Projection;
  43. float4x4 View : View;
  44. float4x3 ViewI : ViewInverse;
  45. float4x4 ProjectionI : ProjectionInverse;
  46. float Time : Time;
  47. #if defined(_WW3D_)
  48. #if !defined(USE_INDIRECT_CONSTANT)
  49. float4x4 ViewProjection
  50. <
  51. string UIWidget = "None";
  52. string SasBindAddress = "Sas.Camera.WorldToProjection";
  53. >;
  54. float3 EyePosition
  55. <
  56. string UIWidget = "None";
  57. string SasBindAddress = "Sas.Camera.Position";
  58. >;
  59. #endif // #if !defined(USE_INDIRECT_CONSTANT)
  60. float4x4 GetViewProjection()
  61. {
  62. return ViewProjection;
  63. }
  64. float3 GetEyePosition()
  65. {
  66. return EyePosition;
  67. }
  68. #else // #if defined(_WW3D_)
  69. float4x4 GetViewProjection()
  70. {
  71. return mul(View, Projection);
  72. }
  73. float3 GetEyePosition()
  74. {
  75. return ViewI[3];
  76. }
  77. #endif // #if defined(_WW3D_)
  78. // Used to see where the shader volume intersects an object.
  79. SAMPLER_2D_BEGIN( DepthTexture,
  80. string SasBindAddress = "WW3D.DepthTexture";
  81. )
  82. MinFilter = Linear;
  83. MagFilter = Linear;
  84. MipFilter = Point;
  85. AddressU = Clamp;
  86. AddressV = Clamp;
  87. SAMPLER_2D_END
  88. // ----------------------------------------------------------------------------
  89. // Material parameters
  90. // ----------------------------------------------------------------------------
  91. SAMPLER_2D_BEGIN( Texture_0,
  92. string UIName = "Diffuse Texture";
  93. )
  94. MinFilter = MinFilterBest;
  95. MagFilter = MagFilterBest;
  96. MipFilter = MipFilterBest;
  97. AddressU = Wrap;
  98. AddressV = Wrap;
  99. SAMPLER_2D_END
  100. bool OpacityOverrideEnable
  101. <
  102. string UIName = "Use Opacity Override for Keyframes";
  103. > = true;
  104. float3 ColorDiffuseKey1
  105. <
  106. string UIName = "Diffuse Material Color Keyframe 1";
  107. string UIWidget = "Color";
  108. > = float3(1.0, 1.0, 1.0);
  109. float3 ColorDiffuseKey2
  110. <
  111. string UIName = "Diffuse Material Color Keyframe 2";
  112. string UIWidget = "Color";
  113. > = float3(1.0, 1.0, 1.0);
  114. float EmissiveHDRMultipler
  115. <
  116. string UIName = "HDR Multiplier";
  117. string UIWidget = "Slider";
  118. float UIMax = 200;
  119. > = 1.0;
  120. bool MultiTextureEnable
  121. <
  122. string UIName = "Multi-Texture Enable";
  123. > = false;
  124. bool MultiplyBlendEnable
  125. <
  126. string UIName = "Multiply Enable";
  127. > = false;
  128. float4 DiffuseCoordOffset
  129. <
  130. string UIName = "Diffuse Coord Offset/Scale";
  131. string UIWidget = "Slider";
  132. float UIMax = 1.0f;
  133. float UIMin = 0;
  134. float UIStep = 0.001f;
  135. > = float4(0.00, 0.00, 1.0, 1.0);
  136. float IntersectionMultiplier
  137. <
  138. string UIName = "Intersection Multiplier: In Game Only";
  139. string UIWidget = "Slider";
  140. float UIMax = 100.0f;
  141. float UIMin = 0.0f;
  142. > = 1.0f;
  143. float EdgeFadeOut
  144. <
  145. string UIName = "Edge Fade: Linear";
  146. string UIWidget = "Slider";
  147. float UIMax = 10.0f;
  148. float UIMin = -10.0f;
  149. > = 0.0f;
  150. bool TextureFadeOutEnable
  151. <
  152. string UIName = "Edge Fade: Custom LUT";
  153. > = false;
  154. SAMPLER_2D_BEGIN( TextureFadeOut,
  155. string UIName = "Edge Fade LUT";
  156. )
  157. MinFilter = MinFilterBest;
  158. MagFilter = MagFilterBest;
  159. MipFilter = MipFilterBest;
  160. AddressU = Clamp;
  161. AddressV = Clamp;
  162. SAMPLER_2D_END
  163. // ----------------------------------------------------------------------------
  164. // Displace Mapping
  165. // ----------------------------------------------------------------------------
  166. SAMPLER_2D_BEGIN( Texture_1,
  167. string UIName = "Displace Texture";
  168. )
  169. MinFilter = MinFilterBest;
  170. MagFilter = MagFilterBest;
  171. MipFilter = MipFilterBest;
  172. AddressU = Wrap;
  173. AddressV = Wrap;
  174. SAMPLER_2D_END
  175. float DisplaceScalar
  176. <
  177. string UIName = "Displace Scale";
  178. string UIWidget = "Slider";
  179. float UIMax = 50.0f;
  180. float UIMin = 0;
  181. float UIStep = 0.01f;
  182. > = 1.0;
  183. float DisplaceAmp
  184. <
  185. string UIName = "Displace Amplitude";
  186. string UIWidget = "Slider";
  187. float UIMax = 50.0f;
  188. float UIMin = 0;
  189. float UIStep = 0.01f;
  190. > = 1.0;
  191. float DisplaceDivergenceAngle
  192. <
  193. string UIName = "Displace Divergence Angle";
  194. string UIWidget = "Slider";
  195. float UIMax = 180.0f;
  196. float UIMin = 0;
  197. float UIStep = 0.5f;
  198. > = 0.0;
  199. float DisplaceSpeed
  200. <
  201. string UIName = "Displace Speed";
  202. string UIWidget = "Slider";
  203. float UIMax = 50.0f;
  204. float UIMin = 0;
  205. float UIStep = 0.01f;
  206. > = 1.0;
  207. bool CullingEnable
  208. <
  209. string UIName = "Culling Enable";
  210. > = true;
  211. #if !defined(USE_INDIRECT_CONSTANT)
  212. float OpacityOverride
  213. <
  214. string UIWidget = "None";
  215. string SasBindAddress = "WW3D.OpacityOverride";
  216. > = 1.0;
  217. #endif // #if !defined(USE_INDIRECT_CONSTANT)
  218. // ----------------------------------------------------------------------------
  219. // SHADER : DEFAULT
  220. // ----------------------------------------------------------------------------
  221. struct VSOutput
  222. {
  223. float4 Position : POSITION;
  224. float4 DiffuseColor : TEXCOORD0;
  225. float4 DiffuseTexCoord : TEXCOORD1;
  226. float4 DisplaceTexCoord : TEXCOORD2;
  227. float2 EdgeFadeValue_Fog: TEXCOORD3;
  228. #if !defined(_3DSMAX_)
  229. float2 ZPositions : TEXCOORD5; // x is z position, y is the ViewEyeDirection z component.
  230. float4 NDCPosition : TEXCOORD6;
  231. #endif // !defined(_3DSMAX_)
  232. };
  233. // ----------------------------------------------------------------------------
  234. VSOutput VS(VSInputSkinningMultipleBones InSkin,
  235. float2 TexCoord0 : TEXCOORD0,
  236. float4 VertexColor: COLOR0,
  237. uniform int numJointsPerVertex)
  238. {
  239. VSOutput Out;
  240. float3 worldPosition = 0;
  241. float3 worldNormal = 0;
  242. CalculatePositionAndNormal(InSkin, numJointsPerVertex, worldPosition, worldNormal);
  243. #if defined(_3DSMAX_)
  244. // Default vertex color is 0 in Max, that's bad.
  245. VertexColor = 1.0;
  246. // A little bit better motion previewing in MAX
  247. Time *= .25;
  248. #endif
  249. //Calculate the displace texture coordinates
  250. DisplaceSpeed *= Time * .01; // animate Displace as a multiplier of Time with a happy MAX modifier
  251. float2 DisplaceTexCoords = TexCoord0 * DisplaceScalar;
  252. // Build Displace Texture Rotation Matrix And Convert Degrees to Radians -----
  253. float cosAngle, sinAngle;
  254. cosAngle = 0;
  255. sinAngle = 0;
  256. float2x2 uvCoordRotate = { 1.0f, 0.0f, 1.0f, 0.0f };
  257. sincos (DisplaceDivergenceAngle * .017453, sinAngle, cosAngle);
  258. uvCoordRotate[0][0] = cosAngle;
  259. uvCoordRotate[0][1] = -sinAngle;
  260. uvCoordRotate[1][1] = uvCoordRotate[0][0];
  261. uvCoordRotate[1][0] = -uvCoordRotate[0][1];
  262. // Rotate and Animate Displace Divergence Texture Coords --------------------
  263. float2 DisplaceTexCoordsDiverge = mul(DisplaceTexCoords, uvCoordRotate);
  264. DisplaceTexCoordsDiverge.x += DisplaceSpeed;
  265. float2 DisplaceTexCoordsDivergeInv = mul(DisplaceTexCoords, transpose(uvCoordRotate));
  266. DisplaceTexCoordsDivergeInv.x += DisplaceSpeed;
  267. // Compute view direction in world space
  268. float3 worldEyeDir = normalize(GetEyePosition() - worldPosition);
  269. float viewingAngle = abs(dot(worldEyeDir,normalize(worldNormal)));
  270. float fadeOut = 0;
  271. Out.EdgeFadeValue_Fog.x = 0;
  272. if (TextureFadeOutEnable == true)
  273. {
  274. Out.EdgeFadeValue_Fog.x = saturate(1 - viewingAngle); // Used in texcoords for per pixel calcultion
  275. }
  276. else
  277. {
  278. if (EdgeFadeOut >= 0)
  279. {
  280. fadeOut = smoothstep(0, EdgeFadeOut, viewingAngle); // Soften Edges
  281. }
  282. else
  283. {
  284. fadeOut = smoothstep(abs(EdgeFadeOut), 0, viewingAngle); // Soften Center
  285. }
  286. Out.EdgeFadeValue_Fog.x = fadeOut;
  287. }
  288. // Compute Diffuse Color and Final Vertex Color
  289. float3 diffuseColorKeyCurrent = 0;
  290. if (OpacityOverrideEnable == true) // Lerp between the 2 key colors using OpacityOverride to drive it
  291. {
  292. // float3 diffuseColorKeyCurrent = lerp(ColorDiffuseKey1, ColorDiffuseKey2, OpacityOverride); // <----- Gavin use me for the final
  293. // Use this temporarily till enginering has the hooks
  294. diffuseColorKeyCurrent = ColorDiffuseKey1; // <----- Gavin delete me in the final
  295. Out.DiffuseColor = VertexColor * float4(diffuseColorKeyCurrent,1);
  296. }
  297. else // Use it for its intended purpose
  298. {
  299. diffuseColorKeyCurrent = ColorDiffuseKey1;
  300. Out.DiffuseColor = VertexColor * float4(diffuseColorKeyCurrent,1) * OpacityOverride;
  301. }
  302. // Compute all registers
  303. Out.Position = mul(float4(worldPosition, 1), GetViewProjection());
  304. TexCoord0.xy *= DiffuseCoordOffset.zw;
  305. // Restrict the numerical range to 0-1 to hide precision issues in the texture sampling when Time goes really large
  306. float2 offset = frac(DiffuseCoordOffset.xy * Time);
  307. Out.DiffuseTexCoord.xyzw = TexCoord0.xyxy + offset.xyxy;
  308. if (MultiTextureEnable == true )
  309. {
  310. Out.DiffuseTexCoord.zw = TexCoord0.xy * DiffuseCoordOffset.zw - offset;
  311. }
  312. Out.DisplaceTexCoord = float4(DisplaceTexCoordsDiverge, DisplaceTexCoordsDivergeInv);
  313. Out.EdgeFadeValue_Fog.y = CalculateFog(Fog, worldPosition, GetEyePosition());
  314. #if !defined(_3DSMAX_)
  315. // --------------------------------------------------------------------------------------------------------
  316. // ------------------------------ Generate Z-depth information --------------------------------------------
  317. // --------------------------------------------------------------------------------------------------------
  318. #define OUTLINE_SCALE 5 //Increase to make the outline bigger
  319. // Convert the vertex position into view space so that we can get the distance between the vertex and the background
  320. float4 vertexPosView = mul(float4(worldPosition, 1), View);
  321. // Finish projecting the position.
  322. float4 ndcPos = mul(vertexPosView, Projection);
  323. Out.NDCPosition = ndcPos;
  324. // Convert the position into a view vector to the far plane.
  325. float4 screenFarPlanePosition = float4(ndcPos.xy, 1, 1);
  326. float4 viewFarPlanePosition4 = mul(screenFarPlanePosition, ProjectionI);
  327. float3 viewFarPlanePosition = viewFarPlanePosition4.xyz / viewFarPlanePosition4.w;
  328. // We don't really want a vector to the far plane. We want the vector with a z length of 1,
  329. // so that we know how much in x-y we need to step per z-depth that we get from the depth texture.
  330. Out.ZPositions.x = vertexPosView.z / OUTLINE_SCALE;
  331. Out.ZPositions.y = (viewFarPlanePosition.z / viewFarPlanePosition.z) / OUTLINE_SCALE;
  332. #endif // !defined(_3DSMAX_)
  333. return Out;
  334. }
  335. // ----------------------------------------------------------------------------
  336. float4 PS(VSOutput In) : COLOR
  337. {
  338. //-------------------------------------------------------------------------
  339. // Shared between Additive and Multiplicitive -----------------------------
  340. //-------------------------------------------------------------------------
  341. float4 color = In.DiffuseColor; // Get vertex color value
  342. float fogStrength = In.EdgeFadeValue_Fog.y; // Get fog value
  343. float3 textureDisplace = tex2D( SAMPLER(Texture_1), In.DisplaceTexCoord.xy); // Get first texture pass of Displaced Coords
  344. textureDisplace += tex2D( SAMPLER(Texture_1), In.DisplaceTexCoord.zw); // Multiply against second pass
  345. textureDisplace = textureDisplace - 1; // Normalize as these are normal maps
  346. // Create displaced texture coords
  347. float4 displacedTextureCoords = In.DiffuseTexCoord + (textureDisplace.xyxy * DisplaceAmp); // Create final texture coords
  348. // Look up diffuse texture using displaced texture coords
  349. float4 textureDiffuse = tex2D( SAMPLER(Texture_0), displacedTextureCoords.xy);
  350. // If using multiple textures do...
  351. if (MultiTextureEnable)
  352. {
  353. textureDiffuse *= tex2D( SAMPLER(Texture_0), displacedTextureCoords.zw);
  354. }
  355. textureDiffuse.xyz = GammaToLinear(textureDiffuse.xyz); // Correct for gamma rendering
  356. // Create texture falloff value
  357. float textureFalloff = 0; // Float defined
  358. if (TextureFadeOutEnable == true) // If using texture LUT for falloff do...
  359. {
  360. textureFalloff = tex2D( SAMPLER(TextureFadeOut), float2(In.EdgeFadeValue_Fog.x,1) );
  361. }
  362. else // Use pure vertex calculated falloff value
  363. {
  364. textureFalloff = In.EdgeFadeValue_Fog.x;
  365. }
  366. #if !defined(_3DSMAX_)
  367. // Use Z depth information
  368. float3 ndcPosition = In.NDCPosition.xyz / In.NDCPosition.w;
  369. // Convert the position into texture space then grab the depth value from the
  370. // depth texture. Then, move along that vector by the depth to find the pixel position.
  371. float2 depthTexCoord = ndcPosition.xy * float2(0.5, -0.5) + 0.5;
  372. float backgroundDepth = tex2D(SAMPLER(DepthTexture), depthTexCoord).x;
  373. float backgroundPosView = backgroundDepth * In.ZPositions.y;
  374. // The closer the particle is to the background, the more transparent it is.
  375. float outlineBlend = saturate(In.ZPositions.x - backgroundPosView);
  376. float outlineDiffuse = tex2D( SAMPLER(TextureFadeOut), float2(1-outlineBlend.x,1) ) * color.xyz * IntersectionMultiplier;
  377. #else
  378. float outlineDiffuse =1;
  379. #endif // !defined(_3DSMAX_)
  380. //-------------------------------------------------------------------------
  381. // Additive ---------------------------------------------------------------
  382. //-------------------------------------------------------------------------
  383. if (MultiplyBlendEnable == false) // If additive do...
  384. {
  385. // Multiply diffuse colors by HDR multiplier if shader is additive
  386. color = float4(In.DiffuseColor.xyz * EmissiveHDRMultipler, In.DiffuseColor.w);
  387. // Overbrighten
  388. color.xyz += color.xyz;
  389. // Output final color
  390. textureDiffuse = (color + outlineDiffuse) * textureDiffuse * textureFalloff * fogStrength;
  391. }
  392. //-------------------------------------------------------------------------
  393. // Multiplicitive ---------------------------------------------------------
  394. //-------------------------------------------------------------------------
  395. else // if Multiplicitive do...
  396. {
  397. // Output final color
  398. // Yes we need to take the inverted VertexColor to multiply against everything else
  399. // so that when we invert the whole equation we get the original color correctly
  400. // multiplied aginst the other values. This allows us to specifiy a single color
  401. // that works for both additive and multiplicitve. mjones
  402. textureDiffuse = 1 - (1 - (color - outlineDiffuse)) * textureDiffuse * textureFalloff * fogStrength * EmissiveHDRMultipler;
  403. textureDiffuse = max(textureDiffuse,0); // Clamp value to > 0 so as to avoid rendering artifacts when working with negative blend numbers
  404. }
  405. //-------------------------------------------------------------------------
  406. // Global shader wrap-up --------------------------------------------------
  407. //-------------------------------------------------------------------------
  408. color.xyz = textureDiffuse;
  409. return color;
  410. }
  411. // ----------------------------------------------------------------------------
  412. // SHADER : MEDIUM
  413. // ----------------------------------------------------------------------------
  414. struct VSOutput_M
  415. {
  416. float4 Position : POSITION;
  417. float4 DiffuseColor : TEXCOORD0;
  418. float4 DiffuseTexCoord : TEXCOORD1;
  419. float4 DisplaceTexCoord : TEXCOORD2;
  420. float2 EdgeFadeValue_Fog: TEXCOORD3;
  421. };
  422. // ----------------------------------------------------------------------------
  423. VSOutput_M VS_M(VSInputSkinningMultipleBones InSkin,
  424. float2 TexCoord0 : TEXCOORD0,
  425. float4 VertexColor: COLOR0,
  426. uniform int numJointsPerVertex)
  427. {
  428. VSOutput_M Out;
  429. float3 worldPosition = 0;
  430. float3 worldNormal = 0;
  431. CalculatePositionAndNormal(InSkin, numJointsPerVertex, worldPosition, worldNormal);
  432. #if defined(_3DSMAX_)
  433. // Default vertex color is 0 in Max, that's bad.
  434. VertexColor = 1.0;
  435. // A little bit better motion previewing in MAX
  436. Time *= .25;
  437. #endif
  438. //Calculate the displace texture coordinates
  439. DisplaceSpeed *= Time * .01; // animate Displace as a multiplier of Time with a happy MAX modifier
  440. float2 DisplaceTexCoords = TexCoord0 * DisplaceScalar;
  441. // Build Displace Texture Rotation Matrix And Convert Degrees to Radians -----
  442. float cosAngle, sinAngle;
  443. cosAngle = 0;
  444. sinAngle = 0;
  445. float2x2 uvCoordRotate = { 1.0f, 0.0f, 1.0f, 0.0f };
  446. sincos (DisplaceDivergenceAngle * .017453, sinAngle, cosAngle);
  447. uvCoordRotate[0][0] = cosAngle;
  448. uvCoordRotate[0][1] = -sinAngle;
  449. uvCoordRotate[1][1] = uvCoordRotate[0][0];
  450. uvCoordRotate[1][0] = -uvCoordRotate[0][1];
  451. // Rotate and Animate Displace Divergence Texture Coords --------------------
  452. float2 DisplaceTexCoordsDiverge = mul(DisplaceTexCoords, uvCoordRotate);
  453. DisplaceTexCoordsDiverge.x += DisplaceSpeed;
  454. float2 DisplaceTexCoordsDivergeInv = mul(DisplaceTexCoords, transpose(uvCoordRotate));
  455. DisplaceTexCoordsDivergeInv.x += DisplaceSpeed;
  456. // Compute view direction in world space
  457. float3 worldEyeDir = normalize(GetEyePosition() - worldPosition);
  458. float viewingAngle = abs(dot(worldEyeDir,normalize(worldNormal)));
  459. float fadeOut = 0;
  460. Out.EdgeFadeValue_Fog.x = 0;
  461. if (TextureFadeOutEnable == true)
  462. {
  463. Out.EdgeFadeValue_Fog.x = saturate(1 - viewingAngle); // Used in texcoords for per pixel calcultion
  464. }
  465. else
  466. {
  467. if (EdgeFadeOut >= 0)
  468. {
  469. fadeOut = smoothstep(0, EdgeFadeOut, viewingAngle); // Soften Edges
  470. }
  471. else
  472. {
  473. fadeOut = smoothstep(abs(EdgeFadeOut), 0, viewingAngle); // Soften Center
  474. }
  475. Out.EdgeFadeValue_Fog.x = fadeOut;
  476. }
  477. // Compute Diffuse Color and Final Vertex Color
  478. float3 diffuseColorKeyCurrent = 0;
  479. if (OpacityOverrideEnable == true) // Lerp between the 2 key colors using OpacityOverride to drive it
  480. {
  481. // float3 diffuseColorKeyCurrent = lerp(ColorDiffuseKey1, ColorDiffuseKey2, OpacityOverride); // <----- Gavin use me for the final
  482. // Use this temporarily till enginering has the hooks
  483. diffuseColorKeyCurrent = ColorDiffuseKey1; // <----- Gavin delete me in the final
  484. Out.DiffuseColor = VertexColor * float4(diffuseColorKeyCurrent,1);
  485. }
  486. else // Use it for its intended purpose
  487. {
  488. diffuseColorKeyCurrent = ColorDiffuseKey1;
  489. Out.DiffuseColor = VertexColor * float4(diffuseColorKeyCurrent,1) * OpacityOverride;
  490. }
  491. // Compute all registers
  492. Out.Position = mul(float4(worldPosition, 1), GetViewProjection());
  493. TexCoord0.xy *= DiffuseCoordOffset.zw;
  494. // Restrict the numerical range to 0-1 to hide precision issues in the texture sampling when Time goes really large
  495. float2 offset = frac(DiffuseCoordOffset.xy * Time);
  496. Out.DiffuseTexCoord.xyzw = TexCoord0.xyxy + offset.xyxy;
  497. if (MultiTextureEnable == true )
  498. {
  499. Out.DiffuseTexCoord.zw = TexCoord0.xy * DiffuseCoordOffset.zw - offset;
  500. }
  501. Out.DisplaceTexCoord = float4(DisplaceTexCoordsDiverge, DisplaceTexCoordsDivergeInv);
  502. Out.EdgeFadeValue_Fog.y = CalculateFog(Fog, worldPosition, GetEyePosition());
  503. return Out;
  504. }
  505. // ----------------------------------------------------------------------------
  506. float4 PS_M(VSOutput_M In) : COLOR
  507. {
  508. //-------------------------------------------------------------------------
  509. // Shared between Additive and Multiplicitive -----------------------------
  510. //-------------------------------------------------------------------------
  511. float4 color = In.DiffuseColor; // Get vertex color value
  512. float fogStrength = In.EdgeFadeValue_Fog.y; // Get fog value
  513. float3 textureDisplace = tex2D( SAMPLER(Texture_1), In.DisplaceTexCoord.xy); // Get first texture pass of Displaced Coords
  514. textureDisplace += tex2D( SAMPLER(Texture_1), In.DisplaceTexCoord.zw); // Multiply against second pass
  515. textureDisplace = textureDisplace - 1; // Normalize as these are normal maps
  516. // Create displaced texture coords
  517. float4 displacedTextureCoords = In.DiffuseTexCoord + (textureDisplace.xyxy * DisplaceAmp); // Create final texture coords
  518. // Look up diffuse texture using displaced texture coords
  519. float4 textureDiffuse = tex2D( SAMPLER(Texture_0), displacedTextureCoords.xy);
  520. // If using multiple textures do...
  521. if (MultiTextureEnable)
  522. {
  523. textureDiffuse *= tex2D( SAMPLER(Texture_0), displacedTextureCoords.zw);
  524. }
  525. // Create texture falloff value
  526. float textureFalloff = 0; // Float defined
  527. if (TextureFadeOutEnable == true) // If using texture LUT for falloff do...
  528. {
  529. textureFalloff = tex2D( SAMPLER(TextureFadeOut), float2(In.EdgeFadeValue_Fog.x,1) );
  530. }
  531. else // Use pure vertex calculated falloff value
  532. {
  533. textureFalloff = In.EdgeFadeValue_Fog.x;
  534. }
  535. //-------------------------------------------------------------------------
  536. // Additive ---------------------------------------------------------------
  537. //-------------------------------------------------------------------------
  538. if (MultiplyBlendEnable == false) // If additive do...
  539. {
  540. // Multiply diffuse colors by HDR multiplier if shader is additive
  541. color = float4(In.DiffuseColor.xyz * EmissiveHDRMultipler, In.DiffuseColor.w);
  542. // Overbrighten
  543. color.xyz += color.xyz;
  544. // Output final color
  545. textureDiffuse = color * textureDiffuse * textureFalloff * fogStrength;
  546. }
  547. //-------------------------------------------------------------------------
  548. // Multiplicitive ---------------------------------------------------------
  549. //-------------------------------------------------------------------------
  550. else // if Multiplicitive do...
  551. {
  552. // Output final color
  553. // Yes we need to take the inverted VertexColor to multiply against everything else
  554. // so that when we invert the whole equation we get the original color correctly
  555. // multiplied aginst the other values. This allows us to specifiy a single color
  556. // that works for both additive and multiplicitve. mjones
  557. textureDiffuse = 1 - (1 - color) * textureDiffuse * textureFalloff * fogStrength * EmissiveHDRMultipler;
  558. textureDiffuse = max(textureDiffuse,0); // Clamp value to > 0 so as to avoid rendering artifacts when working with negative blend numbers
  559. }
  560. //-------------------------------------------------------------------------
  561. // Global shader wrap-up --------------------------------------------------
  562. //-------------------------------------------------------------------------
  563. color.xyz = textureDiffuse;
  564. return color;
  565. }
  566. // ----------------------------------------------------------------------------
  567. // SHADER : LOW
  568. // ----------------------------------------------------------------------------
  569. struct VSOutput_L
  570. {
  571. float4 Position : POSITION;
  572. float4 DiffuseColor : TEXCOORD0;
  573. float4 DiffuseTexCoord : TEXCOORD1;
  574. float2 EdgeFadeValue_Fog: TEXCOORD2;
  575. };
  576. // ----------------------------------------------------------------------------
  577. VSOutput_L VS_L(VSInputSkinningMultipleBones InSkin,
  578. float2 TexCoord0 : TEXCOORD0,
  579. float4 VertexColor: COLOR0,
  580. uniform int numJointsPerVertex)
  581. {
  582. VSOutput_L Out;
  583. float3 worldPosition = 0;
  584. float3 worldNormal = 0;
  585. CalculatePositionAndNormal(InSkin, numJointsPerVertex, worldPosition, worldNormal);
  586. #if defined(_3DSMAX_)
  587. VertexColor = 1.0; // Default vertex color is 0 in Max, that's bad.
  588. Time *= .25; // A little bit better motion previewing in MAX
  589. #endif
  590. // Compute view direction in world space
  591. float3 worldEyeDir = normalize(GetEyePosition() - worldPosition);
  592. float viewingAngle = abs(dot(worldEyeDir,normalize(worldNormal)));
  593. float fadeOut = 0;
  594. Out.EdgeFadeValue_Fog.x = 0;
  595. if (TextureFadeOutEnable == true)
  596. {
  597. Out.EdgeFadeValue_Fog.x = saturate(1 - viewingAngle); // Used in texcoords for per pixel calcultion
  598. }
  599. else
  600. {
  601. if (EdgeFadeOut >= 0)
  602. {
  603. fadeOut = smoothstep(0, EdgeFadeOut, viewingAngle); // Soften Edges
  604. }
  605. else
  606. {
  607. fadeOut = smoothstep(abs(EdgeFadeOut), 0, viewingAngle); // Soften Center
  608. }
  609. Out.EdgeFadeValue_Fog.x = fadeOut;
  610. }
  611. // Compute Diffuse Color and Final Vertex Color
  612. float3 diffuseColorKeyCurrent = 0;
  613. if (OpacityOverrideEnable == true) // Lerp between the 2 key colors using OpacityOverride to drive it
  614. {
  615. // float3 diffuseColorKeyCurrent = lerp(ColorDiffuseKey1, ColorDiffuseKey2, OpacityOverride); // <----- Gavin use me for the final
  616. // Use this temporarily till enginering has the hooks
  617. diffuseColorKeyCurrent = ColorDiffuseKey1; // <----- Gavin delete me in the final
  618. Out.DiffuseColor = VertexColor * float4(diffuseColorKeyCurrent,1);
  619. }
  620. else // Use it for its intended purpose
  621. {
  622. diffuseColorKeyCurrent = ColorDiffuseKey1;
  623. Out.DiffuseColor = VertexColor * float4(diffuseColorKeyCurrent,1) * OpacityOverride;
  624. }
  625. // Compute all registers
  626. Out.Position = mul(float4(worldPosition, 1), GetViewProjection());
  627. TexCoord0.xy *= DiffuseCoordOffset.zw;
  628. // Restrict the numerical range to 0-1 to hide precision issues in the texture sampling when Time goes really large
  629. float2 offset = frac(DiffuseCoordOffset.xy * Time);
  630. Out.DiffuseTexCoord.xyzw = TexCoord0.xyxy + offset.xyxy;
  631. if (MultiTextureEnable == true )
  632. {
  633. Out.DiffuseTexCoord.zw = TexCoord0.xy * DiffuseCoordOffset.zw - offset;
  634. }
  635. Out.EdgeFadeValue_Fog.y = CalculateFog(Fog, worldPosition, GetEyePosition());
  636. return Out;
  637. }
  638. // ----------------------------------------------------------------------------
  639. float4 PS_L(VSOutput_L In) : COLOR
  640. {
  641. //-------------------------------------------------------------------------
  642. // Shared between Additive and Multiplicitive -----------------------------
  643. //-------------------------------------------------------------------------
  644. float4 color = In.DiffuseColor; // Get vertex color value
  645. float fogStrength = In.EdgeFadeValue_Fog.y; // Get fog value
  646. // Look up diffuse texture using displaced texture coords
  647. float4 textureDiffuse = tex2D( SAMPLER(Texture_0), In.DiffuseTexCoord.xy);
  648. if (MultiTextureEnable) // If using multiple textures do...
  649. {
  650. textureDiffuse *= tex2D( SAMPLER(Texture_0), In.DiffuseTexCoord.zw);
  651. }
  652. // Create texture falloff value
  653. float textureFalloff = 0; // Float defined
  654. if (TextureFadeOutEnable == true) // If using texture LUT for falloff do...
  655. {
  656. textureFalloff = tex2D( SAMPLER(TextureFadeOut), float2(In.EdgeFadeValue_Fog.x,1) );
  657. }
  658. else // Use pure vertex calculated falloff value
  659. {
  660. textureFalloff = In.EdgeFadeValue_Fog.x;
  661. }
  662. //-------------------------------------------------------------------------
  663. // Additive ---------------------------------------------------------------
  664. //-------------------------------------------------------------------------
  665. if (MultiplyBlendEnable == false) // If additive do...
  666. {
  667. // Multiply diffuse colors by HDR multiplier if shader is additive
  668. color = float4(In.DiffuseColor.xyz * EmissiveHDRMultipler, In.DiffuseColor.w);
  669. // Overbrighten
  670. color.xyz += color.xyz;
  671. // Output final color
  672. textureDiffuse = color * textureDiffuse * textureFalloff * fogStrength;
  673. }
  674. //-------------------------------------------------------------------------
  675. // Multiplicitive ---------------------------------------------------------
  676. //-------------------------------------------------------------------------
  677. else // if Multiplicitive do...
  678. {
  679. // Output final color
  680. // Yes we need to take the inverted VertexColor to multiply against everything else
  681. // so that when we invert the whole equation we get the original color correctly
  682. // multiplied aginst the other values. This allows us to specifiy a single color
  683. // that works for both additive and multiplicitve. mjones
  684. textureDiffuse = 1 - (1 - color) * textureDiffuse * textureFalloff * fogStrength * EmissiveHDRMultipler;
  685. textureDiffuse = max(textureDiffuse,0); // Clamp value to > 0 so as to avoid rendering artifacts when working with negative blend numbers
  686. }
  687. //-------------------------------------------------------------------------
  688. // Global shader wrap-up --------------------------------------------------
  689. //-------------------------------------------------------------------------
  690. color.xyz = textureDiffuse;
  691. return color;
  692. }
  693. // ----------------------------------------------------------------------------
  694. // Technique: Default
  695. // ----------------------------------------------------------------------------
  696. technique Default
  697. {
  698. pass P0
  699. {
  700. VertexShader = compile VS_2_0 VS(0);
  701. PixelShader = compile PS_2_0 PS();
  702. ZEnable = true;
  703. ZFunc = ZFUNC_INFRONT;
  704. ZWriteEnable = false;
  705. AlphaTestEnable = false;
  706. AlphaBlendEnable = true;
  707. #if defined(EA_PLATFORM_WINDOWS)
  708. CullMode = ( CullingEnable ? D3DCULL_CW : D3DCULL_NONE );
  709. // If MultiplyBlendEnable then blend mode = MULTIPLY else ADDITIVE
  710. SrcBlend = ( MultiplyBlendEnable == true ? D3DBLEND_DESTCOLOR : D3DBLEND_ONE );
  711. DestBlend = ( MultiplyBlendEnable == true ? D3DBLEND_ZERO : D3DBLEND_ONE );
  712. #else
  713. // TODO: Needs to support additive or multiplicative switch, hardcoding additive for now
  714. SrcBlend = One;
  715. DestBlend = One;
  716. CullMode = None;
  717. #endif
  718. }
  719. }
  720. // ----------------------------------------------------------------------------
  721. // Technique: Medium
  722. // ----------------------------------------------------------------------------
  723. technique Default_M
  724. {
  725. pass P0
  726. {
  727. VertexShader = compile VS_2_0 VS_M(0);
  728. PixelShader = compile PS_2_0 PS_M();
  729. ZEnable = true;
  730. ZFunc = ZFUNC_INFRONT;
  731. ZWriteEnable = false;
  732. AlphaTestEnable = false;
  733. AlphaBlendEnable = true;
  734. #if defined(EA_PLATFORM_WINDOWS)
  735. CullMode = ( CullingEnable ? D3DCULL_CW : D3DCULL_NONE );
  736. // If MultiplyBlendEnable then blend mode = MULTIPLY else ADDITIVE
  737. SrcBlend = ( MultiplyBlendEnable == true ? D3DBLEND_DESTCOLOR : D3DBLEND_ONE );
  738. DestBlend = ( MultiplyBlendEnable == true ? D3DBLEND_ZERO : D3DBLEND_ONE );
  739. #else
  740. // TODO: Needs to support additive or multiplicative switch, hardcoding additive for now
  741. SrcBlend = One;
  742. DestBlend = One;
  743. CullMode = None;
  744. #endif
  745. }
  746. }
  747. // ----------------------------------------------------------------------------
  748. // Technique: LOW
  749. // ----------------------------------------------------------------------------
  750. technique Default_L
  751. {
  752. pass P0
  753. {
  754. VertexShader = compile VS_2_0 VS_L(0);
  755. PixelShader = compile PS_2_0 PS_L();
  756. ZEnable = true;
  757. ZFunc = ZFUNC_INFRONT;
  758. ZWriteEnable = false;
  759. AlphaTestEnable = false;
  760. AlphaBlendEnable = true;
  761. #if defined(EA_PLATFORM_WINDOWS)
  762. CullMode = ( CullingEnable ? D3DCULL_CW : D3DCULL_NONE );
  763. // If MultiplyBlendEnable then blend mode = MULTIPLY else ADDITIVE
  764. SrcBlend = ( MultiplyBlendEnable == true ? D3DBLEND_DESTCOLOR : D3DBLEND_ONE );
  765. DestBlend = ( MultiplyBlendEnable == true ? D3DBLEND_ZERO : D3DBLEND_ONE );
  766. #else
  767. // TODO: Needs to support additive or multiplicative switch, hardcoding additive for now
  768. SrcBlend = One;
  769. DestBlend = One;
  770. CullMode = None;
  771. #endif
  772. }
  773. }