Terrain.fx 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898
  1. //////////////////////////////////////////////////////////////////////////////
  2. // ©2005 Electronic Arts Inc
  3. //
  4. // Terrain FX Shader
  5. //////////////////////////////////////////////////////////////////////////////
  6. #define SUPPORT_SSAO 1 // enable SSAO
  7. #define SUPPORT_CLOUDS 1
  8. #define SUPPORT_FOG 1
  9. #define SUPPORT_GLOBAL_LIGHTS 1
  10. #define SUPPORT_LOCAL_LIGHTS 1
  11. #define MaxNumPointLights 6
  12. #include "Common.fxh"
  13. #include "SSAO.fxh"
  14. #include "Gamma.fxh"
  15. #include "MacroTexture.fxh"
  16. #if defined(EA_PLATFORM_XENON)
  17. #define TERRAIN_USE_MULTIPLE_STREAM
  18. #endif
  19. static const float SpecularExponent = 40;
  20. static const float BumpScale = .75;
  21. static const bool EnableNormalMap = true;
  22. static const float HDRColorRange = 2.0f;
  23. static const float3 SpecularColor = float3(1.0, 1.0, 1.0) * HDRColorRange;
  24. // The Blendweight is the alpha value at the corner
  25. //
  26. // 0-----3
  27. // | |
  28. // | |
  29. // | |
  30. // 1-----2
  31. // Since the values is normalize to be > 0, we need to add 1 so -1 become 0 in the lookup table
  32. static const float4 BLENDWEIGHT_LUT[2][13] =
  33. {
  34. // Normal
  35. {
  36. { 1.0, 1.0, 1.0, 1.0 }, // BLENDTYPE_NONE
  37. { 1.0, 1.0, 2.0, 2.0 }, // BLENDTYPE_HORIZONTAL,
  38. { 2.0, 2.0, 1.0, 1.0 }, // BLENDTYPE_HORIZONTAL_INVERTED,
  39. { 2.0, 1.0, 1.0, 2.0 }, // BLENDTYPE_VERTICAL,
  40. { 1.0, 2.0, 2.0, 1.0 }, // BLENDTYPE_VERTICAL_INVERTED,
  41. { 1.0, 0.0, 1.0, 2.0 }, // BLENDTYPE_RIGHTDIAGONAL,
  42. { 0.0, 1.0, 2.0, 1.0 }, // BLENDTYPE_RIGHTDIAGONAL_INVERTED,
  43. { 2.0, 1.0, 2.0, 3.0 }, // BLENDTYPE_RIGHTDIAGONAL_LONG,
  44. { 1.0, 2.0, 3.0, 2.0 }, // BLENDTYPE_RIGHTDIAGONAL_LONG_INVERTED,
  45. { 2.0, 1.0, 0.0, 1.0 }, // BLENDTYPE_LEFTDIAGONAL,
  46. { 1.0, 2.0, 1.0, 0.0 }, // BLENDTYPE_LEFTDIAGONAL_INVERTED,
  47. { 3.0, 2.0, 1.0, 2.0 }, // BLENDTYPE_LEFTDIAGONAL_LONG,
  48. { 2.0, 3.0, 2.0, 1.0 }, // BLENDTYPE_LEFTDIAGONAL_LONG_INVERTED,
  49. },
  50. // Flipped (first column from Normal is moved to the last)
  51. {
  52. { 1.0, 1.0, 1.0, 1.0 }, // BLENDTYPE_NONE
  53. { 1.0, 2.0, 2.0, 1.0 }, // BLENDTYPE_HORIZONTAL,
  54. { 2.0, 1.0, 1.0, 2.0 }, // BLENDTYPE_HORIZONTAL_INVERTED,
  55. { 1.0, 1.0, 2.0, 2.0 }, // BLENDTYPE_VERTICAL,
  56. { 2.0, 2.0, 1.0, 1.0 }, // BLENDTYPE_VERTICAL_INVERTED,
  57. { 0.0, 1.0, 2.0, 1.0 }, // BLENDTYPE_RIGHTDIAGONAL,
  58. { 1.0, 2.0, 1.0, 0.0 }, // BLENDTYPE_RIGHTDIAGONAL_INVERTED,
  59. { 1.0, 2.0, 3.0, 2.0 }, // BLENDTYPE_RIGHTDIAGONAL_LONG,
  60. { 2.0, 3.0, 2.0, 1.0 }, // BLENDTYPE_RIGHTDIAGONAL_LONG_INVERTED,
  61. { 1.0, 0.0, 1.0, 2.0 }, // BLENDTYPE_LEFTDIAGONAL,
  62. { 2.0, 1.0, 0.0, 1.0 }, // BLENDTYPE_LEFTDIAGONAL_INVERTED,
  63. { 2.0, 1.0, 2.0, 3.0 }, // BLENDTYPE_LEFTDIAGONAL_LONG,
  64. { 3.0, 2.0, 1.0, 2.0 }, // BLENDTYPE_LEFTDIAGONAL_LONG_INVERTED,
  65. }
  66. };
  67. // The vertex generated in the order is
  68. // v3-----v2
  69. // | |
  70. // | |
  71. // | |
  72. // v0-----v1
  73. //
  74. // The 2 tri we are building is 0,1,3 and 3,1,2
  75. // 0-----3 3-----2
  76. // | / | |\ |
  77. // | / | | \ |
  78. // |/ | | \|
  79. // 1-----2 0-----1
  80. // Normal Flipped
  81. //
  82. // The reference point for x,y is v0, the following table holds the adjustment of x and y depends on the index (0-3)
  83. // For UV offset, the reference point is v3
  84. #define UV_OFFSET_PER_CELL 469
  85. static const float4 TERRAIN_CORNER_INDEX_OFFSET_LUT[2][4] =
  86. {
  87. // float4(x, y, UV offset x (per cell), UV offset y (per cell) )
  88. // Normal
  89. {
  90. float4( 1.0, 0.0, 0, 0 ),
  91. float4( 0.0, 0.0, 0, UV_OFFSET_PER_CELL ),
  92. float4( 0.0, 1.0, UV_OFFSET_PER_CELL, UV_OFFSET_PER_CELL ),
  93. float4( 1.0, 1.0, UV_OFFSET_PER_CELL, 0 ),
  94. }
  95. , // Flipped
  96. {
  97. float4( 0.0, 0.0, 0, 0 ),
  98. float4( 0.0, 1.0, UV_OFFSET_PER_CELL, 0 ),
  99. float4( 1.0, 1.0, UV_OFFSET_PER_CELL,-UV_OFFSET_PER_CELL ),
  100. float4( 1.0, 0.0, 0,-UV_OFFSET_PER_CELL ),
  101. }
  102. };
  103. #if !HIZ_CULLING
  104. #define SCORCHMARK_Z_BIAS -0.0002
  105. #define ROAD_Z_BIAS -0.0004
  106. #else
  107. #define SCORCHMARK_Z_BIAS 0.0002
  108. #define ROAD_Z_BIAS 0.0004
  109. #endif
  110. int _SasGlobal : SasGlobal
  111. <
  112. string UIWidget = "None";
  113. int3 SasVersion = int3(1, 0, 0);
  114. int MaxLocalLights = MaxNumPointLights;
  115. > = 0;
  116. // ----------------------------------------------------------------------------
  117. // Terrain specific textures
  118. // ----------------------------------------------------------------------------
  119. SAMPLER_2D_BEGIN( BaseSamplerClamped,
  120. string UIWidget = "None";
  121. string SasBindAddress = "Terrain.BaseTexture";
  122. int WW3DDynamicSet = DS_CUSTOM_FIRST;
  123. )
  124. MinFilter = MinFilterBest;
  125. MagFilter = MagFilterBest;
  126. MipFilter = MipFilterBest;
  127. MaxAnisotropy = 8;
  128. AddressU = Clamp;
  129. AddressV = Clamp;
  130. SAMPLER_2D_END
  131. SAMPLER_2D_BEGIN( BaseSamplerClamped_L,
  132. string UIWidget = "None";
  133. string SasBindAddress = "Terrain.BaseTexture";
  134. int WW3DDynamicSet = DS_CUSTOM_FIRST;
  135. )
  136. MinFilter = Linear;
  137. MagFilter = Linear;
  138. MipFilter = Point;
  139. MaxAnisotropy = 1;
  140. AddressU = Clamp;
  141. AddressV = Clamp;
  142. SAMPLER_2D_END
  143. SAMPLER_2D_BEGIN( BaseSamplerWrapped,
  144. string UIWidget = "None";
  145. string SasBindAddress = "Terrain.BaseTexture";
  146. int WW3DDynamicSet = DS_CUSTOM_FIRST;
  147. )
  148. MinFilter = MinFilterBest;
  149. MagFilter = MagFilterBest;
  150. MipFilter = MipFilterBest;
  151. MaxAnisotropy = 8;
  152. AddressU = Wrap;
  153. AddressV = Wrap;
  154. SAMPLER_2D_END
  155. SAMPLER_2D_BEGIN( BaseSamplerWrapped_L,
  156. string UIWidget = "None";
  157. string SasBindAddress = "Terrain.BaseTexture";
  158. int WW3DDynamicSet = DS_CUSTOM_FIRST;
  159. )
  160. MinFilter = Linear;
  161. MagFilter = Linear;
  162. MipFilter = Point;
  163. MaxAnisotropy = 1;
  164. AddressU = Wrap;
  165. AddressV = Wrap;
  166. SAMPLER_2D_END
  167. SAMPLER_2D_BEGIN( NormalSamplerClamped,
  168. string UIWidget = "None";
  169. string SasBindAddress = "Terrain.NormalTexture";
  170. int WW3DDynamicSet = DS_CUSTOM_FIRST;
  171. )
  172. MinFilter = MinFilterBest;
  173. MagFilter = MagFilterBest;
  174. MipFilter = Linear;
  175. MaxAnisotropy = 8;
  176. AddressU = Clamp;
  177. AddressV = Clamp;
  178. SAMPLER_2D_END
  179. SAMPLER_2D_BEGIN( NormalSamplerWrapped,
  180. string UIWidget = "None";
  181. string SasBindAddress = "Terrain.NormalTexture";
  182. int WW3DDynamicSet = DS_CUSTOM_FIRST;
  183. )
  184. MinFilter = MinFilterBest;
  185. MagFilter = MagFilterBest;
  186. MipFilter = Linear;
  187. MaxAnisotropy = 8;
  188. AddressU = Wrap;
  189. AddressV = Wrap;
  190. SAMPLER_2D_END
  191. // ----------------------------------------------------------------------------
  192. // Shroud
  193. // ----------------------------------------------------------------------------
  194. ShroudSetup Shroud
  195. <
  196. string UIWidget = "None";
  197. string SasBindAddress = "Terrain.Shroud";
  198. > = DEFAULT_SHROUD;
  199. SAMPLER_2D_BEGIN( ShroudSampler,
  200. string UIWidget = "None";
  201. string SasBindAddress = "Terrain.Shroud.Texture";
  202. )
  203. MinFilter = Linear;
  204. MagFilter = Linear;
  205. MipFilter = Linear;
  206. AddressU = Clamp;
  207. AddressV = Clamp;
  208. SAMPLER_2D_END
  209. // ----------------------------------------------------------------------------
  210. // Cloud textures
  211. // ----------------------------------------------------------------------------
  212. SAMPLER_2D_BEGIN( CloudSampler,
  213. string UIWidget = "None";
  214. string SasBindAddress = "Terrain.Cloud.Texture";
  215. string ResourceName = "ShaderPreviewCloud.dds";
  216. )
  217. MinFilter = Linear;
  218. MagFilter = Linear;
  219. MipFilter = Linear;
  220. AddressU = Wrap;
  221. AddressV = Wrap;
  222. SAMPLER_2D_END
  223. static const int RenderingMode_TerrainTile = 0;
  224. static const int RenderingMode_Cliff = 1;
  225. static const int RenderingMode_Road = 2;
  226. static const int RenderingMode_Scorch = 3;
  227. static const int RenderingMode_NumOf = 4;
  228. // ----------------------------------------------------------------------------
  229. // Using Terrain Atlas for rendering
  230. // ----------------------------------------------------------------------------
  231. #if defined(EA_PLATFORM_WINDOWS)
  232. bool IsTerrainAtlasEnabled
  233. <
  234. string UIWidget = "None";
  235. string SasBindAddress = "Terrain.IsTerrainAtlasEnabled";
  236. > = false;
  237. #endif // #if defined(EA_PLATFORM_WINDOWS)
  238. // ----------------------------------------------------------------------------
  239. // Shadow mapping
  240. // ----------------------------------------------------------------------------
  241. // Note (WSK) 2008/05/28 - leaving this here since if we move this up, the registers are shifted and
  242. // some register seems to get stomped on if we don't define these here on Xenon.
  243. #include "ShadowMap.fxh"
  244. // ----------------------------------------------------------------------------
  245. // Transformations
  246. // ----------------------------------------------------------------------------
  247. #if defined(_WW3D_)
  248. #if !defined(USE_INDIRECT_CONSTANT)
  249. float3 EyePosition
  250. <
  251. string UIWidget = "None";
  252. string SasBindAddress = "Sas.Camera.Position";
  253. >;
  254. float4x4 ViewProjection
  255. <
  256. string UIWidget = "None";
  257. string SasBindAddress = "Sas.Camera.WorldToProjection";
  258. >;
  259. #endif // #if !defined(USE_INDIRECT_CONSTANT)
  260. float3 GetEyePosition()
  261. {
  262. return EyePosition;
  263. }
  264. float4x4 GetViewProjection()
  265. {
  266. return ViewProjection;
  267. }
  268. #else // #if defined(_WW3D_)
  269. float4x4 View : View;
  270. float4x3 ViewI : ViewInverse;
  271. float4x4 Projection : Projection;
  272. float3 GetEyePosition()
  273. {
  274. return ViewI[3];
  275. }
  276. float4x4 GetViewProjection()
  277. {
  278. return mul(View, Projection);
  279. }
  280. #endif // #if defined(_WW3D_)
  281. // Time (ie. material is animated)
  282. float Time : Time;
  283. // ---------------------------------------------------------------------------
  284. struct VSOutputDefault
  285. {
  286. float4 Position : POSITION;
  287. float4 Color : COLOR0;
  288. float Fog : COLOR1;
  289. float4 BaseTexCoord_BlendWeight : TEXCOORD0;
  290. float4 BlendTex1Coord_BlendTex2Coord : TEXCOORD1;
  291. float2 ShroudTexCoord : TEXCOORD2;
  292. float3 WorldPosition : TEXCOORD3;
  293. float4 MainLightDirection_Falloff : TEXCOORD4;
  294. float3 MainHalfEyeLightDirection : TEXCOORD5_CENTROID;
  295. float4 ShadowMapTexCoord : TEXCOORD6;
  296. };
  297. // ---------------------------------------------------------------------------
  298. VSOutputDefault VS_Default(
  299. float3 Position : POSITION,
  300. float3 Normal : NORMAL,
  301. float4 Color : COLOR0,
  302. float2 BaseTexCoord : TEXCOORD0,
  303. float3 Tangent : TANGENT,
  304. float3 Binormal : BINORMAL,
  305. uniform int renderingMode,
  306. uniform bool isTextureAtlasEnabled
  307. )
  308. {
  309. VSOutputDefault Out;
  310. ISOLATE Out.Position = mul(float4(Position, 1), GetViewProjection());
  311. float3 worldPosition = Position;
  312. Out.Fog = CalculateFog(Fog, worldPosition, GetEyePosition());
  313. float3 worldNormal = Normal;
  314. float3 tangent;
  315. float3 binormal;
  316. if(renderingMode == RenderingMode_Scorch)
  317. {
  318. tangent = Tangent;
  319. binormal = Binormal;
  320. }
  321. else
  322. {
  323. tangent = cross(worldNormal, float3(-1, 0, 0));
  324. binormal = cross(worldNormal, float3(0, 1, 0));
  325. }
  326. // Build 3x3 tranform from object to tangent space
  327. float3x3 worldToTangentSpace = transpose(float3x3(-binormal, -tangent, Normal));
  328. // Compute lighting direction in tangent space
  329. float3 worldLightDir = DirectionalLight[0].Direction;
  330. Out.MainLightDirection_Falloff.xyz = mul(worldLightDir, worldToTangentSpace);
  331. Out.MainLightDirection_Falloff.w = max(0, dot(worldNormal, DirectionalLight[0].Direction));
  332. // Compute view direction in tangent space
  333. float3 worldEyeDir = normalize(GetEyePosition() - worldPosition);
  334. Out.MainHalfEyeLightDirection = normalize(mul(worldLightDir + worldEyeDir, worldToTangentSpace));
  335. // Do vertex lighting for light 1 to n
  336. float3 diffuseLight = 0;
  337. for (int i = 1; i < NumDirectionalLights; i++)
  338. {
  339. diffuseLight += DirectionalLight[i].Color * max(0, dot(worldNormal, DirectionalLight[i].Direction));
  340. }
  341. float3 diffuseColor = (AmbientLightColor + diffuseLight) * Color.xyz;
  342. diffuseColor /= HDRColorRange; // Overbright rendering is already applied in the light color, however we want to do it later in the pixel shader.
  343. Out.Color = float4(diffuseColor, Color.w);
  344. // Output texture information
  345. Out.BaseTexCoord_BlendWeight.xy = BaseTexCoord;
  346. // Initialize terrain tile only data
  347. Out.BaseTexCoord_BlendWeight.zw = float2(0, 0);
  348. Out.BlendTex1Coord_BlendTex2Coord = float4(0, 0, 0, 0);
  349. float2 ShroudTexCoord = CalculateShroudTexCoord(Shroud, worldPosition);
  350. // float2 CloudTexCoord = CalculateCloudTexCoord(Cloud, worldPosition, Time);
  351. // float2 MacroTexCoord = CalculateMacroTexCoord(worldPosition);
  352. Out.ShroudTexCoord = ShroudTexCoord;
  353. Out.WorldPosition = worldPosition;
  354. // Out.CloudTexCoord_MacroTexCoord.xy = CloudTexCoord.xy;
  355. // Out.CloudTexCoord_MacroTexCoord.zw = MacroTexCoord.yx;
  356. if(renderingMode == RenderingMode_Road || renderingMode == RenderingMode_TerrainTile && !isTextureAtlasEnabled)
  357. {
  358. Out.ShadowMapTexCoord = CalculateShadowMapTexCoord_PerspectiveCorrect(worldPosition);
  359. }
  360. else
  361. {
  362. Out.ShadowMapTexCoord = CalculateShadowMapTexCoord(worldPosition);
  363. }
  364. return Out;
  365. }
  366. // ---------------------------------------------------------------------------
  367. VSOutputDefault VS_TerrainTile(
  368. float4 Position_BlendWeight1 : POSITION,
  369. float4 Normal_BlendWeight2 : NORMAL0,
  370. float2 BaseTexCoord : TEXCOORD0,
  371. float2 BlendTex1Coord : TEXCOORD1,
  372. float2 BlendTex2Coord : TEXCOORD2,
  373. float3 Tangent : TANGENT,
  374. float3 Binormal : BINORMAL,
  375. uniform bool isTextureAtlasEnabled
  376. )
  377. {
  378. VSOutputDefault Out;
  379. float3 Position = Position_BlendWeight1.xyz;
  380. float3 Normal = Normal_BlendWeight2.xyz;
  381. float BlendWeight1 = 0.0;
  382. float BlendWeight2 = 0.0;
  383. #if defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XENON)
  384. if (isTextureAtlasEnabled) // [PS3] TODO - this 'if' causes issues when running.
  385. #endif
  386. {
  387. // Unpack vertex data
  388. Normal = (Normal_BlendWeight2.xyz / 100.0) - 1.0;
  389. BaseTexCoord = (BaseTexCoord / 30000.0);
  390. BlendTex1Coord = (BlendTex1Coord / 30000.0);
  391. BlendTex2Coord = (BlendTex2Coord / 30000.0);
  392. BlendWeight1 = Position_BlendWeight1.w - 1.0;
  393. BlendWeight2 = Normal_BlendWeight2.w - 1.0;
  394. }
  395. // Delegate main computations to VS_Default
  396. Out = VS_Default(Position, Normal, float4(1.0, 1.0, 1.0, 1.0), BaseTexCoord, Tangent, Binormal, RenderingMode_TerrainTile, isTextureAtlasEnabled);
  397. #if defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XENON)
  398. if (isTextureAtlasEnabled) // [PS3] TODO - this 'if' causes issues when running.
  399. #endif
  400. {
  401. // Note: intentionally switch 1 and 2
  402. Out.BaseTexCoord_BlendWeight.z = BlendWeight2;
  403. Out.BaseTexCoord_BlendWeight.w = BlendWeight1;
  404. Out.BlendTex1Coord_BlendTex2Coord.xy = BlendTex1Coord.xy;
  405. Out.BlendTex1Coord_BlendTex2Coord.zw = BlendTex2Coord.yx;
  406. }
  407. return Out;
  408. }
  409. #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  410. VSOutputDefault VS_TerrainTileVFetch(
  411. int Index : INDEX,
  412. uniform bool isTextureAtlasEnabled
  413. )
  414. {
  415. VSOutputDefault Out;
  416. float4 BaseTexCoord;
  417. float4 BlendTex1Coord;
  418. float4 BlendTex2Coord;
  419. float3 Tangent = float3(-1, 0, 0);
  420. float3 Binormal = float3(0, 1, 0);
  421. float4 FlipVisibleFlag;
  422. float4 BlendWeights;
  423. // Fetching the cell index for UV info
  424. float cellIndex = trunc(Index / 4.0);
  425. // Fetch the UV information
  426. asm
  427. {
  428. vfetch BaseTexCoord, cellIndex, texcoord3;
  429. vfetch BlendTex1Coord, cellIndex, texcoord4;
  430. vfetch BlendTex2Coord, cellIndex, texcoord5;
  431. vfetch BlendWeights, cellIndex, texcoord6;
  432. vfetch FlipVisibleFlag, cellIndex, texcoord7;
  433. };
  434. // Getting the flags
  435. float IsFlipped = FlipVisibleFlag.x;
  436. float IsVisible = FlipVisibleFlag.y;
  437. // Calculate the index within a cell (0-3)
  438. float vertexIndex = fmod(Index, 4.0);
  439. // Calculate the base row and column index for the corner vertex
  440. const float vertsPerTile = 16.0;
  441. float2 xy = float2(trunc(cellIndex / vertsPerTile), fmod(cellIndex, vertsPerTile)) + TERRAIN_CORNER_INDEX_OFFSET_LUT[IsFlipped][vertexIndex].xy;
  442. // Update the UV offset based on the vertexIndex
  443. float2 uvOffset = TERRAIN_CORNER_INDEX_OFFSET_LUT[IsFlipped][vertexIndex].zw;
  444. BaseTexCoord.xy += uvOffset.xy;
  445. BlendTex1Coord.xy += uvOffset.xy;
  446. BlendTex2Coord.xy += uvOffset.xy;
  447. // Calculate the corner index, after all the offset
  448. float cornerIndex = xy.y + xy.x * (vertsPerTile + 1.0);
  449. float4 Position_BlendWeight1;
  450. float4 Normal_BlendWeight2;
  451. // Fetch the position and normal data
  452. asm
  453. {
  454. vfetch Position_BlendWeight1, cornerIndex, position0;
  455. vfetch Normal_BlendWeight2, cornerIndex, normal0;
  456. };
  457. // Multiply xy by visible, to force x,y be 0,0 for invisible tile
  458. Position_BlendWeight1.xy *= IsVisible;
  459. // Look up the blend weights
  460. Position_BlendWeight1.w = BLENDWEIGHT_LUT[IsFlipped][BlendWeights.x][vertexIndex];
  461. Normal_BlendWeight2.w = BLENDWEIGHT_LUT[IsFlipped][BlendWeights.y][vertexIndex];
  462. // Call the original TerrainTile info
  463. Out = VS_TerrainTile( Position_BlendWeight1, Normal_BlendWeight2, BaseTexCoord, BlendTex1Coord, BlendTex2Coord, Tangent, Binormal, isTextureAtlasEnabled);
  464. return Out;
  465. }
  466. #endif // #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  467. // ---------------------------------------------------------------------------
  468. VSOutputDefault VS_TerrainScorch(
  469. float4 Position_BlendWeight1 : POSITION,
  470. float4 Normal_unpack : NORMAL0,
  471. float4 Color : COLOR0,
  472. float2 BaseTexCoord : TEXCOORD0,
  473. float4 Tangent_unpack : TANGENT,
  474. float4 Binormal_unpack : BINORMAL
  475. )
  476. {
  477. VSOutputDefault Out;
  478. float3 Position = Position_BlendWeight1.xyz;
  479. // Unpack vertex data
  480. float3 Normal = (Normal_unpack.xyz * 255 / 100.0) - 1.0;
  481. float3 Tangent = (Tangent_unpack.xyz * 255 / 100.0) - 1.0;
  482. float3 Binormal = (Tangent_unpack.xyz * 255 / 100.0) - 1.0;
  483. BaseTexCoord = (BaseTexCoord / 30000.0);
  484. // Delegate main computations to VS_Default
  485. return VS_Default(Position, Normal, Color, BaseTexCoord, Tangent, Binormal, RenderingMode_Scorch, false);
  486. }
  487. // ---------------------------------------------------------------------------
  488. #if defined(EA_PLATFORM_PS3)
  489. float4 PS_Default_PS3(VSOutputDefault In, uniform int renderingMode,
  490. uniform sampler2D baseSampler, uniform sampler2D normalSampler,
  491. uniform bool hasShadow, uniform bool isTextureAtlasEnabled,
  492. float2 vPos : PIXELLOC )
  493. {
  494. float2 BaseTexCoord = In.BaseTexCoord_BlendWeight.xy;
  495. float4 baseTextureValue = tex2D(baseSampler, BaseTexCoord);
  496. float2 CloudTexCoord = CalculateCloudTexCoord(Cloud, In.WorldPosition.xyz, Time);
  497. float2 MacroTexCoord = CalculateMacroTexCoord(In.WorldPosition.xyz);
  498. // Doing first and second blend
  499. float2 blendWeight = saturate(In.BaseTexCoord_BlendWeight.wz);
  500. if(renderingMode == RenderingMode_TerrainTile && isTextureAtlasEnabled)
  501. {
  502. float4 texColor1 = tex2D(baseSampler, In.BlendTex1Coord_BlendTex2Coord.xy);
  503. float4 texColor2 = tex2D(baseSampler, In.BlendTex1Coord_BlendTex2Coord.wz);
  504. baseTextureValue = lerp(lerp(baseTextureValue, texColor1, blendWeight[0]), texColor2, blendWeight[1]);
  505. }
  506. float3 baseColor = GammaToLinear(baseTextureValue.xyz);
  507. float3 color = In.Color.xyz;
  508. float opacity = In.Color.w;
  509. if (renderingMode == RenderingMode_Road || renderingMode == RenderingMode_Scorch)
  510. {
  511. opacity *= baseTextureValue.w;
  512. }
  513. // Add normal mapping lighting with main light source
  514. float3 normal;
  515. float specularIntensity;
  516. if (renderingMode == RenderingMode_Road || renderingMode == RenderingMode_Scorch)
  517. {
  518. float4 normal_specular = tex2D(normalSampler, BaseTexCoord);
  519. normal = normal_specular.xyz * 2 - 1;
  520. specularIntensity = normal_specular.w;
  521. }
  522. else
  523. {
  524. float3 normal_specular = tex2D(normalSampler, BaseTexCoord).xyz;
  525. if(renderingMode == RenderingMode_TerrainTile && isTextureAtlasEnabled)
  526. {
  527. float3 normal_specular1 = tex2D(normalSampler, In.BlendTex1Coord_BlendTex2Coord.xy).xyz;
  528. float3 normal_specular2 = tex2D(normalSampler, In.BlendTex1Coord_BlendTex2Coord.wz).xyz;
  529. specularIntensity = baseTextureValue.w;
  530. normal = lerp(lerp(normal_specular, normal_specular1, blendWeight[0]), normal_specular2, blendWeight[1]) * 2 - 1;
  531. }
  532. else
  533. {
  534. specularIntensity = normal_specular.z;
  535. normal.xy = normal_specular.xy * 2 - 1;
  536. normal.z = sqrt(1 - normal.x * normal.x - normal.y * normal.y);
  537. }
  538. }
  539. normal.xy *= BumpScale;
  540. normal = normalize(normal);
  541. if (!EnableNormalMap)
  542. normal = float3(0, 0, 1);
  543. // Compute point lights
  544. #if !defined(EA_PLATFORM_PS3)
  545. for (int i = 0; i < NumPointLights; i++)
  546. {
  547. color += CalculatePointLightDiffuse(PointLight[i], In.WorldPosition, normal);
  548. }
  549. #endif
  550. // Apply texture color
  551. // Note: we need to divide by 2 in VS and restore it in PS since COLOR register is clamped to 1
  552. color *= HDRColorRange * baseColor;
  553. float3 mainLightColor = DirectionalLight[0].Color;
  554. float4 lighting = lit(dot(normal, In.MainLightDirection_Falloff.xyz), dot(normal, In.MainHalfEyeLightDirection), SpecularExponent);
  555. #if 0 // Disable shadow for now.
  556. if (hasShadow)
  557. {
  558. if(renderingMode == RenderingMode_Road || renderingMode == RenderingMode_TerrainTile && !isTextureAtlasEnabled)
  559. {
  560. lighting.yz *= shadow_PerspectiveCorrect( SAMPLER(ShadowMap), In.ShadowMapTexCoord );
  561. }
  562. else
  563. {
  564. lighting.yz *= shadow( SAMPLER(ShadowMap), In.ShadowMapTexCoord );
  565. }
  566. }
  567. #endif
  568. #if 0 // Disable for now.
  569. float3 cloud = GammaToLinear(tex2D( SAMPLER(CloudSampler), CloudTexCoord));
  570. color += mainLightColor * cloud * (lighting.y * baseColor + lighting.z * SpecularColor * specularIntensity);
  571. #endif
  572. #if SUPPORT_SSAO
  573. color *= ComputeSSAO(vPos);
  574. #endif
  575. #if 0 // Disable for now.
  576. // Apply macro
  577. float3 macro = GammaToLinear(tex2D( SAMPLER(MacroSampler), MacroTexCoord));
  578. color *= macro;
  579. // Apply fog
  580. color = lerp(Fog.Color, color, In.Fog);
  581. #endif
  582. // Apply shroud
  583. float2 shroudTexCoord = In.ShroudTexCoord;
  584. float shroud = tex2D( SAMPLER(ShroudSampler), shroudTexCoord).x;
  585. baseColor *= shroud;
  586. #if 0 // Disable for now.
  587. return float4(color, opacity);
  588. #else
  589. return float4(baseColor, 1);
  590. #endif
  591. }
  592. float4 PS_Default_PS3_Terrain(VSOutputDefault In, uniform int renderingMode,
  593. uniform bool hasShadow, uniform bool isTextureAtlasEnabled,
  594. float2 vPos : PIXELLOC ) : COLOR
  595. {
  596. // $note (WSK) : these are temporarily methods (hopefully) to pass the right parameters in since RNAFxCompiler doesn't seem to recognize
  597. // the uniform arguments specified in technique
  598. return PS_Default_PS3(In, RenderingMode_TerrainTile, SAMPLER(BaseSamplerWrapped), SAMPLER(NormalSamplerWrapped), true, true, vPos);
  599. }
  600. float4 PS_Default_PS3_Road(VSOutputDefault In, uniform int renderingMode,
  601. uniform bool hasShadow, uniform bool isTextureAtlasEnabled,
  602. float2 vPos : PIXELLOC ) : COLOR
  603. {
  604. // $note (WSK) : these are temporarily methods (hopefully) to pass the right parameters in since RNAFxCompiler doesn't seem to recognize
  605. // the uniform arguments specified in technique
  606. return PS_Default_PS3(In, RenderingMode_Road, SAMPLER(BaseSamplerWrapped), SAMPLER(NormalSamplerWrapped), true, true, vPos);
  607. }
  608. float4 PS_Default_PS3_Scorch(VSOutputDefault In, uniform int renderingMode,
  609. uniform bool hasShadow, uniform bool isTextureAtlasEnabled,
  610. float2 vPos : PIXELLOC ) : COLOR
  611. {
  612. // $note (WSK) : these are temporarily methods (hopefully) to pass the right parameters in since RNAFxCompiler doesn't seem to recognize
  613. // the uniform arguments specified in technique
  614. return PS_Default_PS3(In, RenderingMode_Scorch, SAMPLER(BaseSamplerClamped), SAMPLER(NormalSamplerClamped), true, true, vPos);
  615. }
  616. float4 PS_Default_PS3_Cliff(VSOutputDefault In, uniform int renderingMode,
  617. uniform bool hasShadow, uniform bool isTextureAtlasEnabled,
  618. float2 vPos : PIXELLOC ) : COLOR
  619. {
  620. // $note (WSK) : these are temporarily methods (hopefully) to pass the right parameters in since RNAFxCompiler doesn't seem to recognize
  621. // the uniform arguments specified in technique
  622. return PS_Default_PS3(In, RenderingMode_Cliff, SAMPLER(BaseSamplerWrapped), SAMPLER(NormalSamplerWrapped), true, true, vPos);
  623. }
  624. #else
  625. float4 PS_Default(VSOutputDefault In, uniform int renderingMode,
  626. uniform sampler2D baseSampler, uniform sampler2D normalSampler,
  627. uniform bool hasShadow, uniform bool isTextureAtlasEnabled,
  628. float2 vPos : PIXELLOC ) COLORTARGET
  629. {
  630. float2 BaseTexCoord = In.BaseTexCoord_BlendWeight.xy;
  631. float4 baseTextureValue = tex2D(baseSampler, BaseTexCoord);
  632. float2 CloudTexCoord = CalculateCloudTexCoord(Cloud, In.WorldPosition.xyz, Time);
  633. float2 MacroTexCoord = CalculateMacroTexCoord(In.WorldPosition.xyz);
  634. // Doing first and second blend
  635. float2 blendWeight = saturate(In.BaseTexCoord_BlendWeight.wz);
  636. if(renderingMode == RenderingMode_TerrainTile && isTextureAtlasEnabled)
  637. {
  638. float4 texColor1 = tex2D(baseSampler, In.BlendTex1Coord_BlendTex2Coord.xy);
  639. float4 texColor2 = tex2D(baseSampler, In.BlendTex1Coord_BlendTex2Coord.wz);
  640. baseTextureValue = lerp(lerp(baseTextureValue, texColor1, blendWeight[0]), texColor2, blendWeight[1]);
  641. }
  642. float3 baseColor = GammaToLinear(baseTextureValue.xyz);
  643. float3 color = In.Color.xyz;
  644. float opacity = In.Color.w;
  645. if (renderingMode == RenderingMode_Road || renderingMode == RenderingMode_Scorch)
  646. {
  647. opacity *= baseTextureValue.w;
  648. }
  649. // Add normal mapping lighting with main light source
  650. float3 normal;
  651. float specularIntensity;
  652. if (renderingMode == RenderingMode_Road || renderingMode == RenderingMode_Scorch)
  653. {
  654. float4 normal_specular = tex2D(normalSampler, BaseTexCoord);
  655. normal = normal_specular * 2 - 1;
  656. if (renderingMode == RenderingMode_Scorch)
  657. specularIntensity = 0;
  658. else
  659. specularIntensity = normal_specular.w;
  660. }
  661. else
  662. {
  663. float3 normal_specular = tex2D(normalSampler, BaseTexCoord);
  664. if(renderingMode == RenderingMode_TerrainTile && isTextureAtlasEnabled)
  665. {
  666. float3 normal_specular1 = tex2D(normalSampler, In.BlendTex1Coord_BlendTex2Coord.xy);
  667. float3 normal_specular2 = tex2D(normalSampler, In.BlendTex1Coord_BlendTex2Coord.wz);
  668. specularIntensity = baseTextureValue.w;
  669. normal = lerp(lerp(normal_specular, normal_specular1, blendWeight[0]), normal_specular2, blendWeight[1]) * 2 - 1;
  670. }
  671. else
  672. {
  673. specularIntensity = normal_specular.z;
  674. normal.xy = normal_specular.xy * 2 - 1;
  675. normal.z = sqrt(1 - normal.x * normal.x - normal.y * normal.y);
  676. }
  677. }
  678. normal.xy *= BumpScale;
  679. normal = normalize(normal);
  680. if (!EnableNormalMap)
  681. normal = float3(0, 0, 1);
  682. // Compute point lights
  683. #if !defined(EA_PLATFORM_PS3)
  684. for (int i = 0; i < NumPointLights; i++)
  685. {
  686. color += CalculatePointLightDiffuse(PointLight[i], In.WorldPosition, normal);
  687. }
  688. #endif
  689. // Apply texture color
  690. // Note: we need to divide by 2 in VS and restore it in PS since COLOR register is clamped to 1
  691. color *= HDRColorRange * baseColor;
  692. float3 mainLightColor = DirectionalLight[0].Color;
  693. float4 lighting = lit(dot(normal, In.MainLightDirection_Falloff.xyz), dot(normal, In.MainHalfEyeLightDirection), SpecularExponent);
  694. if (hasShadow)
  695. {
  696. if(renderingMode == RenderingMode_Road || renderingMode == RenderingMode_TerrainTile && !isTextureAtlasEnabled)
  697. {
  698. lighting.yz *= shadow_PerspectiveCorrect( SAMPLER(ShadowMap), In.ShadowMapTexCoord );
  699. }
  700. else
  701. {
  702. lighting.yz *= shadow( SAMPLER(ShadowMap), In.ShadowMapTexCoord );
  703. }
  704. }
  705. float3 cloud = GammaToLinear(tex2D( SAMPLER(CloudSampler), CloudTexCoord));
  706. color += mainLightColor * cloud * (lighting.y * baseColor + lighting.z * SpecularColor * specularIntensity);
  707. #if SUPPORT_SSAO
  708. color *= ComputeSSAO(vPos);
  709. #endif
  710. // Apply macro
  711. float3 macro = GammaToLinear(tex2D( SAMPLER(MacroSampler), MacroTexCoord));
  712. color *= macro;
  713. // Apply fog
  714. color = lerp(Fog.Color, color, In.Fog);
  715. // Apply shroud
  716. float2 shroudTexCoord = In.ShroudTexCoord;
  717. float shroud = tex2D( SAMPLER(ShroudSampler), shroudTexCoord).x;
  718. color *= shroud;
  719. return float4(color, opacity);
  720. }
  721. float4 PS_Default_Xenon(VSOutputDefault In, uniform int renderingMode,
  722. uniform sampler2D baseSampler, uniform sampler2D normalSampler, float2 vPos : PIXELLOC ) : COLOR
  723. {
  724. return PS_Default(In, renderingMode, baseSampler, normalSampler, 1, true, vPos);
  725. }
  726. #endif // EA_PLATFORM_WINDOWS || EA_PLATFORM_XENON
  727. // ---------------------------------------------------------------------------
  728. // TECHNIQUE : TerrainTile ( HIGH QUALITY )
  729. // ---------------------------------------------------------------------------
  730. DEFINE_ARRAY_MULTIPLIER(VS_TerrainTile_Multiplier_IsTextureAtlasEnabled = 1);
  731. #define VS_TerrainTile_IsTextureAtlasEnabled \
  732. compile VS_3_0 VS_TerrainTile(false), \
  733. compile VS_3_0 VS_TerrainTile(true)
  734. DEFINE_ARRAY_MULTIPLIER(VS_TerrainTile_Multiplier_Final = VS_TerrainTile_Multiplier_IsTextureAtlasEnabled * 2);
  735. #if SUPPORTS_SHADER_ARRAYS
  736. vertexshader VS_TerrainTile_Array[VS_TerrainTile_Multiplier_Final] =
  737. {
  738. VS_TerrainTile_IsTextureAtlasEnabled
  739. };
  740. #endif
  741. DEFINE_ARRAY_MULTIPLIER(PS_TerrainTile_Multiplier_NumShadows = 1);
  742. #define PS_TerrainTile_NumShadows(isTextureAtlasEnabled) \
  743. compile PS_3_0 PS_Default(RenderingMode_TerrainTile, SAMPLER(BaseSamplerClamped), SAMPLER(NormalSamplerClamped), 0, isTextureAtlasEnabled), \
  744. compile PS_3_0 PS_Default(RenderingMode_TerrainTile, SAMPLER(BaseSamplerClamped), SAMPLER(NormalSamplerClamped), 1, isTextureAtlasEnabled)
  745. DEFINE_ARRAY_MULTIPLIER(PS_TerrainTile_Multiplier_IsTextureAtlasEnabled = PS_TerrainTile_Multiplier_NumShadows * 2);
  746. #define PS_TerrainTile_IsTextureAtlasEnabled \
  747. PS_TerrainTile_NumShadows(false), \
  748. PS_TerrainTile_NumShadows(true)
  749. DEFINE_ARRAY_MULTIPLIER(PS_TerrainTile_Multiplier_Final = PS_TerrainTile_Multiplier_IsTextureAtlasEnabled * 2);
  750. #if SUPPORTS_SHADER_ARRAYS
  751. pixelshader PS_TerrainTile_Array[PS_TerrainTile_Multiplier_Final] =
  752. {
  753. PS_TerrainTile_IsTextureAtlasEnabled
  754. };
  755. #endif
  756. // ---------------------------------------------------------------------------
  757. technique TerrainTile
  758. {
  759. pass P0
  760. {
  761. VertexShader = ARRAY_EXPRESSION_DIRECT_VS(VS_TerrainTile_Array,
  762. IsTerrainAtlasEnabled * VS_TerrainTile_Multiplier_IsTextureAtlasEnabled,
  763. // Non-array alternative:
  764. #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  765. compile VS_VERSION VS_TerrainTileVFetch(true)
  766. #else
  767. compile VS_VERSION VS_TerrainTile(true)
  768. #endif
  769. );
  770. #if defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XENON)
  771. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_TerrainTile_Array,
  772. HasShadow * PS_TerrainTile_Multiplier_NumShadows
  773. + IsTerrainAtlasEnabled * PS_TerrainTile_Multiplier_IsTextureAtlasEnabled,
  774. // Non-array alternative:
  775. compile PS_VERSION PS_Default_Xenon(RenderingMode_TerrainTile, SAMPLER(BaseSamplerClamped), SAMPLER(NormalSamplerClamped))
  776. );
  777. #else // EA_PLATFORM_PS3
  778. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_TerrainTile_Array,
  779. HasShadow * PS_TerrainTile_Multiplier_NumShadows
  780. + IsTerrainAtlasEnabled * PS_TerrainTile_Multiplier_IsTextureAtlasEnabled,
  781. // Non-array alternative:
  782. compile PS_VERSION PS_Default_PS3_Terrain()
  783. );
  784. #endif
  785. ZEnable = true;
  786. ZWriteEnable = true;
  787. ZFunc = ZFUNC_INFRONT;
  788. CullMode = CW;
  789. AlphaBlendEnable = false;
  790. AlphaTestEnable = false;
  791. }
  792. }
  793. // ---------------------------------------------------------------------------
  794. // TECHNIQUE : Cliff ( HIGH QUALITY )
  795. // ---------------------------------------------------------------------------
  796. DEFINE_ARRAY_MULTIPLIER(PS_Cliff_Multiplier_NumShadows = 1);
  797. #define PS_Cliff_NumShadows \
  798. compile PS_3_0 PS_Default(RenderingMode_Cliff, SAMPLER(BaseSamplerWrapped), SAMPLER(NormalSamplerWrapped), 0, false), \
  799. compile PS_3_0 PS_Default(RenderingMode_Cliff, SAMPLER(BaseSamplerWrapped), SAMPLER(NormalSamplerWrapped), 1, false)
  800. DEFINE_ARRAY_MULTIPLIER(PS_Cliff_Multiplier_Final = PS_Cliff_Multiplier_NumShadows * 2);
  801. #if SUPPORTS_SHADER_ARRAYS
  802. pixelshader PS_Cliff_Array[PS_Cliff_Multiplier_Final] =
  803. {
  804. PS_Cliff_NumShadows
  805. };
  806. #endif
  807. // ---------------------------------------------------------------------------
  808. technique Cliff
  809. {
  810. pass P0
  811. {
  812. VertexShader = compile VS_3_0 VS_Default(RenderingMode_Cliff, false);
  813. #if defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XENON)
  814. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_Cliff_Array,
  815. HasShadow * PS_Cliff_Multiplier_NumShadows,
  816. // Non-array alternative:
  817. compile PS_VERSION PS_Default_Xenon(RenderingMode_Cliff, SAMPLER(BaseSamplerWrapped), SAMPLER(NormalSamplerWrapped))
  818. );
  819. #else
  820. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_Cliff_Array,
  821. HasShadow * PS_Cliff_Multiplier_NumShadows,
  822. // Non-array alternative:
  823. compile PS_VERSION PS_Default_PS3_Cliff()
  824. );
  825. #endif
  826. ZEnable = true;
  827. ZWriteEnable = false;
  828. ZFunc = ZFUNC_INFRONT;
  829. CullMode = CW;
  830. AlphaBlendEnable = true;
  831. SrcBlend = SrcAlpha;
  832. DestBlend = InvSrcAlpha;
  833. AlphaTestEnable = false;
  834. }
  835. }
  836. // ---------------------------------------------------------------------------
  837. // TECHNIQUE : Road ( HIGH QUALITY )
  838. // ---------------------------------------------------------------------------
  839. DEFINE_ARRAY_MULTIPLIER(PS_Road_Multiplier_NumShadows = 1);
  840. #define PS_Road_NumShadows \
  841. compile PS_3_0 PS_Default(RenderingMode_Road, SAMPLER(BaseSamplerWrapped), SAMPLER(NormalSamplerWrapped), 0, false), \
  842. compile PS_3_0 PS_Default(RenderingMode_Road, SAMPLER(BaseSamplerWrapped), SAMPLER(NormalSamplerWrapped), 1, false)
  843. DEFINE_ARRAY_MULTIPLIER(PS_Road_Multiplier_Final = PS_Road_Multiplier_NumShadows * 2);
  844. #if SUPPORTS_SHADER_ARRAYS
  845. pixelshader PS_Road_Array[PS_Road_Multiplier_Final] =
  846. {
  847. PS_Road_NumShadows
  848. };
  849. #endif
  850. // ---------------------------------------------------------------------------
  851. technique Road
  852. {
  853. pass P0
  854. {
  855. VertexShader = compile VS_3_0 VS_Default(RenderingMode_Road, false);
  856. #if defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XENON)
  857. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_Road_Array,
  858. HasShadow * PS_Road_Multiplier_NumShadows,
  859. // Non-array alternative:
  860. compile PS_VERSION PS_Default_Xenon(RenderingMode_Road, SAMPLER(BaseSamplerWrapped), SAMPLER(NormalSamplerWrapped))
  861. );
  862. #else
  863. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_Road_Array,
  864. HasShadow * PS_Road_Multiplier_NumShadows,
  865. // Non-array alternative:
  866. compile PS_VERSION PS_Default_PS3_Road()
  867. );
  868. #endif
  869. ZEnable = true;
  870. ZWriteEnable = false;
  871. ZFunc = ZFUNC_INFRONT;
  872. CullMode = CW;
  873. AlphaBlendEnable = true;
  874. SrcBlend = SrcAlpha;
  875. DestBlend = InvSrcAlpha;
  876. AlphaTestEnable = false;
  877. DepthBias = ROAD_Z_BIAS;
  878. }
  879. }
  880. // ---------------------------------------------------------------------------
  881. // TECHNIQUE : Scorch ( HIGH QUALITY )
  882. // ---------------------------------------------------------------------------
  883. DEFINE_ARRAY_MULTIPLIER(PS_Scorch_Multiplier_NumShadows = 1);
  884. #define PS_Scorch_NumShadows \
  885. compile PS_3_0 PS_Default(RenderingMode_Scorch, SAMPLER(BaseSamplerClamped), SAMPLER(NormalSamplerClamped), 0, false), \
  886. compile PS_3_0 PS_Default(RenderingMode_Scorch, SAMPLER(BaseSamplerClamped), SAMPLER(NormalSamplerClamped), 1, false)
  887. DEFINE_ARRAY_MULTIPLIER(PS_Scorch_Multiplier_Final = PS_Scorch_Multiplier_NumShadows * 2);
  888. #if SUPPORTS_SHADER_ARRAYS
  889. pixelshader PS_Scorch_Array[PS_Scorch_Multiplier_Final] =
  890. {
  891. PS_Scorch_NumShadows
  892. };
  893. #endif
  894. // ---------------------------------------------------------------------------
  895. technique Scorch
  896. {
  897. pass P0
  898. {
  899. VertexShader = compile VS_3_0 VS_TerrainScorch();
  900. #if defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XENON)
  901. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_Scorch_Array,
  902. HasShadow * PS_Scorch_Multiplier_NumShadows,
  903. // Non-array alternative:
  904. compile PS_VERSION PS_Default_Xenon(RenderingMode_Scorch, SAMPLER(BaseSamplerClamped), SAMPLER(NormalSamplerClamped))
  905. );
  906. #else
  907. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_Scorch_Array,
  908. HasShadow * PS_Scorch_Multiplier_NumShadows,
  909. // Non-array alternative:
  910. compile PS_VERSION PS_Default_PS3_Scorch()
  911. );
  912. #endif
  913. ZEnable = true;
  914. ZWriteEnable = false;
  915. ZFunc = ZFUNC_INFRONT;
  916. CullMode = CW;
  917. AlphaBlendEnable = true;
  918. SrcBlend = SrcAlpha;
  919. DestBlend = InvSrcAlpha;
  920. AlphaTestEnable = false;
  921. DepthBias = SCORCHMARK_Z_BIAS;
  922. }
  923. }
  924. // LOD techniques follow
  925. #if ENABLE_LOD
  926. // ============================================================================
  927. // Default technique, medium quality
  928. // ============================================================================
  929. // ---------------------------------------------------------------------------
  930. struct VSOutput_M
  931. {
  932. float4 Position : POSITION;
  933. float4 Color : COLOR0;
  934. float4 MainLightContribution_Fog : COLOR1;
  935. float4 BaseTexCoord_BlendWeight : TEXCOORD0;
  936. float4 BlendTex1Coord_BlendTex2Coord : TEXCOORD1;
  937. float2 ShroudTexCoord : TEXCOORD2;
  938. float4 CloudTexCoord_MacroTexCoord : TEXCOORD3;
  939. float4 ShadowMapTexCoord : TEXCOORD5;
  940. };
  941. // ---------------------------------------------------------------------------
  942. VSOutput_M VS_Default_M(
  943. float3 Position : POSITION,
  944. float3 Normal : NORMAL,
  945. float4 Color : COLOR0,
  946. float2 BaseTexCoord : TEXCOORD0,
  947. uniform int renderingMode,
  948. uniform bool isTextureAtlasEnabled
  949. )
  950. {
  951. VSOutput_M Out;
  952. Out.Position = mul(float4(Position, 1), GetViewProjection());
  953. float3 worldPosition = Position;
  954. Out.MainLightContribution_Fog.w = CalculateFog(Fog, worldPosition, GetEyePosition());
  955. float3 worldNormal = Normal;
  956. float3 mainLight = DirectionalLight[0].Color * max(0, dot(worldNormal, DirectionalLight[0].Direction));
  957. mainLight /= 2; // Overbright rendering is already applied in the light color, however we want to do it later in the pixel shader.
  958. Out.MainLightContribution_Fog.xyz = mainLight;
  959. // Do vertex lighting for light 1 to n
  960. float3 diffuseLight = 0;
  961. for (int i = 1; i < NumDirectionalLights; i++)
  962. {
  963. diffuseLight += DirectionalLight[i].Color * max(0, dot(worldNormal, DirectionalLight[i].Direction));
  964. }
  965. float3 diffuseColor = (AmbientLightColor + diffuseLight) * Color.xyz;
  966. diffuseColor /= HDRColorRange; // Overbright rendering is already applied in the light color, however we want to do it later in the pixel shader.
  967. Out.Color = float4(diffuseColor, Color.w);
  968. // Output texture information
  969. Out.BaseTexCoord_BlendWeight.xy = BaseTexCoord;
  970. // Initialize terrain tile only data
  971. Out.BaseTexCoord_BlendWeight.zw = float2(0, 0);
  972. Out.BlendTex1Coord_BlendTex2Coord = float4(0, 0, 0, 0);
  973. float2 ShroudTexCoord = CalculateShroudTexCoord(Shroud, worldPosition);
  974. float2 CloudTexCoord = CalculateCloudTexCoord(Cloud, worldPosition, Time);
  975. float2 MacroTexCoord = CalculateMacroTexCoord(worldPosition);
  976. Out.ShroudTexCoord = ShroudTexCoord;
  977. Out.CloudTexCoord_MacroTexCoord.xy = CloudTexCoord.xy;
  978. Out.CloudTexCoord_MacroTexCoord.zw = MacroTexCoord.yx;
  979. if(renderingMode == RenderingMode_Road || renderingMode == RenderingMode_TerrainTile && !isTextureAtlasEnabled)
  980. {
  981. Out.ShadowMapTexCoord = CalculateShadowMapTexCoord_PerspectiveCorrect(worldPosition);
  982. }
  983. else
  984. {
  985. Out.ShadowMapTexCoord = CalculateShadowMapTexCoord(worldPosition);
  986. }
  987. return Out;
  988. }
  989. // ---------------------------------------------------------------------------
  990. VSOutput_M VS_TerrainTile_M(
  991. float4 Position_BlendWeight1 : POSITION,
  992. float4 Normal_BlendWeight2 : NORMAL0,
  993. float2 BaseTexCoord : TEXCOORD0,
  994. float2 BlendTex1Coord : TEXCOORD1,
  995. float2 BlendTex2Coord : TEXCOORD2,
  996. uniform bool isTextureAtlasEnabled
  997. )
  998. {
  999. VSOutput_M Out;
  1000. float3 Position = Position_BlendWeight1.xyz;
  1001. float3 Normal = Normal_BlendWeight2.xyz;
  1002. float BlendWeight1 = 0.0;
  1003. float BlendWeight2 = 0.0;
  1004. if (isTextureAtlasEnabled)
  1005. {
  1006. // Unpack vertex data
  1007. Normal = (Normal_BlendWeight2.xyz / 100.0) - 1.0;
  1008. BaseTexCoord = (BaseTexCoord / 30000.0);
  1009. BlendTex1Coord = (BlendTex1Coord / 30000.0);
  1010. BlendTex2Coord = (BlendTex2Coord / 30000.0);
  1011. BlendWeight1 = Position_BlendWeight1.w - 1.0;
  1012. BlendWeight2 = Normal_BlendWeight2.w - 1.0;
  1013. }
  1014. // Delegate main computations to VS_Default
  1015. Out = VS_Default_M(Position, Normal, float4(1.0, 1.0, 1.0, 1.0), BaseTexCoord, RenderingMode_TerrainTile, isTextureAtlasEnabled);
  1016. if (isTextureAtlasEnabled)
  1017. {
  1018. // Note: intentionally switch 1 and 2
  1019. Out.BaseTexCoord_BlendWeight.z = BlendWeight2;
  1020. Out.BaseTexCoord_BlendWeight.w = BlendWeight1;
  1021. Out.BlendTex1Coord_BlendTex2Coord.xy = BlendTex1Coord.xy;
  1022. Out.BlendTex1Coord_BlendTex2Coord.zw = BlendTex2Coord.yx;
  1023. }
  1024. return Out;
  1025. }
  1026. // ---------------------------------------------------------------------------
  1027. VSOutput_M VS_TerrainScorch_M(
  1028. float4 Position_BlendWeight1 : POSITION,
  1029. float4 Normal_unpack : NORMAL0,
  1030. float4 Color : COLOR0,
  1031. float2 BaseTexCoord : TEXCOORD0
  1032. )
  1033. {
  1034. VSOutputDefault Out;
  1035. float3 Position = Position_BlendWeight1.xyz;
  1036. // Unpack vertex data
  1037. float3 Normal = (Normal_unpack.xyz * 255 / 100.0) - 1.0;
  1038. BaseTexCoord = (BaseTexCoord / 30000.0);
  1039. // Delegate main computations to DefaultVertexShader_M
  1040. return VS_Default_M(Position, Normal, Color, BaseTexCoord, RenderingMode_Scorch, false);
  1041. }
  1042. // ---------------------------------------------------------------------------
  1043. float4 PS_Default_M(VSOutput_M In, uniform int renderingMode,
  1044. uniform sampler2D baseSampler, uniform bool hasShadow,
  1045. uniform bool isTextureAtlasEnabled) : COLOR
  1046. {
  1047. float2 BaseTexCoord = In.BaseTexCoord_BlendWeight.xy;
  1048. float4 baseTextureValue = tex2D(baseSampler, BaseTexCoord);
  1049. // Doing first and second blend
  1050. float2 blendWeight = saturate(In.BaseTexCoord_BlendWeight.wz);
  1051. if(renderingMode == RenderingMode_TerrainTile && isTextureAtlasEnabled)
  1052. {
  1053. float4 texColor1 = tex2D(baseSampler, In.BlendTex1Coord_BlendTex2Coord.xy);
  1054. float4 texColor2 = tex2D(baseSampler, In.BlendTex1Coord_BlendTex2Coord.wz);
  1055. baseTextureValue = lerp(lerp(baseTextureValue, texColor1, blendWeight[0]), texColor2, blendWeight[1]);
  1056. }
  1057. float3 baseColor = baseTextureValue.xyz;
  1058. float2 CloudTexCoord = In.CloudTexCoord_MacroTexCoord.xy;
  1059. float3 cloud = GammaToLinear(tex2D(SAMPLER(CloudSampler), CloudTexCoord));
  1060. float3 mainLight = In.MainLightContribution_Fog.xyz * cloud;
  1061. if (hasShadow)
  1062. {
  1063. if(renderingMode == RenderingMode_Road || renderingMode == RenderingMode_TerrainTile && !isTextureAtlasEnabled)
  1064. {
  1065. mainLight *= shadow_PerspectiveCorrect( SAMPLER(ShadowMap), In.ShadowMapTexCoord );
  1066. }
  1067. else
  1068. {
  1069. mainLight *= shadow( SAMPLER(ShadowMap), In.ShadowMapTexCoord );
  1070. }
  1071. }
  1072. float3 color = (In.Color.xyz + mainLight) * baseColor;
  1073. color *= 2; // Overbrightening
  1074. // Apply reflection or macro
  1075. float2 MacroTexCoord = In.CloudTexCoord_MacroTexCoord.wz;
  1076. float4 macro = tex2D( SAMPLER(MacroSampler), MacroTexCoord);
  1077. // Apply macro
  1078. color *= macro;
  1079. // Apply fog
  1080. color = lerp(Fog.Color, color, In.MainLightContribution_Fog.w);
  1081. // Apply shroud
  1082. float2 shroudTexCoord = In.ShroudTexCoord;
  1083. float shroud = tex2D( SAMPLER(ShroudSampler), shroudTexCoord).x;
  1084. color *= shroud;
  1085. // Calculate opacity
  1086. float opacity = In.Color.w;
  1087. if (renderingMode == RenderingMode_Road || renderingMode == RenderingMode_Scorch)
  1088. {
  1089. opacity *= baseTextureValue.w;
  1090. }
  1091. return float4(color, opacity);
  1092. }
  1093. // ---------------------------------------------------------------------------
  1094. // TECHNIQUE : Terrain Tile (Medium Quality)
  1095. // ---------------------------------------------------------------------------
  1096. DEFINE_ARRAY_MULTIPLIER(VS_TerrainTile_M_Multiplier_IsTextureAtlasEnabled = 1);
  1097. #define VS_TerrainTile_M_IsTextureAtlasEnabled \
  1098. compile VS_2_0 VS_TerrainTile_M(false), \
  1099. compile VS_2_0 VS_TerrainTile_M(true)
  1100. DEFINE_ARRAY_MULTIPLIER(VS_TerrainTile_M_Multiplier_Final = VS_TerrainTile_M_Multiplier_IsTextureAtlasEnabled * 2);
  1101. #if SUPPORTS_SHADER_ARRAYS
  1102. vertexshader VS_TerrainTile_M_Array[VS_TerrainTile_M_Multiplier_Final] =
  1103. {
  1104. VS_TerrainTile_M_IsTextureAtlasEnabled
  1105. };
  1106. #endif
  1107. DEFINE_ARRAY_MULTIPLIER(PS_TerrainTile_M_Multiplier_NumShadows = 1);
  1108. #define PS_TerrainTile_M_NumShadows(isTextureAtlasEnabled) \
  1109. compile PS_2_0 PS_Default_M(RenderingMode_TerrainTile, SAMPLER(BaseSamplerClamped), 0, isTextureAtlasEnabled), \
  1110. compile PS_2_0 PS_Default_M(RenderingMode_TerrainTile, SAMPLER(BaseSamplerClamped), 1, isTextureAtlasEnabled)
  1111. DEFINE_ARRAY_MULTIPLIER(PS_TerrainTile_M_Multiplier_IsTextureAtlasEnabled = PS_TerrainTile_M_Multiplier_NumShadows * 2);
  1112. #define PS_TerrainTile_M_IsTextureAtlasEnabled \
  1113. PS_TerrainTile_M_NumShadows(false), \
  1114. PS_TerrainTile_M_NumShadows(true)
  1115. DEFINE_ARRAY_MULTIPLIER(PS_TerrainTile_M_Multiplier_Final = PS_TerrainTile_M_Multiplier_IsTextureAtlasEnabled * 2);
  1116. #if SUPPORTS_SHADER_ARRAYS
  1117. pixelshader PS_TerrainTile_M_Array[PS_TerrainTile_M_Multiplier_Final] =
  1118. {
  1119. PS_TerrainTile_M_IsTextureAtlasEnabled
  1120. };
  1121. #endif
  1122. technique TerrainTile_M
  1123. {
  1124. pass P0
  1125. {
  1126. VertexShader = ARRAY_EXPRESSION_DIRECT_VS(VS_TerrainTile_M_Array,
  1127. IsTerrainAtlasEnabled * VS_TerrainTile_M_Multiplier_IsTextureAtlasEnabled,
  1128. NO_ARRAY_ALTERNATIVE
  1129. );
  1130. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_TerrainTile_M_Array,
  1131. HasShadow * PS_TerrainTile_M_Multiplier_NumShadows
  1132. + IsTerrainAtlasEnabled * PS_TerrainTile_M_Multiplier_IsTextureAtlasEnabled,
  1133. NO_ARRAY_ALTERNATIVE
  1134. );
  1135. ZEnable = true;
  1136. ZWriteEnable = true;
  1137. ZFunc = ZFUNC_INFRONT;
  1138. CullMode = CW;
  1139. AlphaBlendEnable = false;
  1140. AlphaTestEnable = false;
  1141. }
  1142. }
  1143. // ---------------------------------------------------------------------------
  1144. // TECHNIQUE : Cliff (Medium Quality)
  1145. // ---------------------------------------------------------------------------
  1146. DEFINE_ARRAY_MULTIPLIER(PS_Cliff_M_Multiplier_NumShadows = 1);
  1147. #define PS_Cliff_M_NumShadows \
  1148. compile PS_2_0 PS_Default_M(RenderingMode_Cliff, SAMPLER(BaseSamplerWrapped), 0, false), \
  1149. compile PS_2_0 PS_Default_M(RenderingMode_Cliff, SAMPLER(BaseSamplerWrapped), 1, false)
  1150. DEFINE_ARRAY_MULTIPLIER(PS_Cliff_M_Multiplier_Final = PS_Cliff_M_Multiplier_NumShadows * 2);
  1151. #if SUPPORTS_SHADER_ARRAYS
  1152. pixelshader PS_Cliff_M_Array[PS_Cliff_M_Multiplier_Final] =
  1153. {
  1154. PS_Cliff_M_NumShadows
  1155. };
  1156. #endif
  1157. technique Cliff_M
  1158. {
  1159. pass P0
  1160. {
  1161. VertexShader = compile VS_2_0 VS_Default_M(RenderingMode_Cliff, false);
  1162. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_Cliff_M_Array,
  1163. HasShadow * PS_Cliff_M_Multiplier_NumShadows,
  1164. NO_ARRAY_ALTERNATIVE
  1165. );
  1166. ZEnable = true;
  1167. ZWriteEnable = false;
  1168. ZFunc = ZFUNC_INFRONT;
  1169. CullMode = CW;
  1170. AlphaBlendEnable = true;
  1171. SrcBlend = SrcAlpha;
  1172. DestBlend = InvSrcAlpha;
  1173. AlphaTestEnable = false;
  1174. }
  1175. }
  1176. // ---------------------------------------------------------------------------
  1177. // TECHNIQUE : Road (Medium Quality)
  1178. // ---------------------------------------------------------------------------
  1179. DEFINE_ARRAY_MULTIPLIER(PS_Road_M_Multiplier_NumShadows = 1);
  1180. #define PS_Road_M_NumShadows \
  1181. compile PS_2_0 PS_Default_M(RenderingMode_Road, SAMPLER(BaseSamplerWrapped), 0, false), \
  1182. compile PS_2_0 PS_Default_M(RenderingMode_Road, SAMPLER(BaseSamplerWrapped), 1, false)
  1183. DEFINE_ARRAY_MULTIPLIER(PS_Road_M_Multiplier_Final = PS_Road_M_Multiplier_NumShadows * 2);
  1184. #if SUPPORTS_SHADER_ARRAYS
  1185. pixelshader PS_Road_M_Array[PS_Road_M_Multiplier_Final] =
  1186. {
  1187. PS_Road_M_NumShadows
  1188. };
  1189. #endif
  1190. technique Road_M
  1191. {
  1192. pass P0
  1193. {
  1194. VertexShader = compile VS_2_0 VS_Default_M(RenderingMode_Road, false);
  1195. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_Road_M_Array,
  1196. HasShadow * PS_Road_M_Multiplier_NumShadows,
  1197. NO_ARRAY_ALTERNATIVE
  1198. );
  1199. ZEnable = true;
  1200. ZWriteEnable = false;
  1201. ZFunc = ZFUNC_INFRONT;
  1202. CullMode = CW;
  1203. AlphaBlendEnable = true;
  1204. SrcBlend = SrcAlpha;
  1205. DestBlend = InvSrcAlpha;
  1206. AlphaTestEnable = false;
  1207. DepthBias = ROAD_Z_BIAS;
  1208. }
  1209. }
  1210. // ---------------------------------------------------------------------------
  1211. // TECHNIQUE : Scorch (Medium Quality)
  1212. // ---------------------------------------------------------------------------
  1213. DEFINE_ARRAY_MULTIPLIER(PS_Scorch_M_Multiplier_NumShadows = 1);
  1214. #define PS_Scorch_M_NumShadows \
  1215. compile PS_2_0 PS_Default_M(RenderingMode_Scorch, SAMPLER(BaseSamplerClamped), 0, false), \
  1216. compile PS_2_0 PS_Default_M(RenderingMode_Scorch, SAMPLER(BaseSamplerClamped), 1, false)
  1217. DEFINE_ARRAY_MULTIPLIER(PS_Scorch_M_Multiplier_Final = PS_Scorch_M_Multiplier_NumShadows * 2);
  1218. #if SUPPORTS_SHADER_ARRAYS
  1219. pixelshader PS_Scorch_M_Array[PS_Scorch_M_Multiplier_Final] =
  1220. {
  1221. PS_Scorch_M_NumShadows
  1222. };
  1223. #endif
  1224. technique Scorch_M
  1225. {
  1226. pass P0
  1227. {
  1228. VertexShader = compile VS_2_0 VS_TerrainScorch_M();
  1229. PixelShader = ARRAY_EXPRESSION_DIRECT_PS(PS_Scorch_M_Array,
  1230. HasShadow * PS_Scorch_M_Multiplier_NumShadows,
  1231. NO_ARRAY_ALTERNATIVE
  1232. );
  1233. ZEnable = true;
  1234. ZWriteEnable = false;
  1235. ZFunc = ZFUNC_INFRONT;
  1236. CullMode = CW;
  1237. AlphaBlendEnable = true;
  1238. SrcBlend = SrcAlpha;
  1239. DestBlend = InvSrcAlpha;
  1240. AlphaTestEnable = false;
  1241. DepthBias = SCORCHMARK_Z_BIAS;
  1242. }
  1243. }
  1244. // ============================================================================
  1245. // Default technique, low quality
  1246. // ============================================================================
  1247. // ---------------------------------------------------------------------------
  1248. struct VSOutput_L
  1249. {
  1250. float4 Position : POSITION;
  1251. float4 BaseTexCoord_BlendWeight : TEXCOORD0;
  1252. float4 BlendTex1Coord_BlendTex2Coord : TEXCOORD1;
  1253. float2 ShroudTexCoord : TEXCOORD2;
  1254. float4 Color : TEXCOORD3;
  1255. };
  1256. // ---------------------------------------------------------------------------
  1257. VSOutput_L VS_Default_L(
  1258. float3 Position : POSITION,
  1259. float3 Normal : NORMAL,
  1260. float4 Color : COLOR0,
  1261. float2 BaseTexCoord : TEXCOORD0,
  1262. uniform int renderingMode,
  1263. uniform bool isTextureAtlasEnabled
  1264. )
  1265. {
  1266. VSOutput_L Out;
  1267. Out.Position = mul(float4(Position, 1), GetViewProjection());
  1268. float3 worldPosition = Position;
  1269. float3 worldNormal = Normal;
  1270. // Do vertex lighting for light 1 to n
  1271. float3 diffuseLight = 0;
  1272. for (int i = 0; i < NumDirectionalLights; i++)
  1273. {
  1274. diffuseLight += DirectionalLight[i].Color * max(0, dot(worldNormal, DirectionalLight[i].Direction));
  1275. }
  1276. float3 diffuseColor = (AmbientLightColor + diffuseLight) * Color.xyz;
  1277. Out.Color = float4(diffuseColor, Color.w);
  1278. // Output texture information
  1279. Out.BaseTexCoord_BlendWeight.xy = BaseTexCoord;
  1280. // Initialize terrain tile only data
  1281. Out.BaseTexCoord_BlendWeight.zw = float2(0, 0);
  1282. Out.BlendTex1Coord_BlendTex2Coord = float4(0, 0, 0, 0);
  1283. float2 ShroudTexCoord = CalculateShroudTexCoord(Shroud, worldPosition);
  1284. Out.ShroudTexCoord = ShroudTexCoord;
  1285. return Out;
  1286. }
  1287. // ---------------------------------------------------------------------------
  1288. VSOutput_L VS_TerrainTile_L(
  1289. float4 Position_BlendWeight1 : POSITION,
  1290. float4 Normal_BlendWeight2 : NORMAL0,
  1291. float2 BaseTexCoord : TEXCOORD0,
  1292. float2 BlendTex1Coord : TEXCOORD1,
  1293. float2 BlendTex2Coord : TEXCOORD2,
  1294. uniform bool isTextureAtlasEnabled
  1295. )
  1296. {
  1297. VSOutput_L Out;
  1298. float3 Position = Position_BlendWeight1.xyz;
  1299. float3 Normal = Normal_BlendWeight2.xyz;
  1300. float BlendWeight1 = 0.0;
  1301. float BlendWeight2 = 0.0;
  1302. if (isTextureAtlasEnabled)
  1303. {
  1304. // Unpack vertex data
  1305. Normal = (Normal_BlendWeight2.xyz / 100.0) - 1.0;
  1306. BaseTexCoord = (BaseTexCoord / 30000.0);
  1307. BlendTex1Coord = (BlendTex1Coord / 30000.0);
  1308. BlendTex2Coord = (BlendTex2Coord / 30000.0);
  1309. BlendWeight1 = Position_BlendWeight1.w - 1.0;
  1310. BlendWeight2 = Normal_BlendWeight2.w - 1.0;
  1311. }
  1312. // Delegate main computations to VS_Default
  1313. Out = VS_Default_L(Position, Normal, float4(1.0, 1.0, 1.0, 1.0), BaseTexCoord, RenderingMode_TerrainTile, isTextureAtlasEnabled);
  1314. if (isTextureAtlasEnabled)
  1315. {
  1316. // Note: intentionally switch 1 and 2
  1317. Out.BaseTexCoord_BlendWeight.z = BlendWeight2;
  1318. Out.BaseTexCoord_BlendWeight.w = BlendWeight1;
  1319. Out.BlendTex1Coord_BlendTex2Coord.xy = BlendTex1Coord.xy;
  1320. Out.BlendTex1Coord_BlendTex2Coord.zw = BlendTex2Coord.yx;
  1321. }
  1322. return Out;
  1323. }
  1324. // ---------------------------------------------------------------------------
  1325. VSOutput_L VS_TerrainScorch_L(
  1326. float4 Position_BlendWeight1 : POSITION,
  1327. float4 Normal_unpack : NORMAL0,
  1328. float4 Color : COLOR0,
  1329. float2 BaseTexCoord : TEXCOORD0
  1330. )
  1331. {
  1332. VSOutputDefault Out;
  1333. float3 Position = Position_BlendWeight1.xyz;
  1334. // Unpack vertex data
  1335. float3 Normal = (Normal_unpack.xyz * 255 / 100.0) - 1.0;
  1336. BaseTexCoord = (BaseTexCoord / 30000.0);
  1337. // Delegate main computations to DefaultVertexShader_L
  1338. return VS_Default_L(Position, Normal, Color, BaseTexCoord, RenderingMode_Scorch, false);
  1339. }
  1340. // ---------------------------------------------------------------------------
  1341. float4 PS_Default_L(VSOutput_L In, uniform int renderingMode,
  1342. uniform sampler2D baseSampler, uniform bool isTextureAtlasEnabled) : COLOR
  1343. {
  1344. float2 BaseTexCoord = In.BaseTexCoord_BlendWeight.xy;
  1345. float4 baseTextureValue = tex2D(baseSampler, BaseTexCoord);
  1346. if(renderingMode == RenderingMode_TerrainTile && isTextureAtlasEnabled)
  1347. {
  1348. float4 texColor1 = tex2D(baseSampler, In.BlendTex1Coord_BlendTex2Coord.xy);
  1349. float4 texColor2 = tex2D(baseSampler, In.BlendTex1Coord_BlendTex2Coord.wz);
  1350. // Doing first and second blend
  1351. float2 blendWeight = saturate(In.BaseTexCoord_BlendWeight.wz);
  1352. // This double lerp is expensive on low lod.
  1353. baseTextureValue = lerp(lerp(baseTextureValue, texColor1, blendWeight[0]), texColor2, blendWeight[1]);
  1354. }
  1355. float4 color = In.Color;
  1356. if (renderingMode == RenderingMode_Road || renderingMode == RenderingMode_Scorch)
  1357. {
  1358. color *= baseTextureValue;
  1359. }
  1360. else
  1361. {
  1362. color.xyz *= baseTextureValue.xyz;
  1363. }
  1364. // Apply shroud
  1365. float2 shroudTexCoord = In.ShroudTexCoord;
  1366. float shroud = tex2D( SAMPLER(ShroudSampler), shroudTexCoord).x;
  1367. color.xyz *= shroud;
  1368. return color;
  1369. }
  1370. // ---------------------------------------------------------------------------
  1371. // TECHNIQUE : Terrain Tile (Low Quality)
  1372. // ---------------------------------------------------------------------------
  1373. technique TerrainTile_L
  1374. {
  1375. pass P0
  1376. {
  1377. VertexShader = compile VS_2_0 VS_TerrainTile_L(true);
  1378. PixelShader = compile PS_2_0 PS_Default_L(RenderingMode_TerrainTile, SAMPLER(BaseSamplerClamped_L), true);
  1379. ZEnable = true;
  1380. ZWriteEnable = true;
  1381. ZFunc = ZFUNC_INFRONT;
  1382. CullMode = CW;
  1383. AlphaBlendEnable = false;
  1384. AlphaTestEnable = false;
  1385. }
  1386. }
  1387. // ---------------------------------------------------------------------------
  1388. // TECHNIQUE : Cliff (Low Quality)
  1389. // ---------------------------------------------------------------------------
  1390. technique Cliff_L
  1391. {
  1392. pass P0
  1393. {
  1394. VertexShader = compile VS_2_0 VS_Default_L(RenderingMode_Cliff, false);
  1395. PixelShader = compile PS_2_0 PS_Default_L(RenderingMode_Cliff, SAMPLER(BaseSamplerWrapped_L), false);
  1396. ZEnable = true;
  1397. ZWriteEnable = false;
  1398. ZFunc = ZFUNC_INFRONT;
  1399. CullMode = CW;
  1400. AlphaBlendEnable = true;
  1401. SrcBlend = SrcAlpha;
  1402. DestBlend = InvSrcAlpha;
  1403. AlphaTestEnable = false;
  1404. }
  1405. }
  1406. // ---------------------------------------------------------------------------
  1407. // TECHNIQUE : Road (Low Quality)
  1408. // ---------------------------------------------------------------------------
  1409. technique Road_L
  1410. {
  1411. pass P0
  1412. {
  1413. VertexShader = compile VS_2_0 VS_Default_L(RenderingMode_Road, false);
  1414. PixelShader = compile PS_2_0 PS_Default_L(RenderingMode_Road, SAMPLER(BaseSamplerWrapped_L), false);
  1415. ZEnable = true;
  1416. ZWriteEnable = false;
  1417. ZFunc = ZFUNC_INFRONT;
  1418. CullMode = CW;
  1419. AlphaBlendEnable = true;
  1420. SrcBlend = SrcAlpha;
  1421. DestBlend = InvSrcAlpha;
  1422. AlphaTestEnable = false;
  1423. DepthBias = ROAD_Z_BIAS;
  1424. }
  1425. }
  1426. // ---------------------------------------------------------------------------
  1427. // TECHNIQUE : Scorch (Low Quality)
  1428. // ---------------------------------------------------------------------------
  1429. technique Scorch_L
  1430. {
  1431. pass P0
  1432. {
  1433. VertexShader = compile VS_2_0 VS_TerrainScorch_L();
  1434. PixelShader = compile PS_2_0 PS_Default_L(RenderingMode_Scorch, SAMPLER(BaseSamplerClamped_L), false);
  1435. ZEnable = true;
  1436. ZWriteEnable = false;
  1437. ZFunc = ZFUNC_INFRONT;
  1438. CullMode = CW;
  1439. AlphaBlendEnable = true;
  1440. SrcBlend = SrcAlpha;
  1441. DestBlend = InvSrcAlpha;
  1442. AlphaTestEnable = false;
  1443. DepthBias = SCORCHMARK_Z_BIAS;
  1444. }
  1445. }
  1446. #endif // #if ENABLE_LOD
  1447. // ---------------------------------------------------------------------------
  1448. // ---------------------------------------------------------------------------
  1449. struct VSOutput_CreateShadowMap
  1450. {
  1451. float4 Position : POSITION;
  1452. float Depth : TEXCOORD0;
  1453. };
  1454. // ---------------------------------------------------------------------------
  1455. VSOutput_CreateShadowMap VS_CreateShadowMap(float3 Position : POSITION)
  1456. {
  1457. VSOutput_CreateShadowMap Out;
  1458. Out.Position = mul(float4(Position, 1), GetViewProjection());
  1459. Out.Depth = Out.Position.z / Out.Position.w;
  1460. return Out;
  1461. }
  1462. #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  1463. // ---------------------------------------------------------------------------
  1464. VSOutput_CreateShadowMap VS_CreateShadowMapVFetch(int Index: INDEX)
  1465. {
  1466. VSOutput_CreateShadowMap Out;
  1467. // Fetch the vertex info from Terrain
  1468. VSOutputDefault TerrainVertex = VS_TerrainTileVFetch(Index, true);
  1469. Out.Position = TerrainVertex.Position;
  1470. Out.Depth = Out.Position.z / Out.Position.w;
  1471. return Out;
  1472. }
  1473. #endif // #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  1474. // ---------------------------------------------------------------------------
  1475. float4 PS_CreateShadowMap(VSOutput_CreateShadowMap In) : COLOR
  1476. {
  1477. return In.Depth;
  1478. }
  1479. // ---------------------------------------------------------------------------
  1480. // TECHNIQUE: CreateShadowMap
  1481. // ---------------------------------------------------------------------------
  1482. technique _CreateShadowMap
  1483. {
  1484. pass P0
  1485. {
  1486. #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  1487. VertexShader = compile VS_2_0 VS_CreateShadowMapVFetch();
  1488. #else // #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  1489. VertexShader = compile VS_2_0 VS_CreateShadowMap();
  1490. #endif // #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  1491. PixelShader = compile PS_2_0 PS_CreateShadowMap();
  1492. ZEnable = true;
  1493. ZWriteEnable = true;
  1494. ZFunc = ZFUNC_INFRONT;
  1495. CullMode = CW;
  1496. AlphaBlendEnable = false;
  1497. AlphaTestEnable = false;
  1498. }
  1499. }
  1500. // ---------------------------------------------------------------------------
  1501. // TECHNIQUE: CreateDepthMap
  1502. // ---------------------------------------------------------------------------
  1503. technique _CreateDepthMap
  1504. {
  1505. pass P0
  1506. {
  1507. #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  1508. VertexShader = compile VS_2_0 VS_CreateShadowMapVFetch();
  1509. #else // #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  1510. VertexShader = compile VS_2_0 VS_CreateShadowMap();
  1511. #endif // #if defined(TERRAIN_USE_MULTIPLE_STREAM)
  1512. #if defined(EA_PLATFORM_XENON)
  1513. PixelShader = NULL;
  1514. #else
  1515. PixelShader = compile PS_2_0 PS_CreateShadowMap();
  1516. #endif
  1517. ZEnable = true;
  1518. ZWriteEnable = true;
  1519. ZFunc = ZFUNC_INFRONT;
  1520. CullMode = CW;
  1521. AlphaBlendEnable = false;
  1522. AlphaTestEnable = false;
  1523. }
  1524. }