ObjectsTerrain.fx 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. //////////////////////////////////////////////////////////////////////////////
  2. // ©2008 Electronic Arts Inc
  3. //
  4. // FX Shader for terrain objects. These are objects that need to use similar shading as terrain so that they blend correctly with it.
  5. // Ex. Cliff walls.
  6. //////////////////////////////////////////////////////////////////////////////
  7. #define SUPPORT_SSAO 1 // enable SSAO
  8. #define SUPPORT_SPECMAP 1
  9. #define USE_INTERACTIVE_LIGHTS 1
  10. #define PER_PIXEL_POINT_LIGHT
  11. #define SUPPORT_CLOUDS 1
  12. #define SUPPORT_FOG 1
  13. #define SUPPORT_GLOBAL_LIGHTS 1
  14. #define SUPPORT_LOCAL_LIGHTS 1
  15. #define MaxNumPointLights 8
  16. #include "Common.fxh"
  17. #include "Gamma.fxh"
  18. #include "SSAO.fxh"
  19. #include "ShadowMap.fxh"
  20. #include "MacroTexture.fxh"
  21. int _SasGlobal : SasGlobal
  22. <
  23. string UIWidget = "None";
  24. int3 SasVersion = int3(1, 0, 0);
  25. int MaxLocalLights = MaxNumPointLights;
  26. int MaxSupportedInstancingMode = INSTANCING_MODE_ONE_PER_DRAW_CALL;
  27. string RenderBin = "TerrainLikeGroundObject";
  28. > = 0;
  29. #if defined(EA_PLATFORM_WINDOWS) && defined(_3DSMAX_)
  30. // ----------------------------------------------------------------------------
  31. // SAMPLER : nhendricks : had to pull these in here for MAX to compile
  32. // ----------------------------------------------------------------------------
  33. #define SAMPLER_2D_BEGIN(samplerName, annotations) \
  34. texture samplerName \
  35. < \
  36. annotations \
  37. >; \
  38. sampler2D samplerName##Sampler = sampler_state \
  39. { \
  40. Texture = < samplerName >;
  41. #define SAMPLER_2D_END };
  42. #define SAMPLER( samplerName ) samplerName##Sampler
  43. #define SAMPLER_CUBE_BEGIN(samplerName, annotations) \
  44. texture samplerName \
  45. < \
  46. annotations \
  47. >; \
  48. samplerCUBE samplerName##Sampler = sampler_state \
  49. { \
  50. Texture = < samplerName >;
  51. #define SAMPLER_CUBE_END };
  52. #if defined(_3DSMAX_)
  53. #define DECLARE_MAPPING_TEXCOORD(texcoordIndex) \
  54. int _3DSTexcoordMapping##texcoordIndex : Texcoord \
  55. < \
  56. int Texcoord = texcoordIndex; \
  57. int MapChannel = 1 + texcoordIndex; \
  58. string UIWidget = "None"; \
  59. >;
  60. #define DECLARE_VERTEXCOLOR_INPUT(variableName, firstTexcoordIndex, secondTexCoordIndex) \
  61. float3 _3DSVertexColor : TEXCOORD##firstTexcoordIndex, \
  62. float _3DSVertexAlpha : TEXCOORD##secondTexCoordIndex
  63. #define DECLARE_VERTEXCOLOR_INPUT_STRUCT(variableName, firstTexcoordIndex, secondTexCoordIndex) \
  64. float3 _3DSVertexColor : TEXCOORD##firstTexcoordIndex; \
  65. float _3DSVertexAlpha : TEXCOORD##secondTexCoordIndex
  66. #endif
  67. #endif
  68. DECLARE_MAPPING_TEXCOORD(0)
  69. DECLARE_MAPPING_VERTEXCOLOR(1, 2)
  70. #define EXPRESSION_EVALUATOR_NAME "Objects"
  71. // ----------------------------------------------------------------------------
  72. // Skinning
  73. // ----------------------------------------------------------------------------
  74. #define MaxSkinningBonesPerVertex 1
  75. #include "Skinning.fxh"
  76. // ----------------------------------------------------------------------------
  77. // Cloud layer
  78. // ----------------------------------------------------------------------------
  79. SAMPLER_2D_BEGIN( CloudTexture,
  80. string UIWidget = "None";
  81. string SasBindAddress = "Terrain.Cloud.Texture";
  82. string ResourceName = "ShaderPreviewCloud.dds";
  83. )
  84. MinFilter = Linear;
  85. MagFilter = Linear;
  86. MipFilter = Linear;
  87. AddressU = Wrap;
  88. AddressV = Wrap;
  89. SAMPLER_2D_END
  90. // ----------------------------------------------------------------------------
  91. // Editable parameters
  92. // ----------------------------------------------------------------------------
  93. SAMPLER_2D_BEGIN( DiffuseTexture,
  94. string UIName = "Diffuse Texture";
  95. )
  96. MinFilter = MinFilterBest;
  97. MagFilter = MagFilterBest;
  98. MipFilter = MipFilterBest;
  99. MaxAnisotropy = 8;
  100. AddressU = Wrap;
  101. AddressV = Wrap;
  102. SAMPLER_2D_END
  103. SAMPLER_2D_BEGIN( NormalMap,
  104. string UIName = "Normal Texture";
  105. )
  106. MinFilter = MinFilterBest;
  107. MagFilter = MagFilterBest;
  108. MipFilter = MipFilterBest;
  109. MaxAnisotropy = 8;
  110. AddressU = Wrap;
  111. AddressV = Wrap;
  112. SAMPLER_2D_END
  113. #if defined(SUPPORT_SPECMAP)
  114. SAMPLER_2D_BEGIN( SpecMap,
  115. string UIName = "Specular Map";
  116. )
  117. MinFilter = MinFilterBest;
  118. MagFilter = MagFilterBest;
  119. MipFilter = MipFilterBest;
  120. MaxAnisotropy = 8;
  121. AddressU = Wrap;
  122. AddressV = Wrap;
  123. SAMPLER_2D_END
  124. #endif
  125. // Same as the defaults in objects.fxh. They are just hard coded here since it looks good with the terrain.
  126. static const float3 AmbientColor = float3(1.0, 1.0, 1.0);
  127. static const float4 DiffuseColor = float4(1.0, 1.0, 1.0, 1.0);
  128. static const float3 SpecularColor = float3(1.0, 1.0, 1.0);
  129. static const float SpecularExponent = 50;
  130. static const float BumpScale = .75;
  131. // ----------------------------------------------------------------------------
  132. // Shroud
  133. // ----------------------------------------------------------------------------
  134. ShroudSetup Shroud
  135. <
  136. string UIWidget = "None";
  137. string SasBindAddress = "Terrain.Shroud";
  138. > = DEFAULT_SHROUD;
  139. SAMPLER_2D_BEGIN( ShroudTexture,
  140. string UIWidget = "None";
  141. string SasBindAddress = "Terrain.Shroud.Texture";
  142. )
  143. MinFilter = Linear;
  144. MagFilter = Linear;
  145. MipFilter = Linear;
  146. AddressU = Clamp;
  147. AddressV = Clamp;
  148. SAMPLER_2D_END
  149. #if !defined(USE_INDIRECT_CONSTANT)
  150. float OpacityOverride
  151. <
  152. string UIWidget = "None";
  153. string SasBindAddress = "WW3D.OpacityOverride";
  154. > = 1.0;
  155. float3 TintColor
  156. <
  157. string UIWidget = "None";
  158. string SasBindAddress = "WW3D.TintColor";
  159. > = float3(1, 1, 1);
  160. #endif // #if !defined(USE_INDIRECT_CONSTANT)
  161. // ----------------------------------------------------------------------------
  162. // Transformations (world transformations are in skinning header)
  163. // ----------------------------------------------------------------------------
  164. #if defined(_WW3D_)
  165. #if !defined(USE_INDIRECT_CONSTANT)
  166. float4x4 ViewProjection
  167. <
  168. string UIWidget = "None";
  169. string SasBindAddress = "Sas.Camera.WorldToProjection";
  170. >;
  171. float3 EyePosition
  172. <
  173. string UIWidget = "None";
  174. string SasBindAddress = "Sas.Camera.Position";
  175. >;
  176. #endif // #if !defined(USE_INDIRECT_CONSTANT)
  177. float4x4 GetViewProjection()
  178. {
  179. return ViewProjection;
  180. }
  181. float3 GetEyePosition()
  182. {
  183. return EyePosition;
  184. }
  185. #else // #if defined(_WW3D_)
  186. float4x4 View : View;
  187. float4x3 ViewI : ViewInverse;
  188. float4x4 Projection : Projection;
  189. float4x4 GetViewProjection()
  190. {
  191. return mul(View, Projection);
  192. }
  193. float3 GetEyePosition()
  194. {
  195. return ViewI[3];
  196. }
  197. #endif // #if defined(_WW3D_)
  198. // Time (ie. material is animated)
  199. float Time : Time;
  200. // ----------------------------------------------------------------------------
  201. // SHADER: Default High LOD
  202. // ----------------------------------------------------------------------------
  203. struct VSOutput_H
  204. {
  205. float4 Position : POSITION;
  206. float2 TexCoord0 : TEXCOORD0;
  207. float3x3 TangentToWorldSpace : TEXCOORD1_CENTROID;
  208. float3 WorldPosition : TEXCOORD4;
  209. float4 ShadowMapTexCoord : TEXCOORD5;
  210. float4 ShroudTexCoord_CloudTexCoord : TEXCOORD6;
  211. float3 MainLightHalfEyeVector : TEXCOORD7;
  212. float4 Color : COLOR0;
  213. };
  214. // ----------------------------------------------------------------------------
  215. // SHADER: VS
  216. // ----------------------------------------------------------------------------
  217. VSOutput_H VS_H(VSInputSkinningOneBoneTangentFrame InSkin,
  218. float2 TexCoord0 : TEXCOORD0,
  219. DECLARE_VERTEXCOLOR_INPUT(VertexColor, 1, 2))
  220. {
  221. USE_VERTEXCOLOR(VertexColor);
  222. USE_TEXCOORD(TexCoord0);
  223. USE_DIRECTIONAL_LIGHT_INTERACTIVE(DirectionalLight, 0);
  224. VSOutput_H Out;
  225. float3 worldPosition = 0;
  226. float3 worldNormal = 0;
  227. float3 worldTangent = 0;
  228. float3 worldBinormal = 0;
  229. CalculatePositionAndTangentFrame(InSkin, 0,
  230. worldPosition, worldNormal, worldTangent, worldBinormal);
  231. // Build 3x3 tranform from object to tangent space
  232. Out.TangentToWorldSpace = float3x3(-worldBinormal, -worldTangent, worldNormal);
  233. Out.Color = float4(AmbientLightColor * AmbientColor, OpacityOverride);
  234. // Compute remaining directional lights per vertex, others will be done in pixel shader
  235. float3 diffuseLight = 0;
  236. for (int i = 1; i < NumDirectionalLights; i++)
  237. {
  238. diffuseLight += DirectionalLight[i].Color * max(0, dot(worldNormal, DirectionalLight[i].Direction));
  239. }
  240. Out.Color.xyz += diffuseLight * DiffuseColor;
  241. Out.Color.xyz /= 2; // Prevent clamping in interpolator
  242. Out.Color *= VertexColor;
  243. Out.WorldPosition = worldPosition;
  244. float3 worldEyeDir = normalize(GetEyePosition() - worldPosition);
  245. Out.MainLightHalfEyeVector = normalize(DirectionalLight[0].Direction + worldEyeDir);
  246. // pass texture coordinates for fetching the diffuse and normal maps
  247. Out.TexCoord0 = TexCoord0.xy;
  248. // transform position to projection space
  249. ISOLATE Out.Position = mul(float4(worldPosition, 1), GetViewProjection());
  250. Out.ShadowMapTexCoord = CalculateShadowMapTexCoord(worldPosition);
  251. Out.ShroudTexCoord_CloudTexCoord.xy = CalculateShroudTexCoord(Shroud, worldPosition);
  252. Out.ShroudTexCoord_CloudTexCoord.zw = CalculateCloudTexCoord(Cloud, worldPosition, Time);
  253. return Out;
  254. }
  255. // ----------------------------------------------------------------------------
  256. // SHADER: PS
  257. // ----------------------------------------------------------------------------
  258. float4 PS_H(VSOutput_H In, uniform bool hasShadow, float2 vPos : PIXELLOC) COLORTARGET
  259. {
  260. // Get diffuse color
  261. float2 texCoord0 = In.TexCoord0.xy;
  262. float4 baseTextureValue = tex2D(SAMPLER(DiffuseTexture), texCoord0);
  263. float2 shroudTexCoord = In.ShroudTexCoord_CloudTexCoord.xy;
  264. float2 cloudTexCoord = In.ShroudTexCoord_CloudTexCoord.zw;
  265. // Note: we need to divide by 2 in VS and restore it in PS since COLOR register is clamped to 1
  266. float3 baseColor = GammaToLinear(baseTextureValue.xyz);
  267. float3 color = In.Color.xyz;
  268. float opacity = baseTextureValue.w * In.Color.w;
  269. // Add normal mapping lighting with main light source
  270. float3 normal = (float3)tex2D(SAMPLER(NormalMap), texCoord0) * 2 - 1;
  271. normal.xy *= BumpScale;
  272. normal = mul(normal, In.TangentToWorldSpace);
  273. normal = normalize(normal);
  274. float specularIntensity;
  275. float4 specTexture = tex2D(SAMPLER(SpecMap), texCoord0);
  276. specularIntensity = specTexture.x; // Specular lighting mask
  277. #if !defined(EA_PLATFORM_PS3) // PS3 TODO - 'sce-cgc' currently doesn not like this.
  278. // Compute point lights
  279. for (int i = 0; i < NumPointLights; i++)
  280. {
  281. color += CalculatePointLightDiffuse(PointLight[i], In.WorldPosition, normal);
  282. }
  283. #endif
  284. // Note: We need to divide by 2 in VS and restore it in PS since COLOR register is clamped to 1
  285. color *= baseColor * 2;
  286. float3 mainLightVector = DirectionalLight[0].Direction;
  287. float3 mainLightColor = DirectionalLight[0].Color;
  288. float4 lighting = lit(dot(normal, mainLightVector.xyz), dot(normal, In.MainLightHalfEyeVector), SpecularExponent);
  289. if (hasShadow)
  290. {
  291. lighting.yz *= shadow( SAMPLER(ShadowMap), In.ShadowMapTexCoord );
  292. }
  293. float3 cloud = GammaToLinear(tex2D( SAMPLER(CloudTexture), cloudTexCoord));
  294. color += mainLightColor * cloud * (lighting.y * baseColor + lighting.z * SpecularColor * specularIntensity);
  295. #if SUPPORT_SSAO
  296. color *= ComputeSSAO(vPos);
  297. #endif
  298. // Apply macro
  299. float2 MacroTexCoord = CalculateMacroTexCoord(In.WorldPosition.xyz);
  300. float3 macro = GammaToLinear(tex2D( SAMPLER(MacroSampler), MacroTexCoord));
  301. color *= macro;
  302. // Apply shroud
  303. float shroud = tex2D(SAMPLER(ShroudTexture), shroudTexCoord);
  304. color *= shroud;
  305. return CorrectForFrameBufferGamma(float4(color, opacity));
  306. }
  307. // ----------------------------------------------------------------------------
  308. // SHADER: PS_Xenon
  309. // ----------------------------------------------------------------------------
  310. float4 PS_Xenon( VSOutput_H In, float2 vPos : PIXELLOC) : COLOR
  311. {
  312. return PS_H( In, HasShadow, vPos );
  313. }
  314. // ----------------------------------------------------------------------------
  315. // Arrays: Default_H
  316. // ----------------------------------------------------------------------------
  317. DEFINE_ARRAY_MULTIPLIER( PS_H_Multiplier_NumShadows = 1 );
  318. #define PS_H_NumShadows \
  319. compile PS_3_0 PS_H(0), \
  320. compile PS_3_0 PS_H(1)
  321. DEFINE_ARRAY_MULTIPLIER( PS_H_Multiplier_Final = PS_H_Multiplier_NumShadows * 2 );
  322. #if SUPPORTS_SHADER_ARRAYS
  323. pixelshader PS_H_Array[PS_H_Multiplier_Final] =
  324. {
  325. PS_H_NumShadows
  326. };
  327. #endif
  328. // ----------------------------------------------------------------------------
  329. // Technique: Default
  330. // ----------------------------------------------------------------------------
  331. technique Default
  332. {
  333. pass p0
  334. {
  335. VertexShader = compile VS_3_0 VS_H();
  336. PixelShader = ARRAY_EXPRESSION_PS( PS_H_Array,
  337. HasShadow * PS_H_Multiplier_NumShadows,
  338. compile PS_VERSION PS_Xenon() );
  339. ZEnable = true;
  340. ZFunc = ZFUNC_INFRONT;
  341. ZWriteEnable = true;
  342. CullMode = CW;
  343. AlphaBlendEnable = false;
  344. AlphaTestEnable = true;
  345. AlphaFunc = GreaterEqual;
  346. AlphaRef = DEFAULT_ALPHATEST_THRESHOLD;
  347. }
  348. }
  349. #if ENABLE_LOD
  350. // ----------------------------------------------------------------------------
  351. // SHADER: DEFAULT (Medium)
  352. // ----------------------------------------------------------------------------
  353. struct VSOutput_M
  354. {
  355. float4 Position : POSITION;
  356. float4 TexCoord0_MacroTexCoord : TEXCOORD0;
  357. float4 ShroudTexCoord_CloudTexCoord : TEXCOORD1;
  358. float4 ShadowMapTexCoord : TEXCOORD2;
  359. float4 Color : COLOR;
  360. };
  361. // ----------------------------------------------------------------------------
  362. // SHADER: VS
  363. // ----------------------------------------------------------------------------
  364. VSOutput_M VS_M(VSInputSkinningOneBoneTangentFrame InSkin,
  365. float2 TexCoord0 : TEXCOORD0,
  366. DECLARE_VERTEXCOLOR_INPUT(VertexColor, 1, 2))
  367. {
  368. USE_VERTEXCOLOR(VertexColor);
  369. USE_TEXCOORD(TexCoord0);
  370. USE_DIRECTIONAL_LIGHT_INTERACTIVE(DirectionalLight, 0);
  371. VSOutput_M Out;
  372. float3 worldPosition = 0;
  373. float3 worldNormal = 0;
  374. float3 worldTangent = 0;
  375. float3 worldBinormal = 0;
  376. CalculatePositionAndTangentFrame(InSkin, 0,
  377. worldPosition, worldNormal, worldTangent, worldBinormal);
  378. // transform position to projection space
  379. Out.Position = mul(float4(worldPosition, 1), GetViewProjection());
  380. Out.Color = float4(AmbientLightColor * AmbientColor, OpacityOverride);
  381. // Compute remaining directional lights per vertex, others will be done in pixel shader
  382. float3 diffuseLight = 0;
  383. for (int i = 1; i < NumDirectionalLights; i++)
  384. {
  385. diffuseLight += DirectionalLight[i].Color * max(0, dot(worldNormal, DirectionalLight[i].Direction));
  386. }
  387. Out.Color.xyz += diffuseLight * DiffuseColor;
  388. Out.Color *= VertexColor;
  389. // pass texture coordinates for fetching the diffuse and normal maps
  390. Out.TexCoord0_MacroTexCoord.xy = TexCoord0.xy;
  391. Out.ShadowMapTexCoord = CalculateShadowMapTexCoord(worldPosition);
  392. Out.ShroudTexCoord_CloudTexCoord.xy = CalculateShroudTexCoord(Shroud, worldPosition);
  393. Out.ShroudTexCoord_CloudTexCoord.zw = CalculateCloudTexCoord(Cloud, worldPosition, Time);
  394. Out.TexCoord0_MacroTexCoord.zw = CalculateMacroTexCoord(worldPosition);
  395. return Out;
  396. }
  397. // ----------------------------------------------------------------------------
  398. // SHADER: PS
  399. // ----------------------------------------------------------------------------
  400. // This will save us .5ms on the GPU on a 6800 card. Worth it and there is no visual difference.
  401. #define float4 half4
  402. #define float3 half3
  403. #define float2 half2
  404. #define float half
  405. float4 PS_M(VSOutput_M In, uniform bool hasShadow) COLORTARGET
  406. {
  407. // Get diffuse color
  408. float2 texCoord0 = In.TexCoord0_MacroTexCoord.xy;
  409. float4 baseTextureValue = tex2D( SAMPLER(DiffuseTexture), texCoord0);
  410. // Get bump map normal
  411. // Scale normal to increase/decrease bump effect
  412. float3 bumpNormal = (float3)tex2D( SAMPLER(NormalMap), texCoord0) * 2.0 - 1.0;
  413. bumpNormal.xy *= BumpScale;
  414. bumpNormal = normalize(bumpNormal);
  415. float2 CloudTexCoord = In.ShroudTexCoord_CloudTexCoord.zw;
  416. float3 cloud = GammaToLinear(tex2D(SAMPLER(CloudTexture), CloudTexCoord));
  417. float3 mainLight = DirectionalLight[0].Color * max(0, dot(bumpNormal, DirectionalLight[0].Direction));
  418. mainLight *= cloud;
  419. if (hasShadow)
  420. {
  421. mainLight *= shadow( SAMPLER(ShadowMap), In.ShadowMapTexCoord );
  422. }
  423. float3 color = (In.Color.xyz + mainLight) * baseTextureValue.xyz;
  424. // Apply reflection or macro
  425. float2 MacroTexCoord = In.TexCoord0_MacroTexCoord.zw;
  426. float4 macro = tex2D( SAMPLER(MacroSampler), MacroTexCoord);
  427. // Apply macro
  428. color *= macro;
  429. // Apply shroud
  430. float2 shroudTexCoord = In.ShroudTexCoord_CloudTexCoord.xy;
  431. float shroud = tex2D( SAMPLER(ShroudTexture), shroudTexCoord).x;
  432. color *= shroud;
  433. // Calculate opacity
  434. float opacity = In.Color.w * baseTextureValue.w;
  435. return float4(color, opacity);
  436. }
  437. // We only want to do this for the really expensive part. The rest of the shader can be normal.
  438. #undef float4
  439. #undef float3
  440. #undef float2
  441. #undef float
  442. // ----------------------------------------------------------------------------
  443. // Arrays: Default_M
  444. // ----------------------------------------------------------------------------
  445. DEFINE_ARRAY_MULTIPLIER( PS_M_Multiplier_HasShadow = 1 );
  446. #define PS_M_HasShadow \
  447. compile PS_3_0 PS_M(false), \
  448. compile PS_3_0 PS_M(true)
  449. DEFINE_ARRAY_MULTIPLIER( PS_M_Multiplier_Final = PS_M_Multiplier_HasShadow * 2 );
  450. #if SUPPORTS_SHADER_ARRAYS
  451. pixelshader PS_M_Array[PS_M_Multiplier_Final] =
  452. {
  453. PS_M_HasShadow
  454. };
  455. #endif
  456. // ----------------------------------------------------------------------------
  457. // Technique: Default_M
  458. // ----------------------------------------------------------------------------
  459. technique Default_M
  460. {
  461. pass p0
  462. {
  463. VertexShader = compile VS_3_0 VS_M();
  464. PixelShader = ARRAY_EXPRESSION_PS( PS_M_Array,
  465. HasShadow * PS_M_Multiplier_HasShadow,
  466. NO_ARRAY_ALTERNATIVE);
  467. ZEnable = true;
  468. ZFunc = ZFUNC_INFRONT;
  469. ZWriteEnable = true;
  470. CullMode = CW;
  471. AlphaBlendEnable = false;
  472. AlphaTestEnable = true;
  473. AlphaFunc = GreaterEqual;
  474. AlphaRef = DEFAULT_ALPHATEST_THRESHOLD;
  475. }
  476. }
  477. // ----------------------------------------------------------------------------
  478. // SHADER: Low
  479. // ----------------------------------------------------------------------------
  480. struct VSOutput_L
  481. {
  482. float4 Position : POSITION;
  483. float4 TexCoord0_ShroudTexCoord : TEXCOORD0;
  484. float4 Color : TEXCOORD1;
  485. };
  486. // ----------------------------------------------------------------------------
  487. // SHADER: VS
  488. // ----------------------------------------------------------------------------
  489. VSOutput_L VS_L(VSInputSkinningOneBoneTangentFrame InSkin,
  490. float2 TexCoord0 : TEXCOORD0,
  491. DECLARE_VERTEXCOLOR_INPUT(VertexColor, 1, 2))
  492. {
  493. USE_VERTEXCOLOR(VertexColor);
  494. USE_TEXCOORD(TexCoord0);
  495. USE_DIRECTIONAL_LIGHT_INTERACTIVE(DirectionalLight, 0);
  496. VSOutput_L Out;
  497. float3 worldPosition = 0;
  498. float3 worldNormal = 0;
  499. float3 worldTangent = 0;
  500. float3 worldBinormal = 0;
  501. CalculatePositionAndTangentFrame(InSkin, 0,
  502. worldPosition, worldNormal, worldTangent, worldBinormal);
  503. // transform position to projection space
  504. Out.Position = mul(float4(worldPosition, 1), GetViewProjection());
  505. Out.Color = float4(AmbientLightColor * AmbientColor, OpacityOverride);
  506. // Compute remaining directional lights per vertex, others will be done in pixel shader
  507. float3 diffuseLight = 0;
  508. for (int i = 0; i < NumDirectionalLights; i++)
  509. {
  510. diffuseLight += DirectionalLight[i].Color * max(0, dot(worldNormal, DirectionalLight[i].Direction));
  511. }
  512. Out.Color.xyz += diffuseLight * DiffuseColor;
  513. Out.Color *= VertexColor;
  514. // pass texture coordinates for fetching the diffuse and normal maps
  515. Out.TexCoord0_ShroudTexCoord.xy = TexCoord0.xy;
  516. Out.TexCoord0_ShroudTexCoord.zw = CalculateShroudTexCoord(Shroud, worldPosition);
  517. return Out;
  518. }
  519. // ----------------------------------------------------------------------------
  520. // SHADER: PS
  521. // ----------------------------------------------------------------------------
  522. float4 PS_L(VSOutput_L In) COLORTARGET
  523. {
  524. // Get diffuse color
  525. float2 texCoord0 = In.TexCoord0_ShroudTexCoord.xy;
  526. float4 baseTextureValue = tex2D( SAMPLER(DiffuseTexture), texCoord0);
  527. float4 color = In.Color * baseTextureValue;
  528. // Apply shroud
  529. float2 shroudTexCoord = In.TexCoord0_ShroudTexCoord.zw;
  530. float shroud = tex2D( SAMPLER(ShroudTexture), shroudTexCoord).x;
  531. color.xyz *= shroud;
  532. return color;
  533. }
  534. // ----------------------------------------------------------------------------
  535. // Technique: Default_L
  536. // ----------------------------------------------------------------------------
  537. technique Default_L
  538. {
  539. pass p0
  540. {
  541. VertexShader = compile VS_2_0 VS_L();
  542. PixelShader = compile PS_2_0 PS_L();
  543. ZEnable = true;
  544. ZFunc = ZFUNC_INFRONT;
  545. ZWriteEnable = true;
  546. CullMode = CW;
  547. AlphaBlendEnable = false;
  548. AlphaTestEnable = true;
  549. AlphaFunc = GreaterEqual;
  550. AlphaRef = DEFAULT_ALPHATEST_THRESHOLD;
  551. }
  552. }
  553. #endif // ENABLE_LOD
  554. // ----------------------------------------------------------------------------
  555. // SHADER: CreateShadowMapVS
  556. // ----------------------------------------------------------------------------
  557. struct VSOutput_CreateShadowMap
  558. {
  559. float4 Position : POSITION;
  560. float2 TexCoord0 : TEXCOORD0;
  561. float Depth : TEXCOORD1;
  562. float Opacity : COLOR0;
  563. };
  564. // ----------------------------------------------------------------------------
  565. VSOutput_CreateShadowMap CreateShadowMapVS(VSInputSkinningOneBoneTangentFrame InSkin,
  566. float2 TexCoord0 : TEXCOORD0,
  567. float4 VertexColor: COLOR0)
  568. {
  569. VSOutput_CreateShadowMap Out;
  570. float3 worldPosition = 0;
  571. float3 worldNormal = 0;
  572. float3 worldTangent = 0;
  573. float3 worldBinormal = 0;
  574. CalculatePositionAndTangentFrame(InSkin, 0,
  575. worldPosition, worldNormal, worldTangent, worldBinormal);
  576. #if defined(_3DSMAX_)
  577. // Default vertex color is 0 in Max, that's bad.
  578. VertexColor = 1.0;
  579. #endif
  580. // Transform position to projection space
  581. ISOLATE Out.Position = mul(float4(worldPosition, 1), GetViewProjection());
  582. Out.Depth = Out.Position.z / Out.Position.w;
  583. Out.Opacity = OpacityOverride * VertexColor.w;
  584. Out.TexCoord0 = TexCoord0;
  585. return Out;
  586. }
  587. // ----------------------------------------------------------------------------
  588. float4 CreateShadowMapPS(VSOutput_CreateShadowMap In) : COLOR
  589. {
  590. float opacity = tex2D(SAMPLER(DiffuseTexture), In.TexCoord0).w;
  591. opacity *= In.Opacity;
  592. // Simulate alpha testing for floating point render target
  593. clip(opacity - ((float)DEFAULT_ALPHATEST_THRESHOLD / 255));
  594. return In.Depth;
  595. }
  596. // ----------------------------------------------------------------------------
  597. // Technique _CreateShadowMap
  598. // ----------------------------------------------------------------------------
  599. technique _CreateShadowMap
  600. {
  601. pass p0
  602. {
  603. VertexShader = compile VS_2_0 CreateShadowMapVS();
  604. PixelShader = compile PS_2_0 CreateShadowMapPS();
  605. ZEnable = true;
  606. ZFunc = ZFUNC_INFRONT;
  607. ZWriteEnable = true;
  608. CullMode = CW;
  609. AlphaBlendEnable = false;
  610. AlphaTestEnable = false;
  611. }
  612. }