Lightning.fx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. //////////////////////////////////////////////////////////////////////////////
  2. // ©2005 Electronic Arts Inc
  3. //
  4. // FX Shader for Lightning FX (unlit, 2 texture solution, assumed additive)
  5. //////////////////////////////////////////////////////////////////////////////
  6. #define SUPPORT_FOG 1
  7. #define SUPPORT_RECOLORING 1
  8. #include "Common.fxh"
  9. #include "Gamma.fxh"
  10. #include "Random.fxh"
  11. #if defined(EA_PLATFORM_WINDOWS) && defined(_3DSMAX_)
  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. static const int MaxSkinningBonesPerVertex = 2;
  39. #include "Skinning.fxh"
  40. // ----------------------------------------------------------------------------
  41. // Transformations
  42. // ----------------------------------------------------------------------------
  43. #if defined(_WW3D_)
  44. #if !defined(USE_INDIRECT_CONSTANT)
  45. float4x4 ViewProjection
  46. <
  47. string UIWidget = "None";
  48. string SasBindAddress = "Sas.Camera.WorldToProjection";
  49. >;
  50. float3 EyePosition
  51. <
  52. string UIWidget = "None";
  53. string SasBindAddress = "Sas.Camera.Position";
  54. >;
  55. #endif // #if !defined(USE_INDIRECT_CONSTANT)
  56. float4x4 GetViewProjection()
  57. {
  58. return ViewProjection;
  59. }
  60. float3 GetEyePosition()
  61. {
  62. return EyePosition;
  63. }
  64. #else // #if defined(_WW3D_)
  65. float4x4 Projection : Projection;
  66. float4x4 View : View;
  67. float4x3 ViewI : ViewInverse;
  68. float4x4 GetViewProjection()
  69. {
  70. return mul(View, Projection);
  71. }
  72. float3 GetEyePosition()
  73. {
  74. return ViewI[3];
  75. }
  76. #endif // #if defined(_WW3D_)
  77. float Time : Time;
  78. // ----------------------------------------------------------------------------
  79. // Material parameters
  80. // ----------------------------------------------------------------------------
  81. SAMPLER_2D_BEGIN( Texture_0,
  82. string UIName = "Diffuse Texture";
  83. )
  84. MinFilter = MinFilterBest;
  85. MagFilter = MagFilterBest;
  86. MipFilter = MipFilterBest;
  87. AddressU = Wrap;
  88. AddressV = Wrap;
  89. SAMPLER_2D_END
  90. float3 ColorDiffuse
  91. <
  92. string UIName = "Diffuse Material Color";
  93. string UIWidget = "Color";
  94. > = float3(1.0, 1.0, 1.0);
  95. bool MultiTextureEnable
  96. <
  97. string UIName = "Multi-Texture Enable";
  98. > = false;
  99. float HDRMultiplier
  100. <
  101. string UIName = "HDR Multiplier";
  102. string UIWidget = "Slider";
  103. > = 1.0f;
  104. float4 DiffuseCoordOffset
  105. <
  106. string UIName = "Diffuse Coord Offset/Scale";
  107. string UIWidget = "Slider";
  108. float UIMax = 1.0f;
  109. float UIMin = 0;
  110. float UIStep = 0.001f;
  111. > = float4(0.00, 0.00, 1.0, 1.0);
  112. bool MultiplyBlendEnable
  113. <
  114. string UIName = "Multiply Blend Enable";
  115. > = false;
  116. float EdgeFadeOut
  117. <
  118. string UIName = "Edge fade out";
  119. string UIWidget = "Slider";
  120. > = 0.0f;
  121. // ----------------------------------------------------------------------------
  122. // Displace Mapping
  123. // ----------------------------------------------------------------------------
  124. SAMPLER_2D_BEGIN( Texture_1,
  125. string UIName = "Displace Texture";
  126. )
  127. MinFilter = MinFilterBest;
  128. MagFilter = MagFilterBest;
  129. MipFilter = MipFilterBest;
  130. AddressU = Wrap;
  131. AddressV = Wrap;
  132. SAMPLER_2D_END
  133. bool UniqueWorldCoordEnable
  134. <
  135. string UIName = "Unique World Coords Enable";
  136. > = false;
  137. float UniqueWorldCoordScalar
  138. <
  139. string UIName = "Unique World Coords Strength";
  140. string UIWidget = "Slider";
  141. float UIMax = 1.0f;
  142. float UIMin = 0;
  143. float UIStep = 0.001f;
  144. > = 0.01;
  145. float DisplaceScalar
  146. <
  147. string UIName = "Displace Scale";
  148. string UIWidget = "Slider";
  149. float UIMax = 50.0f;
  150. float UIMin = 0;
  151. float UIStep = 0.01f;
  152. > = 1.0;
  153. float DisplaceAmp
  154. <
  155. string UIName = "Displace Amplitude";
  156. string UIWidget = "Slider";
  157. float UIMax = 50.0f;
  158. float UIMin = 0;
  159. float UIStep = 0.01f;
  160. > = 1.0;
  161. float DisplaceDivergenceAngle
  162. <
  163. string UIName = "Displace Divergence Angle";
  164. string UIWidget = "Slider";
  165. float UIMax = 180.0f;
  166. float UIMin = 0;
  167. float UIStep = 0.5f;
  168. > = 0.0;
  169. float DisplaceSpeed
  170. <
  171. string UIName = "Displace Speed";
  172. string UIWidget = "Slider";
  173. float UIMax = 50.0f;
  174. float UIMin = 0;
  175. float UIStep = 0.01f;
  176. > = 1.0;
  177. // ----------------------------------------------------------------------------
  178. // House coloring
  179. // ----------------------------------------------------------------------------
  180. bool UseRecolorColors
  181. <
  182. string UIName = "Allow House Color";
  183. > = false;
  184. bool CullingEnable
  185. <
  186. string UIName = "Culling Enable";
  187. > = true;
  188. // ----------------------------------------------------------------------------
  189. // SHADER : DEFAULT
  190. // ----------------------------------------------------------------------------
  191. struct VSOutput
  192. {
  193. float4 Position : POSITION;
  194. float4 DiffuseColor : COLOR0;
  195. float4 DiffuseTexCoord : TEXCOORD0;
  196. float4 DisplaceTexCoord : TEXCOORD1;
  197. float Fog : TEXCOORD3;
  198. };
  199. // ----------------------------------------------------------------------------
  200. VSOutput VS(VSInputSkinningMultipleBones InSkin,
  201. float2 TexCoord0 : TEXCOORD0,
  202. float4 VertexColor: COLOR0,
  203. uniform int numJointsPerVertex)
  204. {
  205. VSOutput Out;
  206. float3 worldPosition = 0;
  207. float3 worldNormal = 0;
  208. CalculatePositionAndNormal(InSkin, numJointsPerVertex, worldPosition, worldNormal);
  209. #if defined(_3DSMAX_)
  210. // Default vertex color is 0 in Max, that's bad.
  211. VertexColor = 1.0;
  212. // A little bit better motion previewing in MAX
  213. Time *= .25;
  214. #endif
  215. //Calculate the displace texture coordinates
  216. DisplaceSpeed *= Time * .01; // animate Displace as a multiplier of Time with a a happy MAX modifier
  217. float2 DisplaceTexCoords = TexCoord0 * DisplaceScalar;
  218. if (UniqueWorldCoordEnable == true )
  219. {
  220. DisplaceTexCoords.y += (worldPosition.y + worldPosition.x) * UniqueWorldCoordScalar * .1; //the ".1" helps max with a small spinner
  221. }
  222. // Build Displace Texture Rotation Matrix And Convert Degrees to Radians -----
  223. float cosAngle, sinAngle;
  224. cosAngle = 0;
  225. sinAngle = 0;
  226. float2x2 uvCoordRotate = { 1.0f, 0.0f, 1.0f, 0.0f };
  227. sincos (DisplaceDivergenceAngle * .017453, sinAngle, cosAngle);
  228. uvCoordRotate[0][0] = cosAngle;
  229. uvCoordRotate[0][1] = -sinAngle;
  230. uvCoordRotate[1][1] = uvCoordRotate[0][0];
  231. uvCoordRotate[1][0] = -uvCoordRotate[0][1];
  232. // Rotate and Animate Displace Divergence Texture Coords --------------------
  233. float2 DisplaceTexCoordsDiverge = mul(DisplaceTexCoords, uvCoordRotate);
  234. DisplaceTexCoordsDiverge.x += DisplaceSpeed;
  235. float2 DisplaceTexCoordsDivergeInv = mul(DisplaceTexCoords, transpose(uvCoordRotate));
  236. DisplaceTexCoordsDivergeInv.x += DisplaceSpeed;
  237. // Compute view direction in world space
  238. float3 worldEyeDir = normalize(GetEyePosition() - worldPosition);
  239. float viewingAngle = abs(dot(worldEyeDir,worldNormal));
  240. float fadeOut = smoothstep(0, EdgeFadeOut, viewingAngle);
  241. VertexColor.w *= fadeOut;
  242. // Compute all registers
  243. Out.Position = mul(float4(worldPosition, 1), GetViewProjection());
  244. Out.DiffuseColor = VertexColor;// * float4(ColorDiffuse,1);
  245. if (MultiplyBlendEnable == true )
  246. {
  247. Out.DiffuseColor = VertexColor * float4(1 - ColorDiffuse,1);
  248. }
  249. Out.DiffuseTexCoord.xyzw = TexCoord0.xyxy + (DiffuseCoordOffset * Time);
  250. if (MultiTextureEnable == true )
  251. {
  252. Out.DiffuseTexCoord.zw = TexCoord0.xy * DiffuseCoordOffset.zw - (DiffuseCoordOffset * Time);
  253. }
  254. Out.DisplaceTexCoord = float4(DisplaceTexCoordsDiverge, DisplaceTexCoordsDivergeInv);
  255. Out.Fog = CalculateFog(Fog, worldPosition, GetEyePosition());
  256. return Out;
  257. }
  258. // Xenon vertex shader: Remove uniform from NumJointsPerVertex parameter and have it do real branching.
  259. VSOutput VS_Xenon(VSInputSkinningMultipleBones InSkin,
  260. float2 TexCoord0 : TEXCOORD0,
  261. float4 VertexColor: COLOR0)
  262. {
  263. return VS(InSkin, TexCoord0, VertexColor, NumJointsPerVertex);
  264. }
  265. // ----------------------------------------------------------------------------
  266. float4 PS(VSOutput In) : COLOR
  267. {
  268. float4 color = In.DiffuseColor * HDRMultiplier;
  269. color *= In.DiffuseColor.w;
  270. float fogStrength = In.Fog;
  271. float3 textureDisplace = tex2D( SAMPLER(Texture_1), In.DisplaceTexCoord.xy);
  272. textureDisplace += tex2D( SAMPLER(Texture_1), In.DisplaceTexCoord.zw);
  273. textureDisplace = textureDisplace - 1;
  274. float4 displacedTextureCoords = In.DiffuseTexCoord + (textureDisplace.xyxy * DisplaceAmp);
  275. float4 textures = tex2D( SAMPLER(Texture_0), displacedTextureCoords.xy);
  276. if (MultiTextureEnable)
  277. {
  278. textures *= tex2D( SAMPLER(Texture_0), displacedTextureCoords.zw);
  279. }
  280. textures.xyz = GammaToLinear(textures.xyz);
  281. color *= textures;
  282. if (MultiplyBlendEnable)
  283. {
  284. color = .5 - color;
  285. }
  286. // Apply house color
  287. if (UseRecolorColors)
  288. {
  289. color.xyz *= lerp(RecolorColor, float3(1,1,1), .35);
  290. }
  291. // Overbrighten
  292. color.xyz += color.xyz;
  293. // Fog used with additive blending just needs to reduce the additive influence, not blend towards the fog color
  294. color.xyz *= fogStrength;
  295. return color;
  296. }
  297. // ----------------------------------------------------------------------------
  298. // Technique: Default
  299. // ----------------------------------------------------------------------------
  300. DEFINE_ARRAY_MULTIPLIER(VS_Multiplier_NumJointsPerVertex = 1);
  301. #define VS_NumJointsPerVertex \
  302. compile VS_2_0 VS(0), \
  303. compile VS_2_0 VS(1), \
  304. compile VS_2_0 VS(2)
  305. DEFINE_ARRAY_MULTIPLIER(VS_Multiplier_Final = VS_Multiplier_NumJointsPerVertex * 3);
  306. #if SUPPORTS_SHADER_ARRAYS
  307. vertexshader VS_Array[VS_Multiplier_Final] = { VS_NumJointsPerVertex };
  308. #endif
  309. technique Default
  310. {
  311. pass P0
  312. {
  313. VertexShader = ARRAY_EXPRESSION_VS(VS_Array,
  314. min(NumJointsPerVertex, 2) * VS_Multiplier_NumJointsPerVertex,
  315. // Non-array alternative:
  316. compile VS_VERSION VS_Xenon()
  317. );
  318. PixelShader = compile PS_2_0 PS();
  319. ZEnable = true;
  320. ZFunc = ZFUNC_INFRONT;
  321. ZWriteEnable = false;
  322. AlphaBlendEnable = true;
  323. #if defined(EA_PLATFORM_WINDOWS)
  324. CullMode = ( CullingEnable ? D3DCULL_CW : D3DCULL_NONE );
  325. // Additive or Multiply Blend Mode
  326. SrcBlend = ( MultiplyBlendEnable == true ? D3DBLEND_DESTCOLOR : D3DBLEND_ONE );
  327. DestBlend = ( MultiplyBlendEnable == true ? D3DBLEND_ZERO : D3DBLEND_ONE );
  328. #else
  329. CullMode = None;
  330. // Additive or Multiply Blend Mode
  331. SrcBlend = One;
  332. DestBlend = One;
  333. #endif
  334. }
  335. }