Common.fxh 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. //////////////////////////////////////////////////////////////////////////////
  2. // ©2005 Electronic Arts Inc
  3. //
  4. // Common header for FX files
  5. //////////////////////////////////////////////////////////////////////////////
  6. #ifndef _COMMON_FXH_
  7. #define _COMMON_FXH_
  8. // Include platform specific macros
  9. #if defined( EA_PLATFORM_XENON )
  10. #include "xenon_macros.fxh"
  11. #elif defined( EA_PLATFORM_PS3 )
  12. #include "ps3_macros.fxh"
  13. #else
  14. #include "win32_macros.fxh"
  15. #endif
  16. #include "Sas.fxh"
  17. // Set some preprocessor define for 3DSMax.
  18. // Since we can't set it there, define it excluding our other tools.
  19. #if !defined(_WW3D_) && !defined(_FX_COMPOSER_)
  20. #define _3DSMAX_
  21. #endif
  22. // This is used by 3dsmax to load the correct parser
  23. #if defined(_3DSMAX_)
  24. string ParamID = "0x1";
  25. #endif
  26. // Tell RNA to assume everything that isn't marked by a semantic/annotation is a material parameter.
  27. string DefaultParameterScopeBlock = "material";
  28. //
  29. // Expression evaluator system.
  30. // Allows shaders to hook up to CPU code to assign render states or shader constants
  31. //
  32. // To disable expression evaluators for a file temporarily, define the DISABLE_EXPRESSION_EVALUATORS macro
  33. #if !defined(_WW3D_) || defined(DISABLE_EXPRESSION_EVALUATORS)
  34. #define EXPRESSION_EVALUATOR_ENABLED 0
  35. #else
  36. #define EXPRESSION_EVALUATOR_ENABLED 1
  37. #endif
  38. #if EXPRESSION_EVALUATOR_ENABLED
  39. #define USE_EXPRESSION_EVALUATOR(name) string ExpressionEvaluator = name;
  40. #else
  41. #define USE_EXPRESSION_EVALUATOR(name)
  42. #endif
  43. #if defined(EA_PLATFORM_XENON) || defined(EA_PLATFORM_PS3)
  44. #define SUPPORTS_SHADER_ARRAYS 0
  45. #else // EA_PLATFORM_WINDOWS
  46. #define SUPPORTS_SHADER_ARRAYS 1
  47. #endif
  48. #if SUPPORTS_SHADER_ARRAYS
  49. // Use these macros to define shader arrays.
  50. // The "direct" version of the macro will never try to use the expression evaluator to evaluate the array index.
  51. #define ARRAY_EXPRESSION_DIRECT_VS(arrayName, expression, noArraySupportAlternative) ( arrayName[ expression ] )
  52. #define ARRAY_EXPRESSION_DIRECT_PS(arrayName, expression, noArraySupportAlternative) ( arrayName[ expression ] )
  53. // The non-"direct" version of the macro use the expression evaluator to evaluate the array index when possible.
  54. // [LLatta 2007-09-13] Let's not use expression evaluators for arrays at the moment, reevaluate the overhead this can have later.
  55. #if 0 // EXPRESSION_EVALUATOR_ENABLED
  56. int _ArrayIndexVS = 0;
  57. int _ArrayIndexPS = 0;
  58. #define ARRAY_EXPRESSION_VS(arrayName, expression, noArraySupportAlternative) ( arrayName[ _ArrayIndexVS ] )
  59. #define ARRAY_EXPRESSION_PS(arrayName, expression, noArraySupportAlternative) ( arrayName[ _ArrayIndexPS ] )
  60. #define DEFINE_ARRAY_MULTIPLIER(initializer) \
  61. static const int initializer; \
  62. const int _##initializer
  63. #else // !EXPRESSION_EVALUATOR_ENABLED
  64. #define ARRAY_EXPRESSION_VS(arrayName, expression, noArraySupportAlternative) ( arrayName[ expression ] )
  65. #define ARRAY_EXPRESSION_PS(arrayName, expression, noArraySupportAlternative) ( arrayName[ expression ] )
  66. #define DEFINE_ARRAY_MULTIPLIER(initializer) \
  67. static const int initializer
  68. #endif
  69. #define COLORTARGET : COLOR
  70. #else // !SUPPORT_SHADER_ARRAYS
  71. #define ARRAY_EXPRESSION_DIRECT_VS(arrayName, expression, noArraySupportAlternative) noArraySupportAlternative
  72. #define ARRAY_EXPRESSION_DIRECT_PS(arrayName, expression, noArraySupportAlternative) noArraySupportAlternative
  73. #define ARRAY_EXPRESSION_VS(arrayName, expression, noArraySupportAlternative) noArraySupportAlternative
  74. #define ARRAY_EXPRESSION_PS(arrayName, expression, noArraySupportAlternative) noArraySupportAlternative
  75. #define DEFINE_ARRAY_MULTIPLIER(initializer) static const int initializer
  76. #define COLORTARGET
  77. #endif
  78. //
  79. // Technique LOD
  80. //
  81. #if !defined(ENABLE_LOD)
  82. #if defined(EA_PLATFORM_WINDOWS)
  83. #define ENABLE_LOD 1
  84. #else // EA_PLATFORM_XENON
  85. #define ENABLE_LOD 0
  86. #endif
  87. #endif
  88. // Isolate
  89. #if defined(EA_PLATFORM_XENON)
  90. #define ISOLATE [isolate]
  91. #else
  92. #define ISOLATE
  93. #endif
  94. // Static
  95. // 'sce-cgc' does not like 'static const' on arrays.
  96. #if defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XENON)
  97. #define STATICARRAY static
  98. #else
  99. #define STATICARRAY
  100. #endif
  101. //
  102. // HI-Z CULLING
  103. //
  104. #if !HIZ_CULLING
  105. #define ZFUNC_INFRONT LessEqual
  106. #else
  107. #define ZFUNC_INFRONT GreaterEqual
  108. #endif
  109. //
  110. // InstancingMode values
  111. // Use in SasGlobal annotation for MaxSupportedInstancingMode
  112. //
  113. #define INSTANCING_MODE_NONE 0
  114. #define INSTANCING_MODE_ONE_PER_DRAW_CALL 1
  115. #define INSTANCING_MODE_MATRIX_STREAM 2
  116. //
  117. // COLOR VALUES
  118. //
  119. #define RGB 7
  120. #define RGBA 15
  121. // Shader parameters are associated to a "dynamic set". Each set can be updated independently,
  122. // so that multiple objects that eg. only differ in their world transformation can be rendered
  123. // without updating all the other rendering states.
  124. //
  125. // Keep this in sync with FXShaderParameter.h
  126. //
  127. static const int DS_DEFAULT = 0; // Parameters without WW3DDynamicSet annotation fall into this category
  128. static const int DS_WORLD_TRANSFORMATIONS = 1; // Parameters that change when the world matrix changes (World, WorldView, WorldInverse...)
  129. static const int DS_CUSTOM_FIRST = 2; // These sets can be used for custom shader rendering sequences
  130. static const int DS_CUSTOM_LAST = 5;
  131. // Threshold for AlphaRef render state when doing alpha testing
  132. #define DEFAULT_ALPHATEST_THRESHOLD 0x60
  133. //
  134. // Common distance fog setup info, can be bound to "WW3D.Fog" binding
  135. //
  136. struct WW3DFog
  137. {
  138. //bool IsEnabled; // There is a bug in the D3DX Effect framework, this needs to be float to work
  139. float IsEnabled;
  140. float4 Color;
  141. float RangeStart;
  142. //float RangeEnd;
  143. float OneOverRangeDelta; // = 1.0 / (RangeEnd - RangeStart)
  144. };
  145. #define DEFAULT_FOG_DISABLED { false, float4(1, 1, 1, 1), 0, /*1000*/ 0.001 }
  146. // Fog has been globally disabled now. By making it static const it will compile out for the most part now.
  147. #if SUPPORT_FOG
  148. static const WW3DFog Fog
  149. <
  150. string UIWidget = "None";
  151. string SasBindAddress = "WW3D.Fog";
  152. > = DEFAULT_FOG_DISABLED;
  153. #endif
  154. // Calculate the "distance fog value", appropriate for use with the FOG output semantic of a vertex shader.
  155. // Returns 1.0 for completely un-fogged areas, and 0.0 for completely fogged, between that if partially fogged.
  156. float CalculateFog(WW3DFog Fog, float3 WorldPosition, float3 CameraPosition)
  157. {
  158. return 1.0 - Fog.IsEnabled * saturate((length(WorldPosition - CameraPosition) - Fog.RangeStart) * Fog.OneOverRangeDelta);
  159. }
  160. //
  161. // Common shroud setup, can be bound to "Terrain.Shroud" binding
  162. //
  163. struct ShroudSetup
  164. {
  165. float4 ScaleUV_OffsetUV;
  166. };
  167. #define DEFAULT_SHROUD { float4(1, 1, 0, 0) }
  168. // Calculate the texture coordinates for shroud lookup
  169. float2 CalculateShroudTexCoord(ShroudSetup shroud, float3 WorldPosition)
  170. {
  171. return (WorldPosition.xy + shroud.ScaleUV_OffsetUV.zw) * shroud.ScaleUV_OffsetUV.xy;
  172. }
  173. // Remap the high end of the shroud transition so that effects become invisible in "fog of war"
  174. float BiasShroudValueForEffects( float normalizedShroudValue )
  175. {
  176. // We'd like to simply do this: return max( 0, ( normalizedShroudValue - 0.75 ) * 4 );
  177. // However, pixel shader 1.1 doesn't let you use numbers above 2
  178. // So, we cleverly trick the HLSL compiler into doing it in two steps
  179. float shroud = normalizedShroudValue - 0.75;
  180. shroud *= 2;
  181. shroud = max( 0, shroud );
  182. shroud *= 2;
  183. return shroud;
  184. }
  185. //
  186. // Common cloud layer computation
  187. //
  188. struct CloudSetup
  189. {
  190. float4 WorldPositionMultiplier_XYZZ;
  191. float2 CurrentOffsetUV;
  192. };
  193. #define DEFAULT_CLOUD { float4(0, 0, 0, 0), float2(0, 0) }
  194. // Calculate the texture coordinates for cloud lookup
  195. float2 CalculateCloudTexCoord(CloudSetup cloudSetup, float3 WorldPosition, float Time)
  196. {
  197. // This code illustrates how to compute the current CloudSetup members from the previous, more intuitive (but less optimal) values:
  198. // float2 cloudScale = cloudSetup.ScaleUV_OffsetPerSecondUV.xy / 2;
  199. // float2 cloudOffsetPerSecond = cloudSetup.ScaleUV_OffsetPerSecondUV.zw;
  200. // CurrentOffsetUV = frac(Time * cloudOffsetPerSecond);
  201. // WorldPositionMultiplier_XYZZ = float4(cloudScale.xy, cloudScale.xy * cloudSetup.ProjectionDirection.xy / cloudSetup.ProjectionDirection.z
  202. float4 multipliedWP = WorldPosition.xyzz * cloudSetup.WorldPositionMultiplier_XYZZ;
  203. return multipliedWP.xy - multipliedWP.zw + cloudSetup.CurrentOffsetUV;
  204. }
  205. //
  206. // Light source definition helpers
  207. //
  208. #define DEFAULT_DIRECTIONAL_LIGHT_1 \
  209. { pow(float3(1.247, 1.207, 1.043), 2.2), float3(0.62914, -0.34874, 0.69465) }
  210. #define DEFAULT_DIRECTIONAL_LIGHT_2 \
  211. { pow(float3(0.745, 0.831, 0.894), 2.2), float3(-0.32877, 0.90329, 0.27563) }
  212. #define DEFAULT_DIRECTIONAL_LIGHT_3 \
  213. { pow(float3(0.690, 0.667, 0.690), 2.2), float3(-0.80704, -0.58635, 0.06975) }
  214. #define DEFAULT_DIRECTIONAL_LIGHT_DISABLED \
  215. { float3(0, 0, 0), float3(0, 0, 1) }
  216. #define DEFAULT_POINT_LIGHT_DISABLED \
  217. { float3(0, 0, 0), float3(0, 0, 0), float2(0, 0) }
  218. float CalculatePointLightAttenuation(SasPointLight light, float lightDistance)
  219. {
  220. float innerRange = light.Range_Inner_Outer.x;
  221. float outerRange = light.Range_Inner_Outer.y;
  222. // Make a squared fall-off
  223. float attenuation = saturate(1.0 - (lightDistance - innerRange) / (outerRange - innerRange));
  224. attenuation *= attenuation;
  225. return attenuation;
  226. }
  227. float3 CalculatePointLightDiffuse(SasPointLight light, float3 worldPosition, float3 worldNormal)
  228. {
  229. float3 direction = light.Position - worldPosition;
  230. float lightDistance = length(direction);
  231. direction /= lightDistance;
  232. float attenuation = CalculatePointLightAttenuation(light, lightDistance);
  233. return light.Color * attenuation * max(dot(worldNormal, direction), 0);
  234. }
  235. #if (defined(_3DSMAX_) || defined(_FX_COMPOSER_)) && defined(USE_INTERACTIVE_LIGHTS)
  236. #define DECLARE_DIRECTIONAL_LIGHT_INTERACTIVE(lightName, lightIndex) \
  237. float3 lightName##lightIndex : Direction < \
  238. string Object = "DirectionalLight"; \
  239. string Space = "World"; \
  240. string UIName = "Directional Light " #lightIndex; \
  241. > = float3(0, 0, -1);
  242. #define USE_DIRECTIONAL_LIGHT_INTERACTIVE(lightName, lightIndex) \
  243. lightName[lightIndex].Direction = lightName##lightIndex;
  244. #define DECLARE_POINT_LIGHT_INTERACTIVE(lightName, lightIndex) \
  245. float3 lightName##lightIndex : Position < \
  246. string Object = "PointLight"; \
  247. string Space = "World"; \
  248. string UIName = "Point Light " #lightIndex; \
  249. > = float3(0, 0, 0);
  250. #define USE_POINT_LIGHT_INTERACTIVE(lightName, lightIndex) \
  251. lightName[lightIndex].Position = lightName##lightIndex;
  252. #else
  253. #define DECLARE_DIRECTIONAL_LIGHT_INTERACTIVE(lightName, lightIndex) static const int dummyDeclareDirectionalLight = 0
  254. #define USE_DIRECTIONAL_LIGHT_INTERACTIVE(lightName, lightIndex) static const int dummyUseDirectionalLight = 0
  255. #define DECLARE_POINT_LIGHT_INTERACTIVE(lightName, lightIndex) static const int dummyDeclarePointLight = 0
  256. #define USE_POINT_LIGHT_INTERACTIVE(lightName, lightIndex) static const int dummyUsePointLight = 0
  257. #endif
  258. //
  259. // Macros to add support for multiple texture coordinates and vertex colors/alpah in 3DSMax
  260. //
  261. #if defined(_3DSMAX_)
  262. #define DECLARE_MAPPING_TEXCOORD(texcoordIndex) \
  263. int _3DSTexcoordMapping##texcoordIndex : Texcoord \
  264. < \
  265. int Texcoord = texcoordIndex; \
  266. int MapChannel = 1 + texcoordIndex; \
  267. string UIWidget = "None"; \
  268. >;
  269. #define DECLARE_MAPPING_VERTEXCOLOR(firstTexcoordIndex, secondTexCoordIndex) \
  270. int _3DSTexcoordMappingVertexColor : Texcoord \
  271. < \
  272. int Texcoord = firstTexcoordIndex; \
  273. int MapChannel = 0; \
  274. string UIWidget = "None"; \
  275. >; \
  276. int _3DSTexcoordMappingVertexAlpha : Texcoord \
  277. < \
  278. int Texcoord = secondTexCoordIndex; \
  279. int MapChannel = -2; \
  280. string UIWidget = "None"; \
  281. >;
  282. #define DECLARE_VERTEXCOLOR_INPUT(variableName, firstTexcoordIndex, secondTexCoordIndex) \
  283. float3 _3DSVertexColor : TEXCOORD##firstTexcoordIndex, \
  284. float _3DSVertexAlpha : TEXCOORD##secondTexCoordIndex
  285. #define DECLARE_VERTEXCOLOR_INPUT_STRUCT(variableName, firstTexcoordIndex, secondTexCoordIndex) \
  286. float3 _3DSVertexColor : TEXCOORD##firstTexcoordIndex; \
  287. float _3DSVertexAlpha : TEXCOORD##secondTexCoordIndex
  288. #define PASS_THROUGH_VERTEXCOLOR(variableName) _3DSVertexColor, _3DSVertexAlpha
  289. #define USE_VERTEXCOLOR(variableName) \
  290. float4 variableName = float4(_3DSVertexColor, _3DSVertexAlpha)
  291. // Seems 3DSMax subtracts 1 from the v coordinate. Go figure.
  292. #define USE_TEXCOORD(variableName) \
  293. variableName.y = 1 + variableName.y
  294. #else // !defined _3DSMAX_
  295. #define DECLARE_MAPPING_TEXCOORD(texcoordIndex)
  296. #define DECLARE_MAPPING_VERTEXCOLOR(firstTexcoordIndex, secondTexCoordIndex)
  297. #define DECLARE_VERTEXCOLOR_INPUT(variableName, firstTexCoord, secondTexCoordIndex) \
  298. float4 variableName : COLOR0
  299. #define DECLARE_VERTEXCOLOR_INPUT_STRUCT(variableName, firstTexCoord, secondTexCoordIndex) \
  300. float4 variableName : COLOR0
  301. #define PASS_THROUGH_VERTEXCOLOR(variableName) variableName
  302. // Dummy definitions. Could be defined as nothing, this way they ensure a minimal syntax correctness.
  303. #define USE_VERTEXCOLOR(variableName) variableName
  304. #define USE_TEXCOORD(variableName) variableName
  305. #endif
  306. //
  307. // Declare constants with nice UI, since Max lacks creating spinners for vector variable
  308. // Example usage:
  309. // DECLARE_FLOAT2(foo, 1.0f, 1.0f);
  310. // DECLARE_FLOAT2_CUSTOM(bar, 1.0f, 1.0f, float UIMin = 0.5; float UIMax = 1.0; float UIStep = 0.1);
  311. //
  312. #define DECLARE_FLOAT2(varName, defaultX, defaultY) \
  313. DECLARE_FLOAT2_CUSTOM(varName, defaultX, defaultY, int __unused = 0)
  314. #define DECLARE_FLOAT3(varName, defaultX, defaultY, defaultZ) \
  315. DECLARE_FLOAT3_CUSTOM(varName, defaultX, defaultY, defaultZ, int __unused = 0)
  316. #define DECLARE_FLOAT4(varName, defaultX, defaultY, defaultZ, defaultW) \
  317. DECLARE_FLOAT4_CUSTOM(varName, defaultX, defaultY, defaultZ, defaultW, int __unused = 0)
  318. #if defined(_WW3D_) || defined(_FX_COMPOSER_)
  319. #define DECLARE_FLOAT2_CUSTOM(varName, defaultX, defaultY, additionalAnnotations) \
  320. float2 varName = float2(defaultX, defaultY)
  321. #define DECLARE_FLOAT3_CUSTOM(varName, defaultX, defaultY, defaultZ, additionalAnnotations) \
  322. float3 varName = float3(defaultX, defaultY, defaultZ)
  323. #define DECLARE_FLOAT4_CUSTOM(varName, defaultX, defaultY, defaultZ, defaultW, additionalAnnotations) \
  324. float4 varName = float4(defaultX, defaultY, defaultZ, defaultW)
  325. #define USE_FLOAT2(varName)
  326. #define USE_FLOAT3(varName)
  327. #define USE_FLOAT4(varName)
  328. #else // !_WW3D_ i.e. this is when compiling in 3DS Max
  329. #define DECLARE_FLOAT2_CUSTOM(varName, defaultX, defaultY, additionalAnnotations) \
  330. float varName##__X < \
  331. string UIName = #varName ".x"; \
  332. string UIType = "FloatSpinner"; \
  333. additionalAnnotations; \
  334. > = float(defaultX); \
  335. float varName##__Y < \
  336. string UIName = #varName ".y"; \
  337. string UIType = "FloatSpinner"; \
  338. additionalAnnotations; \
  339. > = float(defaultY)
  340. #define DECLARE_FLOAT3_CUSTOM(varName, defaultX, defaultY, defaultZ, additionalAnnotations) \
  341. float varName##__X < \
  342. string UIName = #varName ".x"; \
  343. string UIType = "FloatSpinner"; \
  344. additionalAnnotations; \
  345. > = float(defaultX); \
  346. float varName##__Y < \
  347. string UIName = #varName ".y"; \
  348. string UIType = "FloatSpinner"; \
  349. additionalAnnotations; \
  350. > = float(defaultY); \
  351. float varName##__Z < \
  352. string UIName = #varName ".z"; \
  353. string UIType = "FloatSpinner"; \
  354. additionalAnnotations; \
  355. > = float(defaultZ)
  356. #define DECLARE_FLOAT4_CUSTOM(varName, defaultX, defaultY, defaultZ, defaultW, additionalAnnotations) \
  357. float varName##__X < \
  358. string UIName = #varName ".x"; \
  359. string UIType = "FloatSpinner"; \
  360. additionalAnnotations; \
  361. > = float(defaultX); \
  362. float varName##__Y < \
  363. string UIName = #varName ".y"; \
  364. string UIType = "FloatSpinner"; \
  365. additionalAnnotations; \
  366. > = float(defaultY); \
  367. float varName##__Z < \
  368. string UIName = #varName ".z"; \
  369. string UIType = "FloatSpinner"; \
  370. additionalAnnotations; \
  371. > = float(defaultZ); \
  372. float varName##__W < \
  373. string UIName = #varName ".w"; \
  374. string UIType = "FloatSpinner"; \
  375. additionalAnnotations; \
  376. > = float(defaultW)
  377. #define USE_FLOAT2(varName) float2 varName = float2(varName##__X, varName##__Y)
  378. #define USE_FLOAT3(varName) float3 varName = float3(varName##__X, varName##__Y, varName##__Z)
  379. #define USE_FLOAT4(varName) float4 varName = float4(varName##__X, varName##__Y, varName##__Z, varName##__W)
  380. #endif
  381. //
  382. // Global Parameters sections
  383. //
  384. // We need to include this with all shaders ssince with the USE_INDIRECT_CONSTANT, we need to reserved the registers even
  385. // for the shaders that don't use those constants to avoid stomping of those registers.
  386. #include "GlobalParameters.fxh"
  387. #endif // Include guard