terrFeatureHLSL.cpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "terrain/hlsl/terrFeatureHLSL.h"
  24. #include "terrain/terrFeatureTypes.h"
  25. #include "materials/materialFeatureTypes.h"
  26. #include "materials/materialFeatureData.h"
  27. #include "materials/processedMaterial.h"
  28. #include "gfx/gfxDevice.h"
  29. #include "shaderGen/langElement.h"
  30. #include "shaderGen/shaderOp.h"
  31. #include "shaderGen/featureMgr.h"
  32. #include "shaderGen/shaderGen.h"
  33. #include "core/module.h"
  34. namespace
  35. {
  36. void register_hlsl_shader_features_for_terrain(GFXAdapterType type)
  37. {
  38. if (type != Direct3D11)
  39. return;
  40. FEATUREMGR->registerFeature( MFT_TerrainBaseMap, new TerrainBaseMapFeatHLSL );
  41. FEATUREMGR->registerFeature( MFT_TerrainParallaxMap, new NamedFeatureHLSL( "Terrain Parallax Texture" ) );
  42. FEATUREMGR->registerFeature( MFT_TerrainDetailMap, new TerrainDetailMapFeatHLSL );
  43. FEATUREMGR->registerFeature( MFT_TerrainNormalMap, new TerrainNormalMapFeatHLSL );
  44. FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new NamedFeatureHLSL("TerrainMacroMap Deprecated")); // new TerrainMacroMapFeatHLSL);
  45. FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatHLSL );
  46. FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureHLSL( "Terrain Side Projection" ) );
  47. FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatHLSL );
  48. FEATUREMGR->registerFeature( MFT_TerrainORMMap, new TerrainORMMapFeatHLSL );
  49. FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatHLSL );
  50. }
  51. };
  52. MODULE_BEGIN( TerrainFeatHLSL )
  53. MODULE_INIT_AFTER( ShaderGen )
  54. MODULE_INIT
  55. {
  56. SHADERGEN->getFeatureInitSignal().notify(&register_hlsl_shader_features_for_terrain);
  57. }
  58. MODULE_END;
  59. TerrainFeatHLSL::TerrainFeatHLSL()
  60. : mTorqueDep(ShaderGen::smCommonShaderPath + String("/torque.hlsl" ))
  61. {
  62. addDependency( &mTorqueDep );
  63. }
  64. Var* TerrainFeatHLSL::_getUniformVar( const char *name, const char *type, ConstantSortPosition csp )
  65. {
  66. Var *theVar = (Var*)LangElement::find( name );
  67. if ( !theVar )
  68. {
  69. theVar = new Var;
  70. theVar->setType( type );
  71. theVar->setName( name );
  72. theVar->uniform = true;
  73. theVar->constSortPos = csp;
  74. }
  75. return theVar;
  76. }
  77. Var* TerrainFeatHLSL::_getInDetailCoord( Vector<ShaderComponent*> &componentList )
  78. {
  79. String name( String::ToString( "detCoord%d", getProcessIndex() ) );
  80. Var *inDet = (Var*)LangElement::find( name );
  81. if ( !inDet )
  82. {
  83. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  84. inDet = connectComp->getElement( RT_TEXCOORD );
  85. inDet->setName( name );
  86. inDet->setStructName( "IN" );
  87. inDet->setType( "float4" );
  88. }
  89. return inDet;
  90. }
  91. Var* TerrainFeatHLSL::_getInMacroCoord( Vector<ShaderComponent*> &componentList )
  92. {
  93. String name( String::ToString( "macroCoord%d", getProcessIndex() ) );
  94. Var *inDet = (Var*)LangElement::find( name );
  95. if ( !inDet )
  96. {
  97. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  98. inDet = connectComp->getElement( RT_TEXCOORD );
  99. inDet->setName( name );
  100. inDet->setStructName( "IN" );
  101. inDet->setType( "float4" );
  102. }
  103. return inDet;
  104. }
  105. Var* TerrainFeatHLSL::_getNormalMapTex()
  106. {
  107. String name(String::ToString("normalMap%d", getProcessIndex()));
  108. Var *normalMap = (Var*)LangElement::find(name);
  109. if (!normalMap)
  110. {
  111. normalMap = new Var;
  112. normalMap->setType("SamplerState");
  113. normalMap->setName(name);
  114. normalMap->uniform = true;
  115. normalMap->sampler = true;
  116. normalMap->constNum = Var::getTexUnitNum();
  117. }
  118. return normalMap;
  119. }
  120. Var* TerrainFeatHLSL::_getORMConfigMapTex()
  121. {
  122. String name(String::ToString("ormConfigMap%d", getProcessIndex()));
  123. Var *ormConfigMap = (Var*)LangElement::find(name);
  124. if (!ormConfigMap)
  125. {
  126. ormConfigMap = new Var;
  127. ormConfigMap->setType("SamplerState");
  128. ormConfigMap->setName(name);
  129. ormConfigMap->uniform = true;
  130. ormConfigMap->sampler = true;
  131. ormConfigMap->constNum = Var::getTexUnitNum();
  132. }
  133. return ormConfigMap;
  134. }
  135. Var* TerrainFeatHLSL::_getDetailIdStrengthParallax()
  136. {
  137. String name( String::ToString( "detailIdStrengthParallax%d", getProcessIndex() ) );
  138. Var *detailInfo = (Var*)LangElement::find( name );
  139. if ( !detailInfo )
  140. {
  141. detailInfo = new Var;
  142. detailInfo->setType( "float3" );
  143. detailInfo->setName( name );
  144. detailInfo->uniform = true;
  145. detailInfo->constSortPos = cspPotentialPrimitive;
  146. }
  147. return detailInfo;
  148. }
  149. Var* TerrainFeatHLSL::_getMacroIdStrengthParallax()
  150. {
  151. String name( String::ToString( "macroIdStrengthParallax%d", getProcessIndex() ) );
  152. Var *detailInfo = (Var*)LangElement::find( name );
  153. if ( !detailInfo )
  154. {
  155. detailInfo = new Var;
  156. detailInfo->setType( "float3" );
  157. detailInfo->setName( name );
  158. detailInfo->uniform = true;
  159. detailInfo->constSortPos = cspPotentialPrimitive;
  160. }
  161. return detailInfo;
  162. }
  163. void TerrainBaseMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
  164. const MaterialFeatureData &fd )
  165. {
  166. MultiLine *meta = new MultiLine;
  167. output = meta;
  168. // Generate the incoming texture var.
  169. Var *inTex;
  170. {
  171. Var *inPos = (Var*)LangElement::find( "inPosition" );
  172. if ( !inPos )
  173. inPos = (Var*)LangElement::find( "position" );
  174. inTex = new Var( "texCoord", "float3" );
  175. Var *oneOverTerrainSize = _getUniformVar( "oneOverTerrainSize", "float", cspPass );
  176. // NOTE: The y coord here should be negative to have
  177. // the texture maps not end up flipped which also caused
  178. // normal and parallax mapping to be incorrect.
  179. //
  180. // This mistake early in development means that the layer
  181. // id bilinear blend depends on it being that way.
  182. //
  183. // So instead i fixed this by flipping the base and detail
  184. // coord y scale to compensate when rendering.
  185. //
  186. meta->addStatement( new GenOp( " @ = @.xyz * float3( @, @, -@ );\r\n",
  187. new DecOp( inTex ), inPos, oneOverTerrainSize, oneOverTerrainSize, oneOverTerrainSize ) );
  188. }
  189. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  190. // Pass the texture coord to the pixel shader.
  191. Var *outTex = connectComp->getElement( RT_TEXCOORD );
  192. outTex->setName( "outTexCoord" );
  193. outTex->setStructName( "OUT" );
  194. outTex->setType( "float3" );
  195. meta->addStatement( new GenOp( " @.xy = @.xy;\r\n", outTex, inTex ) );
  196. // If this shader has a side projected layer then we
  197. // pass the dot product between the +Y and the normal
  198. // thru outTexCoord.z for use in blending the textures.
  199. if ( fd.features.hasFeature( MFT_TerrainSideProject ) )
  200. {
  201. Var *inNormal = (Var*)LangElement::find( "normal" );
  202. meta->addStatement(
  203. new GenOp( " @.z = pow( abs( dot( normalize( float3( @.x, @.y, 0 ) ), float3( 0, 1, 0 ) ) ), 10.0 );\r\n",
  204. outTex, inNormal, inNormal ) );
  205. }
  206. else
  207. meta->addStatement( new GenOp( " @.z = 0;\r\n", outTex ) );
  208. // HACK: This is sort of lazy... we generate the tanget
  209. // vector here so that we're sure it exists in the parallax
  210. // and normal features which will expect "T" to exist.
  211. //
  212. // If this shader doesn't use it the shader compiler will
  213. // optimize away this code.
  214. //
  215. Var *inTangentZ = getVertTexCoord( "tcTangentZ" );
  216. Var *inTanget = new Var( "T", "float3" );
  217. Var *squareSize = _getUniformVar( "squareSize", "float", cspPass );
  218. meta->addStatement( new GenOp( " @ = normalize( float3( @, 0, @ ) );\r\n",
  219. new DecOp( inTanget ), squareSize, inTangentZ ) );
  220. }
  221. void TerrainBaseMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
  222. const MaterialFeatureData &fd )
  223. {
  224. // grab connector texcoord register
  225. Var *texCoord = getInTexCoord( "texCoord", "float3", componentList );
  226. // create texture var
  227. Var *diffuseMap = new Var;
  228. diffuseMap->setType( "SamplerState" );
  229. diffuseMap->setName( "baseTexMap" );
  230. diffuseMap->uniform = true;
  231. diffuseMap->sampler = true;
  232. diffuseMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
  233. MultiLine *meta = new MultiLine;
  234. Var *baseColor = new Var;
  235. baseColor->setType( "float4" );
  236. baseColor->setName( "baseColor" );
  237. Var *diffuseTex = new Var;
  238. diffuseTex->setType("Texture2D");
  239. diffuseTex->setName("baseTexture");
  240. diffuseTex->uniform = true;
  241. diffuseTex->texture = true;
  242. diffuseTex->constNum = diffuseMap->constNum;
  243. meta->addStatement(new GenOp(" @ = @.Sample( @, @.xy );\r\n", new DecOp(baseColor), diffuseTex, diffuseMap, texCoord));
  244. ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
  245. if (fd.features.hasFeature(MFT_isDeferred))
  246. {
  247. target= ShaderFeature::RenderTarget1;
  248. }
  249. meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul,NULL,target ) ) );
  250. output = meta;
  251. }
  252. ShaderFeature::Resources TerrainBaseMapFeatHLSL::getResources( const MaterialFeatureData &fd )
  253. {
  254. Resources res;
  255. res.numTexReg = 1;
  256. res.numTex = 1;
  257. return res;
  258. }
  259. U32 TerrainBaseMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
  260. {
  261. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
  262. }
  263. TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL()
  264. : mTorqueDep(ShaderGen::smCommonShaderPath + String("/torque.hlsl" )),
  265. mTerrainDep(ShaderGen::smCommonShaderPath + String("/terrain/terrain.hlsl" ))
  266. {
  267. addDependency( &mTorqueDep );
  268. addDependency( &mTerrainDep );
  269. }
  270. void TerrainDetailMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
  271. const MaterialFeatureData &fd )
  272. {
  273. const S32 detailIndex = getProcessIndex();
  274. // Grab incoming texture coords... the base map feature
  275. // made sure this was created.
  276. Var *inTex = (Var*)LangElement::find( "texCoord" );
  277. AssertFatal( inTex, "The texture coord is missing!" );
  278. // Grab the input position.
  279. Var *inPos = (Var*)LangElement::find( "inPosition" );
  280. if ( !inPos )
  281. inPos = (Var*)LangElement::find( "position" );
  282. // Get the object space eye position.
  283. Var *eyePos = _getUniformVar( "eyePos", "float3", cspPotentialPrimitive );
  284. MultiLine *meta = new MultiLine;
  285. // If we have parallax mapping then make sure we've sent
  286. // the negative view vector to the pixel shader.
  287. if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
  288. !LangElement::find( "outNegViewTS" ) )
  289. {
  290. // Get the object to tangent transform which
  291. // will consume 3 output registers.
  292. Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta, fd );
  293. // Now use a single output register to send the negative
  294. // view vector in tangent space to the pixel shader.
  295. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  296. Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD );
  297. outNegViewTS->setName( "outNegViewTS" );
  298. outNegViewTS->setStructName( "OUT" );
  299. outNegViewTS->setType( "float3" );
  300. meta->addStatement( new GenOp( " @ = mul( @, float3( @ - @.xyz ) );\r\n",
  301. outNegViewTS, objToTangentSpace, eyePos, inPos ) );
  302. }
  303. // Get the distance from the eye to this vertex.
  304. Var *dist = (Var*)LangElement::find( "dist" );
  305. if ( !dist )
  306. {
  307. dist = new Var;
  308. dist->setType( "float" );
  309. dist->setName( "dist" );
  310. meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n",
  311. new DecOp( dist ), inPos, eyePos ) );
  312. }
  313. // grab connector texcoord register
  314. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  315. Var *outTex = connectComp->getElement( RT_TEXCOORD );
  316. outTex->setName( String::ToString( "detCoord%d", detailIndex ) );
  317. outTex->setStructName( "OUT" );
  318. outTex->setType( "float4" );
  319. // Get the detail scale and fade info.
  320. Var *detScaleAndFade = new Var;
  321. detScaleAndFade->setType( "float4" );
  322. detScaleAndFade->setName( String::ToString( "detailScaleAndFade%d", detailIndex ) );
  323. detScaleAndFade->uniform = true;
  324. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  325. // Setup the detail coord.
  326. //
  327. // NOTE: You see here we scale the texture coord by 'xyx'
  328. // to generate the detail coord. This y is here because
  329. // its scale is flipped to correct for the non negative y
  330. // in texCoord.
  331. //
  332. // See TerrainBaseMapFeatHLSL::processVert().
  333. //
  334. meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) );
  335. // And sneak the detail fade thru the w detailCoord.
  336. meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  337. outTex, detScaleAndFade, dist, detScaleAndFade ) );
  338. output = meta;
  339. }
  340. void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
  341. const MaterialFeatureData &fd )
  342. {
  343. const S32 detailIndex = getProcessIndex();
  344. Var *inTex = getVertTexCoord( "texCoord" );
  345. MultiLine *meta = new MultiLine;
  346. // We need the negative tangent space view vector
  347. // as in parallax mapping we step towards the camera.
  348. Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
  349. if ( !negViewTS &&
  350. fd.features.hasFeature( MFT_TerrainParallaxMap ) )
  351. {
  352. Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
  353. if ( !inNegViewTS )
  354. {
  355. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  356. inNegViewTS = connectComp->getElement( RT_TEXCOORD );
  357. inNegViewTS->setName( "outNegViewTS" );
  358. inNegViewTS->setStructName( "IN" );
  359. inNegViewTS->setType( "float3" );
  360. }
  361. negViewTS = new Var( "negViewTS", "float3" );
  362. meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
  363. }
  364. // Get the layer samples.
  365. Var *layerSample = (Var*)LangElement::find( "layerSample" );
  366. if ( !layerSample )
  367. {
  368. layerSample = new Var;
  369. layerSample->setType( "float4" );
  370. layerSample->setName( "layerSample" );
  371. // Get the layer texture var
  372. Var *layerTex = new Var;
  373. layerTex->setType( "SamplerState" );
  374. layerTex->setName( "layerTex" );
  375. layerTex->uniform = true;
  376. layerTex->sampler = true;
  377. layerTex->constNum = Var::getTexUnitNum();
  378. Var* layerTexObj = new Var;
  379. layerTexObj->setName("layerTexObj");
  380. layerTexObj->setType("Texture2D");
  381. layerTexObj->uniform = true;
  382. layerTexObj->texture = true;
  383. layerTexObj->constNum = layerTex->constNum;
  384. // Read the layer texture to get the samples.
  385. meta->addStatement(new GenOp(" @ = round( @.Sample( @, @.xy ) * 255.0f );\r\n",
  386. new DecOp(layerSample), layerTexObj, layerTex, inTex));
  387. }
  388. Var *layerSize = (Var*)LangElement::find( "layerSize" );
  389. if ( !layerSize )
  390. {
  391. layerSize = new Var;
  392. layerSize->setType( "float" );
  393. layerSize->setName( "layerSize" );
  394. layerSize->uniform = true;
  395. layerSize->constSortPos = cspPass;
  396. }
  397. // Grab the incoming detail coord.
  398. Var *inDet = _getInDetailCoord( componentList );
  399. // Get the detail id.
  400. Var *detailInfo = _getDetailIdStrengthParallax();
  401. // Create the detail blend var.
  402. Var *detailBlend = new Var;
  403. detailBlend->setType( "float" );
  404. detailBlend->setName( String::ToString( "detailBlend%d", detailIndex ) );
  405. // Calculate the blend for this detail texture.
  406. meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
  407. new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
  408. // Get a var and accumulate the blend amount.
  409. Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
  410. if ( !blendTotal )
  411. {
  412. blendTotal = new Var;
  413. blendTotal->setName( "blendTotal" );
  414. blendTotal->setType( "float" );
  415. meta->addStatement( new GenOp( " @ = 0;\r\n", new DecOp( blendTotal ) ) );
  416. }
  417. // Add to the blend total.
  418. meta->addStatement(new GenOp(" @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend));
  419. // If we had a parallax feature... then factor in the parallax
  420. // amount so that it fades out with the layer blending.
  421. if (fd.features.hasFeature(MFT_TerrainParallaxMap, detailIndex))
  422. {
  423. // Get the rest of our inputs.
  424. Var *normalMap = _getNormalMapTex();
  425. String name(String::ToString("normalMapTex%d", getProcessIndex()));
  426. Var *normalMapTex = (Var*)LangElement::find(name);
  427. if (!normalMapTex)
  428. {
  429. normalMapTex = new Var;
  430. normalMapTex->setName(String::ToString("normalMapTex%d", getProcessIndex()));
  431. normalMapTex->setType("Texture2D");
  432. normalMapTex->uniform = true;
  433. normalMapTex->texture = true;
  434. normalMapTex->constNum = normalMap->constNum;
  435. }
  436. // Call the library function to do the rest.
  437. if (fd.features.hasFeature(MFT_IsBC3nm, detailIndex))
  438. {
  439. meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, @, @.xy, @, @.z * @ );\r\n",
  440. inDet, normalMapTex, normalMap, inDet, negViewTS, detailInfo, detailBlend));
  441. }
  442. else
  443. {
  444. meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, @, @.xy, @, @.z * @ );\r\n",
  445. inDet, normalMapTex, normalMap, inDet, negViewTS, detailInfo, detailBlend));
  446. }
  447. }
  448. // Check to see if we have a gbuffer normal.
  449. Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
  450. // If we have a gbuffer normal and we don't have a
  451. // normal map feature then we need to lerp in a
  452. // default normal else the normals below this layer
  453. // will show thru.
  454. if (gbNormal &&
  455. !fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex))
  456. {
  457. Var *viewToTangent = getInViewToTangent(componentList);
  458. meta->addStatement(new GenOp(" @ = lerp( @, @[2], min( @, @.w ) );\r\n",
  459. gbNormal, gbNormal, viewToTangent, detailBlend, inDet));
  460. }
  461. Var *detailColor = (Var*)LangElement::find( "detailColor" );
  462. if ( !detailColor )
  463. {
  464. detailColor = new Var;
  465. detailColor->setType( "float4" );
  466. detailColor->setName( "detailColor" );
  467. meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
  468. }
  469. // Get the detail texture.
  470. Var *detailMap = new Var;
  471. detailMap->setType( "SamplerState" );
  472. detailMap->setName( String::ToString( "detailMap%d", detailIndex ) );
  473. detailMap->uniform = true;
  474. detailMap->sampler = true;
  475. detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
  476. // If we're using SM 3.0 then take advantage of
  477. // dynamic branching to skip layers per-pixel.
  478. if ( GFX->getPixelShaderVersion() >= 3.0f )
  479. meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
  480. meta->addStatement( new GenOp( " {\r\n" ) );
  481. // Note that we're doing the standard greyscale detail
  482. // map technique here which can darken and lighten the
  483. // diffuse texture.
  484. //
  485. // We take two color samples and lerp between them for
  486. // side projection layers... else a single sample.
  487. //
  488. //Sampled detail texture that is not expanded
  489. Var* detailTex = new Var;
  490. detailTex->setName(String::ToString("detailTex%d", detailIndex));
  491. detailTex->setType("Texture2D");
  492. detailTex->uniform = true;
  493. detailTex->texture = true;
  494. detailTex->constNum = detailMap->constNum;
  495. if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
  496. {
  497. meta->addStatement(new GenOp(" @ = ( lerp( @.Sample( @, @.yz ), @.Sample( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
  498. detailColor, detailTex, detailMap, inDet, detailTex, detailMap, inDet, inTex));
  499. }
  500. else
  501. {
  502. meta->addStatement(new GenOp(" @ = ( @.Sample( @, @.xy ) * 2.0 ) - 1.0;\r\n",
  503. detailColor, detailTex, detailMap, inDet));
  504. }
  505. meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
  506. detailColor, detailInfo, inDet ) );
  507. ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
  508. if (fd.features.hasFeature(MFT_isDeferred))
  509. target= ShaderFeature::RenderTarget1;
  510. Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
  511. meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n", outColor, outColor));
  512. meta->addStatement( new GenOp( " @ += @ * @;\r\n",
  513. outColor, detailColor, detailBlend));
  514. meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n", outColor, outColor));
  515. meta->addStatement( new GenOp( " }\r\n" ) );
  516. output = meta;
  517. }
  518. ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialFeatureData &fd )
  519. {
  520. Resources res;
  521. if ( getProcessIndex() == 0 )
  522. {
  523. // If this is the first detail pass then we
  524. // samples from the layer tex.
  525. res.numTex += 1;
  526. // If this material also does parallax then it
  527. // will generate the negative view vector and the
  528. // worldToTanget transform.
  529. if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) )
  530. res.numTexReg += 4;
  531. }
  532. // sample from the detail texture for diffuse coloring.
  533. res.numTex += 1;
  534. // If we have parallax for this layer then we'll also
  535. // be sampling the normal map for the parallax heightmap.
  536. if ( fd.features.hasFeature( MFT_TerrainParallaxMap, getProcessIndex() ) )
  537. res.numTex += 1;
  538. // Finally we always send the detail texture
  539. // coord to the pixel shader.
  540. res.numTexReg += 1;
  541. return res;
  542. }
  543. U32 TerrainDetailMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
  544. {
  545. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
  546. }
  547. TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL()
  548. : mTorqueDep(ShaderGen::smCommonShaderPath + String("/torque.hlsl" )),
  549. mTerrainDep(ShaderGen::smCommonShaderPath + String("/terrain/terrain.hlsl" ))
  550. {
  551. addDependency( &mTorqueDep );
  552. addDependency( &mTerrainDep );
  553. }
  554. void TerrainMacroMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
  555. const MaterialFeatureData &fd )
  556. {
  557. const S32 detailIndex = getProcessIndex();
  558. // Grab incoming texture coords... the base map feature
  559. // made sure this was created.
  560. Var *inTex = (Var*)LangElement::find( "texCoord" );
  561. AssertFatal( inTex, "The texture coord is missing!" );
  562. // Grab the input position.
  563. Var *inPos = (Var*)LangElement::find( "inPosition" );
  564. if ( !inPos )
  565. inPos = (Var*)LangElement::find( "position" );
  566. // Get the object space eye position.
  567. Var *eyePos = _getUniformVar( "eyePos", "float3", cspPotentialPrimitive );
  568. MultiLine *meta = new MultiLine;
  569. // Get the distance from the eye to this vertex.
  570. Var *dist = (Var*)LangElement::find( "macroDist" );
  571. if ( !dist )
  572. {
  573. dist = new Var;
  574. dist->setType( "float" );
  575. dist->setName( "macroDist" );
  576. meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n",
  577. new DecOp( dist ), inPos, eyePos ) );
  578. }
  579. // grab connector texcoord register
  580. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  581. Var *outTex = connectComp->getElement( RT_TEXCOORD );
  582. outTex->setName( String::ToString( "macroCoord%d", detailIndex ) );
  583. outTex->setStructName( "OUT" );
  584. outTex->setType( "float4" );
  585. // Get the detail scale and fade info.
  586. Var *detScaleAndFade = new Var;
  587. detScaleAndFade->setType( "float4" );
  588. detScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) );
  589. detScaleAndFade->uniform = true;
  590. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  591. // Setup the detail coord.
  592. meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) );
  593. // And sneak the detail fade thru the w detailCoord.
  594. meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  595. outTex, detScaleAndFade, dist, detScaleAndFade ) );
  596. output = meta;
  597. }
  598. void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
  599. const MaterialFeatureData &fd )
  600. {
  601. const S32 detailIndex = getProcessIndex();
  602. Var *inTex = getVertTexCoord( "texCoord" );
  603. MultiLine *meta = new MultiLine;
  604. // We need the negative tangent space view vector
  605. // as in parallax mapping we step towards the camera.
  606. Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
  607. if ( !negViewTS &&
  608. fd.features.hasFeature( MFT_TerrainParallaxMap ) )
  609. {
  610. Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
  611. if ( !inNegViewTS )
  612. {
  613. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  614. inNegViewTS = connectComp->getElement( RT_TEXCOORD );
  615. inNegViewTS->setName( "outNegViewTS" );
  616. inNegViewTS->setStructName( "IN" );
  617. inNegViewTS->setType( "float3" );
  618. }
  619. negViewTS = new Var( "negViewTS", "float3" );
  620. meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
  621. }
  622. // Get the layer samples.
  623. Var *layerSample = (Var*)LangElement::find( "layerSample" );
  624. if ( !layerSample )
  625. {
  626. layerSample = new Var;
  627. layerSample->setType( "float4" );
  628. layerSample->setName( "layerSample" );
  629. // Get the layer texture var
  630. Var *layerTex = new Var;
  631. layerTex->setType( "SamplerState" );
  632. layerTex->setName( "macrolayerTex" );
  633. layerTex->uniform = true;
  634. layerTex->sampler = true;
  635. layerTex->constNum = Var::getTexUnitNum();
  636. // Read the layer texture to get the samples.
  637. Var *layerTexObj = new Var;
  638. layerTexObj->setType("Texture2D");
  639. layerTexObj->setName("macroLayerTexObj");
  640. layerTexObj->uniform = true;
  641. layerTexObj->texture = true;
  642. layerTexObj->constNum = layerTex->constNum;
  643. meta->addStatement(new GenOp(" @ = round( @.Sample( @, @.xy ) * 255.0f );\r\n",
  644. new DecOp(layerSample), layerTexObj, layerTex, inTex));
  645. }
  646. Var *layerSize = (Var*)LangElement::find( "layerSize" );
  647. if ( !layerSize )
  648. {
  649. layerSize = new Var;
  650. layerSize->setType( "float" );
  651. layerSize->setName( "layerSize" );
  652. layerSize->uniform = true;
  653. layerSize->constSortPos = cspPass;
  654. }
  655. // Grab the incoming detail coord.
  656. Var *inDet = _getInMacroCoord( componentList );
  657. // Get the detail id.
  658. Var *detailInfo = _getMacroIdStrengthParallax();
  659. // Create the detail blend var.
  660. Var *detailBlend = new Var;
  661. detailBlend->setType( "float" );
  662. detailBlend->setName( String::ToString( "macroBlend%d", detailIndex ) );
  663. // Calculate the blend for this detail texture.
  664. meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
  665. new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
  666. // Get a var and accumulate the blend amount.
  667. Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
  668. if ( !blendTotal )
  669. {
  670. blendTotal = new Var;
  671. blendTotal->setName( "blendTotal" );
  672. blendTotal->setType( "float" );
  673. meta->addStatement( new GenOp( " @ = 0;\r\n", new DecOp( blendTotal ) ) );
  674. }
  675. // Add to the blend total.
  676. meta->addStatement(new GenOp(" @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend));
  677. // Check to see if we have a gbuffer normal.
  678. Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
  679. // If we have a gbuffer normal and we don't have a
  680. // normal map feature then we need to lerp in a
  681. // default normal else the normals below this layer
  682. // will show thru.
  683. if ( gbNormal &&
  684. !fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
  685. {
  686. Var *viewToTangent = getInViewToTangent( componentList );
  687. meta->addStatement( new GenOp( " @ = lerp( @, @[2], min( @, @.w ) );\r\n",
  688. gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
  689. }
  690. Var *detailColor = (Var*)LangElement::find("macroColor");
  691. if (!detailColor)
  692. {
  693. detailColor = new Var;
  694. detailColor->setType( "float4" );
  695. detailColor->setName( "macroColor" );
  696. meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
  697. }
  698. // Get the detail texture.
  699. Var *detailMap = new Var;
  700. detailMap->setType( "SamplerState" );
  701. detailMap->setName( String::ToString( "macroMap%d", detailIndex ) );
  702. detailMap->uniform = true;
  703. detailMap->sampler = true;
  704. detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
  705. //Create texture object for directx 11
  706. Var *detailTex = new Var;
  707. detailTex->setName(String::ToString("macroMapTex%d", detailIndex));
  708. detailTex->setType("Texture2D");
  709. detailTex->uniform = true;
  710. detailTex->texture = true;
  711. detailTex->constNum = detailMap->constNum;
  712. // If we're using SM 3.0 then take advantage of
  713. // dynamic branching to skip layers per-pixel.
  714. if ( GFX->getPixelShaderVersion() >= 3.0f )
  715. meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
  716. meta->addStatement( new GenOp( " {\r\n" ) );
  717. // Note that we're doing the standard greyscale detail
  718. // map technique here which can darken and lighten the
  719. // diffuse texture.
  720. //
  721. // We take two color samples and lerp between them for
  722. // side projection layers... else a single sample.
  723. //
  724. if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
  725. {
  726. meta->addStatement(new GenOp(" @ = ( lerp( @.Sample( @, @.yz ), @.Sample( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
  727. detailColor, detailTex, detailMap, inDet, detailTex, detailMap, inDet, inTex));
  728. }
  729. else
  730. {
  731. meta->addStatement(new GenOp(" @ = ( @.Sample( @, @.xy ) * 2.0 ) - 1.0;\r\n",
  732. detailColor, detailTex, detailMap, inDet));
  733. }
  734. meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
  735. detailColor, detailInfo, inDet ) );
  736. ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
  737. if (fd.features.hasFeature(MFT_isDeferred))
  738. target= ShaderFeature::RenderTarget1;
  739. Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
  740. meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n", outColor, outColor));
  741. meta->addStatement(new GenOp(" @ += @ * @;\r\n",
  742. outColor, detailColor, detailBlend));
  743. meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n", outColor, outColor));
  744. meta->addStatement( new GenOp( " }\r\n" ) );
  745. output = meta;
  746. }
  747. ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFeatureData &fd )
  748. {
  749. Resources res;
  750. if ( getProcessIndex() == 0 )
  751. {
  752. // If this is the first detail pass then we
  753. // samples from the layer tex.
  754. res.numTex += 1;
  755. }
  756. res.numTex += 1;
  757. // Finally we always send the detail texture
  758. // coord to the pixel shader.
  759. res.numTexReg += 1;
  760. return res;
  761. }
  762. U32 TerrainMacroMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
  763. {
  764. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
  765. }
  766. void TerrainNormalMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
  767. const MaterialFeatureData &fd )
  768. {
  769. // We only need to process normals during the deferred.
  770. if ( !fd.features.hasFeature( MFT_DeferredConditioner ) )
  771. return;
  772. MultiLine *meta = new MultiLine;
  773. // Make sure the world to tangent transform
  774. // is created and available for the pixel shader.
  775. getOutViewToTangent( componentList, meta, fd );
  776. output = meta;
  777. }
  778. void TerrainNormalMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
  779. const MaterialFeatureData &fd )
  780. {
  781. // We only need to process normals during the deferred.
  782. if (!fd.features.hasFeature(MFT_DeferredConditioner))
  783. return;
  784. MultiLine *meta = new MultiLine;
  785. Var *viewToTangent = getInViewToTangent( componentList );
  786. // This var is read from GBufferConditionerHLSL and
  787. // used in the deferred output.
  788. Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
  789. if ( !gbNormal )
  790. {
  791. gbNormal = new Var;
  792. gbNormal->setName( "gbNormal" );
  793. gbNormal->setType( "float3" );
  794. meta->addStatement( new GenOp( " @ = @[2];\r\n", new DecOp( gbNormal ), viewToTangent ) );
  795. }
  796. const S32 normalIndex = getProcessIndex();
  797. Var *detailBlend = (Var*)LangElement::find( String::ToString( "detailBlend%d", normalIndex ) );
  798. AssertFatal( detailBlend, "The detail blend is missing!" );
  799. // If we're using SM 3.0 then take advantage of
  800. // dynamic branching to skip layers per-pixel.
  801. if ( GFX->getPixelShaderVersion() >= 3.0f )
  802. meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
  803. meta->addStatement( new GenOp( " {\r\n" ) );
  804. // Get the normal map texture.
  805. Var *normalMap = _getNormalMapTex();
  806. /// Get the texture coord.
  807. Var *inDet = _getInDetailCoord( componentList );
  808. Var *inTex = getVertTexCoord( "texCoord" );
  809. // Sample the normal map.
  810. //
  811. // We take two normal samples and lerp between them for
  812. // side projection layers... else a single sample.
  813. LangElement *texOp;
  814. String name(String::ToString("normalMapTex%d", getProcessIndex()));
  815. Var *normalMapTex = (Var*)LangElement::find(name);
  816. if (!normalMapTex)
  817. {
  818. normalMapTex = new Var;
  819. normalMapTex->setName(String::ToString("normalMapTex%d", getProcessIndex()));
  820. normalMapTex->setType("Texture2D");
  821. normalMapTex->uniform = true;
  822. normalMapTex->texture = true;
  823. normalMapTex->constNum = normalMap->constNum;
  824. }
  825. if (fd.features.hasFeature(MFT_TerrainSideProject, normalIndex))
  826. {
  827. texOp = new GenOp("lerp( @.Sample( @, @.yz ), @.Sample( @, @.xz ), @.z )",
  828. normalMapTex, normalMap, inDet, normalMapTex, normalMap, inDet, inTex);
  829. }
  830. else
  831. texOp = new GenOp("@.Sample(@, @.xy)", normalMapTex, normalMap, inDet);
  832. // create bump normal
  833. Var *bumpNorm = new Var;
  834. bumpNorm->setName( "bumpNormal" );
  835. bumpNorm->setType( "float4" );
  836. LangElement *bumpNormDecl = new DecOp( bumpNorm );
  837. meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
  838. // If this is the last normal map then we
  839. // can test to see the total blend value
  840. // to see if we should clip the result.
  841. Var* blendTotal = (Var*)LangElement::find("blendTotal");
  842. if (blendTotal)
  843. {
  844. if (fd.features.getNextFeatureIndex(MFT_TerrainNormalMap, normalIndex) == -1)
  845. meta->addStatement(new GenOp(" if ( @ > 0.0001f ){\r\n\r\n", blendTotal));
  846. }
  847. // Normalize is done later...
  848. // Note: The reverse mul order is intentional. Affine matrix.
  849. meta->addStatement( new GenOp( " @ = lerp( @, mul( @.xyz, @ ), min( @, @.w ) );\r\n",
  850. gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet ) );
  851. if (blendTotal)
  852. {
  853. if (fd.features.getNextFeatureIndex(MFT_TerrainNormalMap, normalIndex) == -1)
  854. meta->addStatement(new GenOp(" }\r\n"));
  855. }
  856. // End the conditional block.
  857. meta->addStatement( new GenOp( " }\r\n" ) );
  858. output = meta;
  859. }
  860. ShaderFeature::Resources TerrainNormalMapFeatHLSL::getResources( const MaterialFeatureData &fd )
  861. {
  862. Resources res;
  863. // If this is the first normal map and there
  864. // are no parallax features then we will
  865. // generate the worldToTanget transform.
  866. if ( !fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
  867. ( getProcessIndex() == 0 || !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() - 1 ) ) )
  868. res.numTexReg = 3;
  869. res.numTex = 1;
  870. return res;
  871. }
  872. void TerrainLightMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
  873. const MaterialFeatureData &fd )
  874. {
  875. // grab connector texcoord register
  876. Var *inTex = (Var*)LangElement::find( "texCoord" );
  877. if ( !inTex )
  878. return;
  879. // Get the lightmap texture.
  880. Var *lightMap = new Var;
  881. lightMap->setType( "SamplerState" );
  882. lightMap->setName( "lightMapTex" );
  883. lightMap->uniform = true;
  884. lightMap->sampler = true;
  885. lightMap->constNum = Var::getTexUnitNum();
  886. MultiLine *meta = new MultiLine;
  887. // Find or create the lightMask value which is read by
  888. // RTLighting to mask out the lights.
  889. //
  890. // The first light is always the sunlight so we apply
  891. // the shadow mask to only the first channel.
  892. //
  893. Var *lightMask = (Var*)LangElement::find( "lightMask" );
  894. if ( !lightMask )
  895. {
  896. lightMask = new Var( "lightMask", "float4" );
  897. meta->addStatement( new GenOp( " @ = 1;\r\n", new DecOp( lightMask ) ) );
  898. }
  899. Var* lightMapTex = new Var;
  900. lightMapTex->setName("lightMapTexObj");
  901. lightMapTex->setType("Texture2D");
  902. lightMapTex->uniform = true;
  903. lightMapTex->texture = true;
  904. lightMapTex->constNum = lightMap->constNum;
  905. meta->addStatement(new GenOp(" @[0] = @.Sample( @, @.xy ).r;\r\n", lightMask, lightMapTex, lightMap, inTex));
  906. output = meta;
  907. }
  908. ShaderFeature::Resources TerrainLightMapFeatHLSL::getResources( const MaterialFeatureData &fd )
  909. {
  910. Resources res;
  911. res.numTex = 1;
  912. return res;
  913. }
  914. void TerrainAdditiveFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
  915. const MaterialFeatureData &fd )
  916. {
  917. Var *color = NULL;
  918. Var* norm = NULL;
  919. if (fd.features[MFT_isDeferred])
  920. {
  921. color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
  922. norm = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
  923. }
  924. else
  925. color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
  926. Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
  927. if ( !color || !blendTotal )
  928. return;
  929. MultiLine *meta = new MultiLine;
  930. meta->addStatement( new GenOp( " clip( @ - 0.0001 );\r\n", blendTotal ) );
  931. meta->addStatement( new GenOp( " @.a = @;\r\n", color, blendTotal ) );
  932. if (fd.features[MFT_isDeferred])
  933. {
  934. meta->addStatement(new GenOp(" @.a = @;\r\n", norm, blendTotal));
  935. }
  936. output = meta;
  937. }
  938. //standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO),
  939. //.b = specular strength, a= spec power.
  940. void TerrainORMMapFeatHLSL::processVert(Vector<ShaderComponent*> &componentList,
  941. const MaterialFeatureData &fd)
  942. {
  943. const S32 detailIndex = getProcessIndex();
  944. // Grab incoming texture coords... the base map feature
  945. // made sure this was created.
  946. Var *inTex = (Var*)LangElement::find("texCoord");
  947. AssertFatal(inTex, "The texture coord is missing!");
  948. // Grab the input position.
  949. Var *inPos = (Var*)LangElement::find("inPosition");
  950. if (!inPos)
  951. inPos = (Var*)LangElement::find("position");
  952. // Get the object space eye position.
  953. Var *eyePos = _getUniformVar("eyePos", "float3", cspPotentialPrimitive);
  954. MultiLine *meta = new MultiLine;
  955. // If we have parallax mapping then make sure we've sent
  956. // the negative view vector to the pixel shader.
  957. if (fd.features.hasFeature(MFT_TerrainParallaxMap) &&
  958. !LangElement::find("outNegViewTS"))
  959. {
  960. // Get the object to tangent transform which
  961. // will consume 3 output registers.
  962. Var *objToTangentSpace = getOutObjToTangentSpace(componentList, meta, fd);
  963. // Now use a single output register to send the negative
  964. // view vector in tangent space to the pixel shader.
  965. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
  966. Var *outNegViewTS = connectComp->getElement(RT_TEXCOORD);
  967. outNegViewTS->setName("outNegViewTS");
  968. outNegViewTS->setStructName("OUT");
  969. outNegViewTS->setType("float3");
  970. meta->addStatement(new GenOp(" @ = mul( @, float3( @ - @.xyz ) );\r\n",
  971. outNegViewTS, objToTangentSpace, eyePos, inPos));
  972. }
  973. // Get the distance from the eye to this vertex.
  974. Var *dist = (Var*)LangElement::find("dist");
  975. if (!dist)
  976. {
  977. dist = new Var;
  978. dist->setType("float");
  979. dist->setName("dist");
  980. meta->addStatement(new GenOp(" @ = distance( @.xyz, @ );\r\n",
  981. new DecOp(dist), inPos, eyePos));
  982. }
  983. // grab connector texcoord register
  984. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
  985. Var *outTex = (Var*)LangElement::find(String::ToString("detCoord%d", detailIndex));
  986. if (outTex == NULL)
  987. {
  988. outTex = connectComp->getElement(RT_TEXCOORD);
  989. outTex->setName(String::ToString("detCoord%d", detailIndex));
  990. outTex->setStructName("OUT");
  991. outTex->setType("float4");
  992. }
  993. // Get the detail scale and fade info.
  994. Var *detScaleAndFade = (Var*)LangElement::find(String::ToString("detailScaleAndFade%d", detailIndex));
  995. if (detScaleAndFade == NULL)
  996. {
  997. detScaleAndFade->setType("float4");
  998. detScaleAndFade->setName(String::ToString("detailScaleAndFade%d", detailIndex));
  999. detScaleAndFade->uniform = true;
  1000. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  1001. }
  1002. // Setup the detail coord.
  1003. //
  1004. // NOTE: You see here we scale the texture coord by 'xyx'
  1005. // to generate the detail coord. This y is here because
  1006. // its scale is flipped to correct for the non negative y
  1007. // in texCoord.
  1008. //
  1009. // See TerrainBaseMapFeatHLSL::processVert().
  1010. //
  1011. meta->addStatement(new GenOp(" @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade));
  1012. // And sneak the detail fade thru the w detailCoord.
  1013. meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  1014. outTex, detScaleAndFade, dist, detScaleAndFade));
  1015. output = meta;
  1016. }
  1017. U32 TerrainORMMapFeatHLSL::getOutputTargets(const MaterialFeatureData &fd) const
  1018. {
  1019. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::DefaultTarget;
  1020. }
  1021. void TerrainORMMapFeatHLSL::processPix(Vector<ShaderComponent*> &componentList,
  1022. const MaterialFeatureData &fd)
  1023. {
  1024. /// Get the texture coord.
  1025. Var *inDet = _getInDetailCoord(componentList);
  1026. Var *inTex = getVertTexCoord("texCoord");
  1027. const S32 compositeIndex = getProcessIndex();
  1028. Var *ormConfigMap = _getORMConfigMapTex();
  1029. // Sample the normal map.
  1030. //
  1031. // We take two normal samples and lerp between them for
  1032. // side projection layers... else a single sample.
  1033. LangElement *texOp;
  1034. String name(String::ToString("ormConfigMapTex%d", getProcessIndex()));
  1035. Var *ormConfigMapTex = (Var*)LangElement::find(name);
  1036. if (!ormConfigMapTex)
  1037. {
  1038. ormConfigMapTex = new Var;
  1039. ormConfigMapTex->setName(String::ToString("ormConfigMapTex%d", getProcessIndex()));
  1040. ormConfigMapTex->setType("Texture2D");
  1041. ormConfigMapTex->uniform = true;
  1042. ormConfigMapTex->texture = true;
  1043. ormConfigMapTex->constNum = ormConfigMap->constNum;
  1044. }
  1045. if (fd.features.hasFeature(MFT_TerrainSideProject, compositeIndex))
  1046. {
  1047. texOp = new GenOp("lerp( @.Sample( @, @.yz ), @.Sample( @, @.xz ), @.z )",
  1048. ormConfigMapTex, ormConfigMap, inDet, ormConfigMapTex, ormConfigMap, inDet, inTex);
  1049. }
  1050. else
  1051. texOp = new GenOp("@.Sample(@, @.xy)", ormConfigMapTex, ormConfigMap, inDet);
  1052. // search for material var
  1053. Var * ormConfig;
  1054. OutputTarget targ = DefaultTarget;
  1055. if (fd.features[MFT_isDeferred])
  1056. {
  1057. targ = RenderTarget2;
  1058. }
  1059. ormConfig = (Var*)LangElement::find(getOutputTargetVarName(targ));
  1060. MultiLine * meta = new MultiLine;
  1061. if (!ormConfig)
  1062. {
  1063. // create color var
  1064. ormConfig = new Var;
  1065. ormConfig->setType("fragout");
  1066. ormConfig->setName(getOutputTargetVarName(targ));
  1067. ormConfig->setStructName("OUT");
  1068. }
  1069. Var *detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", compositeIndex));
  1070. AssertFatal(detailBlend, "The detail blend is missing!");
  1071. String matinfoName(String::ToString("matinfoCol%d", compositeIndex));
  1072. Var *matinfoCol = new Var(matinfoName, "float3");
  1073. Var *priorComp = (Var*)LangElement::find(String::ToString("matinfoCol%d", compositeIndex - 1));
  1074. if (priorComp)
  1075. {
  1076. meta->addStatement(new GenOp(" @ = @.rgb*@;\r\n", new DecOp(matinfoCol), texOp, detailBlend));
  1077. meta->addStatement(new GenOp(" @.gba += @;\r\n", ormConfig, matinfoCol));
  1078. }
  1079. else
  1080. {
  1081. meta->addStatement(new GenOp(" @ = lerp(float3(1.0,1.0,0.0),@.rgb,@);\r\n", new DecOp(matinfoCol), texOp, detailBlend));
  1082. meta->addStatement(new GenOp(" @ = float4(0.0,@);\r\n", ormConfig, matinfoCol));
  1083. }
  1084. if (fd.features[MFT_InvertRoughness])
  1085. {
  1086. meta->addStatement(new GenOp(" @.b = [email protected];\r\n", ormConfig, ormConfig));
  1087. }
  1088. output = meta;
  1089. }
  1090. ShaderFeature::Resources TerrainORMMapFeatHLSL::getResources(const MaterialFeatureData &fd)
  1091. {
  1092. Resources res;
  1093. res.numTex = 1;
  1094. return res;
  1095. }
  1096. // reminder, the matinfo buffer is flags, smooth, ao, metal
  1097. U32 TerrainBlankInfoMapFeatHLSL::getOutputTargets(const MaterialFeatureData &fd) const
  1098. {
  1099. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::DefaultTarget;
  1100. }
  1101. void TerrainBlankInfoMapFeatHLSL::processPix(Vector<ShaderComponent*> &componentList,
  1102. const MaterialFeatureData &fd)
  1103. {
  1104. // search for material var
  1105. Var *material;
  1106. OutputTarget targ = DefaultTarget;
  1107. if (fd.features[MFT_isDeferred])
  1108. {
  1109. targ = RenderTarget2;
  1110. }
  1111. material = (Var*)LangElement::find(getOutputTargetVarName(targ));
  1112. MultiLine * meta = new MultiLine;
  1113. if (!material)
  1114. {
  1115. // create color var
  1116. material = new Var;
  1117. material->setType("fragout");
  1118. material->setName(getOutputTargetVarName(targ));
  1119. material->setStructName("OUT");
  1120. }
  1121. meta->addStatement(new GenOp(" @ = float4(0.0,1.0,1.0,0.0);\r\n", material));
  1122. output = meta;
  1123. }