terrFeatureGLSL.cpp 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332
  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/glsl/terrFeatureGLSL.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_glsl_shader_features_for_terrain(GFXAdapterType type)
  37. {
  38. if(type != OpenGL)
  39. return;
  40. FEATUREMGR->registerFeature( MFT_TerrainBaseMap, new TerrainBaseMapFeatGLSL );
  41. FEATUREMGR->registerFeature( MFT_TerrainParallaxMap, new NamedFeatureGLSL( "Terrain Parallax Texture" ) );
  42. FEATUREMGR->registerFeature( MFT_TerrainDetailMap, new TerrainDetailMapFeatGLSL );
  43. FEATUREMGR->registerFeature( MFT_TerrainNormalMap, new TerrainNormalMapFeatGLSL );
  44. FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatGLSL );
  45. FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatGLSL );
  46. FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureGLSL( "Terrain Side Projection" ) );
  47. FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatGLSL );
  48. FEATUREMGR->registerFeature( MFT_TerrainCompositeMap, new TerrainCompositeMapFeatGLSL );
  49. FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatGLSL );
  50. }
  51. };
  52. MODULE_BEGIN( TerrainFeatGLSL )
  53. MODULE_INIT_AFTER( ShaderGen )
  54. MODULE_INIT
  55. {
  56. SHADERGEN->getFeatureInitSignal().notify(&register_glsl_shader_features_for_terrain);
  57. }
  58. MODULE_END;
  59. TerrainFeatGLSL::TerrainFeatGLSL()
  60. : mTorqueDep(ShaderGen::smCommonShaderPath + String("/gl/torque.glsl" ))
  61. {
  62. addDependency( &mTorqueDep );
  63. }
  64. Var* TerrainFeatGLSL::_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* TerrainFeatGLSL::_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( "vec4" );
  88. }
  89. return inDet;
  90. }
  91. Var* TerrainFeatGLSL::_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( "vec4" );
  102. }
  103. return inDet;
  104. }
  105. Var* TerrainFeatGLSL::_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( "sampler2D" );
  113. normalMap->setName( name );
  114. normalMap->uniform = true;
  115. normalMap->sampler = true;
  116. normalMap->constNum = Var::getTexUnitNum();
  117. }
  118. return normalMap;
  119. }
  120. Var* TerrainFeatGLSL::_getCompositeMapTex()
  121. {
  122. String name(String::ToString("compositeMap%d", getProcessIndex()));
  123. Var *compositeMap = (Var*)LangElement::find(name);
  124. if (!compositeMap)
  125. {
  126. compositeMap = new Var;
  127. compositeMap->setType("sampler2D");
  128. compositeMap->setName(name);
  129. compositeMap->uniform = true;
  130. compositeMap->sampler = true;
  131. compositeMap->constNum = Var::getTexUnitNum();
  132. }
  133. return compositeMap;
  134. }
  135. Var* TerrainFeatGLSL::_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( "vec3" );
  143. detailInfo->setName( name );
  144. detailInfo->uniform = true;
  145. detailInfo->constSortPos = cspPotentialPrimitive;
  146. }
  147. return detailInfo;
  148. }
  149. Var* TerrainFeatGLSL::_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( "vec3" );
  157. detailInfo->setName( name );
  158. detailInfo->uniform = true;
  159. detailInfo->constSortPos = cspPotentialPrimitive;
  160. }
  161. return detailInfo;
  162. }
  163. void TerrainBaseMapFeatGLSL::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", "vec3" );
  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 * vec3( @, @, -@ );\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( "vec3" );
  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( vec3( @.x, @.y, 0 ) ), vec3( 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", "vec3" );
  217. Var *squareSize = _getUniformVar( "squareSize", "float", cspPass );
  218. meta->addStatement( new GenOp( " @ = normalize( vec3( @, 0, @ ) );\r\n",
  219. new DecOp( inTanget ), squareSize, inTangentZ ) );
  220. }
  221. void TerrainBaseMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  222. const MaterialFeatureData &fd )
  223. {
  224. // grab connector texcoord register
  225. Var *texCoord = getInTexCoord( "texCoord", "vec3", componentList );
  226. // create texture var
  227. Var *diffuseMap = new Var;
  228. diffuseMap->setType( "sampler2D" );
  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( "vec4" );
  236. baseColor->setName( "baseColor" );
  237. meta->addStatement( new GenOp( " @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
  238. ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
  239. if(fd.features.hasFeature(MFT_isDeferred))
  240. {
  241. target= ShaderFeature::RenderTarget1;
  242. }
  243. meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul,NULL,target ) ) );
  244. output = meta;
  245. }
  246. ShaderFeature::Resources TerrainBaseMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  247. {
  248. Resources res;
  249. res.numTexReg = 1;
  250. res.numTex = 1;
  251. return res;
  252. }
  253. U32 TerrainBaseMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
  254. {
  255. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
  256. }
  257. TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL()
  258. : mTorqueDep(ShaderGen::smCommonShaderPath + String("/gl/torque.glsl" )),
  259. mTerrainDep(ShaderGen::smCommonShaderPath + String("/terrain/terrain.glsl" ))
  260. {
  261. addDependency( &mTorqueDep );
  262. addDependency( &mTerrainDep );
  263. }
  264. void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  265. const MaterialFeatureData &fd )
  266. {
  267. const S32 detailIndex = getProcessIndex();
  268. // Grab incoming texture coords... the base map feature
  269. // made sure this was created.
  270. Var *inTex = (Var*)LangElement::find( "texCoord" );
  271. AssertFatal( inTex, "The texture coord is missing!" );
  272. // Grab the input position.
  273. Var *inPos = (Var*)LangElement::find( "inPosition" );
  274. if ( !inPos )
  275. inPos = (Var*)LangElement::find( "position" );
  276. // Get the object space eye position.
  277. Var *eyePos = _getUniformVar( "eyePos", "vec3", cspPotentialPrimitive );
  278. MultiLine *meta = new MultiLine;
  279. // If we have parallax mapping then make sure we've sent
  280. // the negative view vector to the pixel shader.
  281. if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
  282. !LangElement::find( "outNegViewTS" ) )
  283. {
  284. // Get the object to tangent transform which
  285. // will consume 3 output registers.
  286. Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta, fd );
  287. // Now use a single output register to send the negative
  288. // view vector in tangent space to the pixel shader.
  289. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  290. Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD );
  291. outNegViewTS->setName( "outNegViewTS" );
  292. outNegViewTS->setStructName( "OUT" );
  293. outNegViewTS->setType( "vec3" );
  294. meta->addStatement( new GenOp( " @ = tMul( @, vec3( @ - @.xyz ) );\r\n",
  295. outNegViewTS, objToTangentSpace, eyePos, inPos ) );
  296. }
  297. // Get the distance from the eye to this vertex.
  298. Var *dist = (Var*)LangElement::find( "dist" );
  299. if ( !dist )
  300. {
  301. dist = new Var;
  302. dist->setType( "float" );
  303. dist->setName( "dist" );
  304. meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n",
  305. new DecOp( dist ), inPos, eyePos ) );
  306. }
  307. // grab connector texcoord register
  308. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  309. Var *outTex = connectComp->getElement( RT_TEXCOORD );
  310. outTex->setName( String::ToString( "detCoord%d", detailIndex ) );
  311. outTex->setStructName( "OUT" );
  312. outTex->setType( "vec4" );
  313. // Get the detail scale and fade info.
  314. Var *detScaleAndFade = new Var;
  315. detScaleAndFade->setType( "vec4" );
  316. detScaleAndFade->setName( String::ToString( "detailScaleAndFade%d", detailIndex ) );
  317. detScaleAndFade->uniform = true;
  318. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  319. // Setup the detail coord.
  320. //
  321. // NOTE: You see here we scale the texture coord by 'xyx'
  322. // to generate the detail coord. This y is here because
  323. // its scale is flipped to correct for the non negative y
  324. // in texCoord.
  325. //
  326. // See TerrainBaseMapFeatGLSL::processVert().
  327. //
  328. meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) );
  329. // And sneak the detail fade thru the w detailCoord.
  330. meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  331. outTex, detScaleAndFade, dist, detScaleAndFade ) );
  332. output = meta;
  333. }
  334. void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  335. const MaterialFeatureData &fd )
  336. {
  337. const S32 detailIndex = getProcessIndex();
  338. Var *inTex = getVertTexCoord( "texCoord" );
  339. MultiLine *meta = new MultiLine;
  340. // We need the negative tangent space view vector
  341. // as in parallax mapping we step towards the camera.
  342. Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
  343. if ( !negViewTS &&
  344. fd.features.hasFeature( MFT_TerrainParallaxMap ) )
  345. {
  346. Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
  347. if ( !inNegViewTS )
  348. {
  349. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  350. inNegViewTS = connectComp->getElement( RT_TEXCOORD );
  351. inNegViewTS->setName( "outNegViewTS" );
  352. inNegViewTS->setStructName( "IN" );
  353. inNegViewTS->setType( "vec3" );
  354. }
  355. negViewTS = new Var( "negViewTS", "vec3" );
  356. meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
  357. }
  358. // Get the layer samples.
  359. Var *layerSample = (Var*)LangElement::find( "layerSample" );
  360. if ( !layerSample )
  361. {
  362. layerSample = new Var;
  363. layerSample->setType( "vec4" );
  364. layerSample->setName( "layerSample" );
  365. // Get the layer texture var
  366. Var *layerTex = new Var;
  367. layerTex->setType( "sampler2D" );
  368. layerTex->setName( "layerTex" );
  369. layerTex->uniform = true;
  370. layerTex->sampler = true;
  371. layerTex->constNum = Var::getTexUnitNum();
  372. // Read the layer texture to get the samples.
  373. meta->addStatement( new GenOp( " @ = round( tex2D( @, @.xy ) * 255.0f );\r\n",
  374. new DecOp( layerSample ), layerTex, inTex ) );
  375. }
  376. Var *layerSize = (Var*)LangElement::find( "layerSize" );
  377. if ( !layerSize )
  378. {
  379. layerSize = new Var;
  380. layerSize->setType( "float" );
  381. layerSize->setName( "layerSize" );
  382. layerSize->uniform = true;
  383. layerSize->constSortPos = cspPass;
  384. }
  385. // Grab the incoming detail coord.
  386. Var *inDet = _getInDetailCoord( componentList );
  387. // Get the detail id.
  388. Var *detailInfo = _getDetailIdStrengthParallax();
  389. // Create the detail blend var.
  390. Var *detailBlend = new Var;
  391. detailBlend->setType( "float" );
  392. detailBlend->setName( String::ToString( "detailBlend%d", detailIndex ) );
  393. // Calculate the blend for this detail texture.
  394. meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
  395. new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
  396. // New terrain
  397. Var *lerpBlend = (Var*)LangElement::find("lerpBlend");
  398. if (!lerpBlend)
  399. {
  400. lerpBlend = new Var;
  401. lerpBlend->setType("float");
  402. lerpBlend->setName("lerpBlend");
  403. lerpBlend->uniform = true;
  404. lerpBlend->constSortPos = cspPrimitive;
  405. }
  406. Var *blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", detailIndex));
  407. if (!blendDepth)
  408. {
  409. blendDepth = new Var;
  410. blendDepth->setType("float");
  411. blendDepth->setName(String::ToString("blendDepth%d", detailIndex));
  412. blendDepth->uniform = true;
  413. blendDepth->constSortPos = cspPrimitive;
  414. }
  415. ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
  416. if (fd.features.hasFeature(MFT_isDeferred))
  417. target= ShaderFeature::RenderTarget1;
  418. Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
  419. if (!outColor)
  420. {
  421. // create color var
  422. outColor = new Var;
  423. outColor->setType("vec4");
  424. outColor->setName("col");
  425. outColor->setStructName("OUT");
  426. meta->addStatement(new GenOp(" @;\r\n", outColor));
  427. }
  428. Var *detailColor = (Var*)LangElement::find("detailColor");
  429. if (!detailColor)
  430. {
  431. detailColor = new Var;
  432. detailColor->setType("vec4");
  433. detailColor->setName("detailColor");
  434. meta->addStatement(new GenOp(" @;\r\n", new DecOp(detailColor)));
  435. }
  436. // Get the detail texture.
  437. Var *detailMap = new Var;
  438. detailMap->setType("sampler2D");
  439. detailMap->setName(String::ToString("detailMap%d", detailIndex));
  440. detailMap->uniform = true;
  441. detailMap->sampler = true;
  442. detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
  443. // Get the normal map texture.
  444. Var *normalMap = _getNormalMapTex();
  445. // Issue happens somewhere here -----
  446. // Sample the normal map.
  447. //
  448. // We take two normal samples and lerp between them for
  449. // side projection layers... else a single sample.
  450. LangElement *texOp;
  451. // Note that we're doing the standard greyscale detail
  452. // map technique here which can darken and lighten the
  453. // diffuse texture.
  454. //
  455. // We take two color samples and lerp between them for
  456. // side projection layers... else a single sample.
  457. //
  458. if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
  459. {
  460. meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
  461. detailColor, detailMap, inDet, detailMap, inDet, inTex));
  462. texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
  463. normalMap, inDet, normalMap, inDet, inTex);
  464. }
  465. else
  466. {
  467. meta->addStatement(new GenOp(" @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
  468. detailColor, detailMap, inDet));
  469. texOp = new GenOp("tex2D(@, @.xy)", normalMap, inDet);
  470. }
  471. // New terrain
  472. // Get a var and accumulate the blend amount.
  473. Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
  474. if ( !blendTotal )
  475. {
  476. blendTotal = new Var;
  477. blendTotal->setName( "blendTotal" );
  478. blendTotal->setType( "float" );
  479. meta->addStatement( new GenOp( " @ = 0;\r\n", new DecOp( blendTotal ) ) );
  480. }
  481. // Add to the blend total.
  482. meta->addStatement(new GenOp(" @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend));
  483. // If we had a parallax feature... then factor in the parallax
  484. // amount so that it fades out with the layer blending.
  485. if ( fd.features.hasFeature( MFT_TerrainParallaxMap, detailIndex ) )
  486. {
  487. // Call the library function to do the rest.
  488. if (fd.features.hasFeature(MFT_IsBC3nm, detailIndex))
  489. {
  490. meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n",
  491. inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend));
  492. }
  493. else
  494. {
  495. meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n",
  496. inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend));
  497. }
  498. }
  499. // Check to see if we have a gbuffer normal.
  500. Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
  501. // If we have a gbuffer normal and we don't have a
  502. // normal map feature then we need to lerp in a
  503. // default normal else the normals below this layer
  504. // will show thru.
  505. if (gbNormal &&
  506. !fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex))
  507. {
  508. Var *viewToTangent = getInViewToTangent(componentList);
  509. meta->addStatement(new GenOp(" @ = lerp( @, @[2], min( @, @.w ) );\r\n",
  510. gbNormal, gbNormal, viewToTangent, detailBlend, inDet));
  511. }
  512. // If we're using SM 3.0 then take advantage of
  513. // dynamic branching to skip layers per-pixel.
  514. if ( GFX->getPixelShaderVersion() >= 3.0f )
  515. meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
  516. meta->addStatement( new GenOp( " {\r\n" ) );
  517. // Note that we're doing the standard greyscale detail
  518. // map technique here which can darken and lighten the
  519. // diffuse texture.
  520. //
  521. // We take two color samples and lerp between them for
  522. // side projection layers... else a single sample.
  523. //
  524. if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
  525. {
  526. meta->addStatement( new GenOp( " @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
  527. detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
  528. }
  529. else
  530. {
  531. meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
  532. detailColor, detailMap, inDet ) );
  533. }
  534. meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
  535. detailColor, detailInfo, inDet ) );
  536. meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n", outColor, outColor));
  537. meta->addStatement(new GenOp(" @ += @ * @;\r\n",
  538. outColor, detailColor, detailBlend));
  539. meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n", outColor, outColor));
  540. meta->addStatement( new GenOp( " }\r\n" ) );
  541. output = meta;
  542. }
  543. ShaderFeature::Resources TerrainDetailMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  544. {
  545. Resources res;
  546. if ( getProcessIndex() == 0 )
  547. {
  548. // If this is the first detail pass then we
  549. // samples from the layer tex.
  550. res.numTex += 1;
  551. // If this material also does parallax then it
  552. // will generate the negative view vector and the
  553. // worldToTanget transform.
  554. if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) )
  555. res.numTexReg += 4;
  556. }
  557. // sample from the detail texture for diffuse coloring.
  558. res.numTex += 1;
  559. // If we have parallax for this layer then we'll also
  560. // be sampling the normal map for the parallax heightmap.
  561. if ( fd.features.hasFeature( MFT_TerrainParallaxMap, getProcessIndex() ) )
  562. res.numTex += 1;
  563. // Finally we always send the detail texture
  564. // coord to the pixel shader.
  565. res.numTexReg += 1;
  566. return res;
  567. }
  568. U32 TerrainDetailMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
  569. {
  570. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
  571. }
  572. TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL()
  573. : mTorqueDep(ShaderGen::smCommonShaderPath + String("/gl/torque.glsl" )),
  574. mTerrainDep(ShaderGen::smCommonShaderPath + String("/terrain/terrain.glsl" ))
  575. {
  576. addDependency( &mTorqueDep );
  577. addDependency( &mTerrainDep );
  578. }
  579. void TerrainMacroMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  580. const MaterialFeatureData &fd )
  581. {
  582. const S32 detailIndex = getProcessIndex();
  583. // Grab incoming texture coords... the base map feature
  584. // made sure this was created.
  585. Var *inTex = (Var*)LangElement::find( "texCoord" );
  586. AssertFatal( inTex, "The texture coord is missing!" );
  587. // Grab the input position.
  588. Var *inPos = (Var*)LangElement::find( "inPosition" );
  589. if ( !inPos )
  590. inPos = (Var*)LangElement::find( "position" );
  591. // Get the object space eye position.
  592. Var *eyePos = _getUniformVar( "eyePos", "vec3", cspPotentialPrimitive );
  593. MultiLine *meta = new MultiLine;
  594. // Get the distance from the eye to this vertex.
  595. Var *dist = (Var*)LangElement::find( "macroDist" );
  596. if ( !dist )
  597. {
  598. dist = new Var;
  599. dist->setType( "float" );
  600. dist->setName( "macroDist" );
  601. meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n",
  602. new DecOp( dist ), inPos, eyePos ) );
  603. }
  604. // grab connector texcoord register
  605. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  606. Var *outTex = connectComp->getElement( RT_TEXCOORD );
  607. outTex->setName( String::ToString( "macroCoord%d", detailIndex ) );
  608. outTex->setStructName( "OUT" );
  609. outTex->setType( "vec4" );
  610. // Get the detail scale and fade info.
  611. Var *detScaleAndFade = new Var;
  612. detScaleAndFade->setType( "vec4" );
  613. detScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) );
  614. detScaleAndFade->uniform = true;
  615. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  616. // Setup the detail coord.
  617. meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) );
  618. // And sneak the detail fade thru the w detailCoord.
  619. meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  620. outTex, detScaleAndFade, dist, detScaleAndFade ) );
  621. output = meta;
  622. }
  623. void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  624. const MaterialFeatureData &fd )
  625. {
  626. const S32 detailIndex = getProcessIndex();
  627. Var *inTex = getVertTexCoord( "texCoord" );
  628. MultiLine *meta = new MultiLine;
  629. // We need the negative tangent space view vector
  630. // as in parallax mapping we step towards the camera.
  631. Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
  632. if ( !negViewTS &&
  633. fd.features.hasFeature( MFT_TerrainParallaxMap ) )
  634. {
  635. Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
  636. if ( !inNegViewTS )
  637. {
  638. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  639. inNegViewTS = connectComp->getElement( RT_TEXCOORD );
  640. inNegViewTS->setName( "outNegViewTS" );
  641. inNegViewTS->setStructName( "IN" );
  642. inNegViewTS->setType( "vec3" );
  643. }
  644. negViewTS = new Var( "negViewTS", "vec3" );
  645. meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
  646. }
  647. // Get the layer samples.
  648. Var *layerSample = (Var*)LangElement::find( "layerSample" );
  649. if ( !layerSample )
  650. {
  651. layerSample = new Var;
  652. layerSample->setType( "vec4" );
  653. layerSample->setName( "layerSample" );
  654. // Get the layer texture var
  655. Var *layerTex = new Var;
  656. layerTex->setType( "sampler2D" );
  657. layerTex->setName( "macrolayerTex" );
  658. layerTex->uniform = true;
  659. layerTex->sampler = true;
  660. layerTex->constNum = Var::getTexUnitNum();
  661. // Read the layer texture to get the samples.
  662. meta->addStatement( new GenOp( " @ = round( tex2D( @, @.xy ) * 255.0f );\r\n",
  663. new DecOp( layerSample ), layerTex, inTex ) );
  664. }
  665. Var *layerSize = (Var*)LangElement::find( "layerSize" );
  666. if ( !layerSize )
  667. {
  668. layerSize = new Var;
  669. layerSize->setType( "float" );
  670. layerSize->setName( "layerSize" );
  671. layerSize->uniform = true;
  672. layerSize->constSortPos = cspPass;
  673. }
  674. // Grab the incoming detail coord.
  675. Var *inDet = _getInMacroCoord( componentList );
  676. // Get the detail id.
  677. Var *detailInfo = _getMacroIdStrengthParallax();
  678. // Create the detail blend var.
  679. Var *detailBlend = new Var;
  680. detailBlend->setType( "float" );
  681. detailBlend->setName( String::ToString( "macroBlend%d", detailIndex ) );
  682. // Calculate the blend for this detail texture.
  683. meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
  684. new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
  685. // Get a var and accumulate the blend amount.
  686. Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
  687. if ( !blendTotal )
  688. {
  689. blendTotal = new Var;
  690. //blendTotal->setName( "blendTotal" );
  691. blendTotal->setName( "blendTotal" );
  692. blendTotal->setType( "float" );
  693. meta->addStatement( new GenOp( " @ = 0;\r\n", new DecOp( blendTotal ) ) );
  694. }
  695. // Add to the blend total.
  696. meta->addStatement(new GenOp(" @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend));
  697. Var *detailColor = (Var*)LangElement::find( "macroColor" );
  698. if ( !detailColor )
  699. {
  700. detailColor = new Var;
  701. detailColor->setType( "vec4" );
  702. detailColor->setName( "macroColor" );
  703. meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
  704. }
  705. // Get the detail texture.
  706. Var *detailMap = new Var;
  707. detailMap->setType( "sampler2D" );
  708. detailMap->setName( String::ToString( "macroMap%d", detailIndex ) );
  709. detailMap->uniform = true;
  710. detailMap->sampler = true;
  711. detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
  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( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
  727. detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
  728. }
  729. else
  730. {
  731. meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
  732. detailColor, 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 TerrainMacroMapFeatGLSL::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 TerrainMacroMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
  763. {
  764. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
  765. }
  766. void TerrainNormalMapFeatGLSL::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 TerrainNormalMapFeatGLSL::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 GBufferConditionerGLSL 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( "vec3" );
  794. meta->addStatement( new GenOp( " @ = tGetMatrix3Row(@, 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. if ( fd.features.hasFeature( MFT_TerrainSideProject, normalIndex ) )
  815. {
  816. texOp = new GenOp( "lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
  817. normalMap, inDet, normalMap, inDet, inTex );
  818. }
  819. else
  820. texOp = new GenOp( "tex2D(@, @.xy)", normalMap, inDet );
  821. // create bump normal
  822. Var *bumpNorm = new Var;
  823. bumpNorm->setName( "bumpNormal" );
  824. bumpNorm->setType( "vec4" );
  825. LangElement *bumpNormDecl = new DecOp( bumpNorm );
  826. meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
  827. // Normalize is done later...
  828. // Note: The reverse mul order is intentional. Affine matrix.
  829. meta->addStatement( new GenOp( " @ = lerp( @, tMul( @.xyz, @ ), min( @, @.w ) );\r\n",
  830. gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet ) );
  831. // End the conditional block.
  832. meta->addStatement( new GenOp( " }\r\n" ) );
  833. // If this is the last normal map then we
  834. // can test to see the total blend value
  835. // to see if we should clip the result.
  836. //if ( fd.features.getNextFeatureIndex( MFT_TerrainNormalMap, normalIndex ) == -1 )
  837. //meta->addStatement( new GenOp( " clip( @ - 0.0001f );\r\n", blendTotal ) );
  838. output = meta;
  839. }
  840. ShaderFeature::Resources TerrainNormalMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  841. {
  842. Resources res;
  843. // We only need to process normals during the deferred.
  844. if ( fd.features.hasFeature( MFT_DeferredConditioner ) )
  845. {
  846. // If this is the first normal map and there
  847. // are no parallax features then we will
  848. // generate the worldToTanget transform.
  849. if ( !fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
  850. ( getProcessIndex() == 0 || !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() - 1 ) ) )
  851. res.numTexReg = 3;
  852. res.numTex = 1;
  853. }
  854. return res;
  855. }
  856. void TerrainLightMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  857. const MaterialFeatureData &fd )
  858. {
  859. // grab connector texcoord register
  860. Var *inTex = (Var*)LangElement::find( "texCoord" );
  861. if ( !inTex )
  862. return;
  863. // Get the lightmap texture.
  864. Var *lightMap = new Var;
  865. lightMap->setType( "sampler2D" );
  866. lightMap->setName( "lightMapTex" );
  867. lightMap->uniform = true;
  868. lightMap->sampler = true;
  869. lightMap->constNum = Var::getTexUnitNum();
  870. MultiLine *meta = new MultiLine;
  871. // Find or create the lightMask value which is read by
  872. // RTLighting to mask out the lights.
  873. //
  874. // The first light is always the sunlight so we apply
  875. // the shadow mask to only the first channel.
  876. //
  877. Var *lightMask = (Var*)LangElement::find( "lightMask" );
  878. if ( !lightMask )
  879. {
  880. lightMask = new Var( "lightMask", "vec4" );
  881. meta->addStatement( new GenOp( " @ = vec4(1);\r\n", new DecOp( lightMask ) ) );
  882. }
  883. meta->addStatement( new GenOp( " @[0] = tex2D( @, @.xy ).r;\r\n", lightMask, lightMap, inTex ) );
  884. output = meta;
  885. }
  886. ShaderFeature::Resources TerrainLightMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  887. {
  888. Resources res;
  889. res.numTex = 1;
  890. return res;
  891. }
  892. void TerrainAdditiveFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  893. const MaterialFeatureData &fd )
  894. {
  895. Var *color = NULL;
  896. if (fd.features[MFT_isDeferred])
  897. {
  898. color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
  899. }
  900. else
  901. color = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
  902. Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
  903. if ( !color || !blendTotal )
  904. return;
  905. MultiLine *meta = new MultiLine;
  906. meta->addStatement( new GenOp( " clip( @ - 0.0001 );\r\n", blendTotal ) );
  907. meta->addStatement( new GenOp( " @.a = @;\r\n", color, blendTotal ) );
  908. output = meta;
  909. }
  910. //standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO),
  911. //.b = specular strength, a= spec power.
  912. void TerrainCompositeMapFeatGLSL::processVert(Vector<ShaderComponent*> &componentList,
  913. const MaterialFeatureData &fd)
  914. {
  915. const S32 detailIndex = getProcessIndex();
  916. // Grab incoming texture coords... the base map feature
  917. // made sure this was created.
  918. Var *inTex = (Var*)LangElement::find("texCoord");
  919. AssertFatal(inTex, "The texture coord is missing!");
  920. // Grab the input position.
  921. Var *inPos = (Var*)LangElement::find("inPosition");
  922. if (!inPos)
  923. inPos = (Var*)LangElement::find("position");
  924. // Get the object space eye position.
  925. Var *eyePos = _getUniformVar("eyePos", "vec3", cspPotentialPrimitive);
  926. MultiLine *meta = new MultiLine;
  927. // If we have parallax mapping then make sure we've sent
  928. // the negative view vector to the pixel shader.
  929. if (fd.features.hasFeature(MFT_TerrainParallaxMap) &&
  930. !LangElement::find("outNegViewTS"))
  931. {
  932. // Get the object to tangent transform which
  933. // will consume 3 output registers.
  934. Var *objToTangentSpace = getOutObjToTangentSpace(componentList, meta, fd);
  935. // Now use a single output register to send the negative
  936. // view vector in tangent space to the pixel shader.
  937. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
  938. Var *outNegViewTS = connectComp->getElement(RT_TEXCOORD);
  939. outNegViewTS->setName("outNegViewTS");
  940. outNegViewTS->setStructName("OUT");
  941. outNegViewTS->setType("vec3");
  942. meta->addStatement(new GenOp(" @ = @ * vec3( @ - @.xyz );\r\n",
  943. outNegViewTS, objToTangentSpace, eyePos, inPos));
  944. }
  945. // Get the distance from the eye to this vertex.
  946. Var *dist = (Var*)LangElement::find("dist");
  947. if (!dist)
  948. {
  949. dist = new Var;
  950. dist->setType("float");
  951. dist->setName("dist");
  952. meta->addStatement(new GenOp(" @ = distance( @.xyz, @ );\r\n",
  953. new DecOp(dist), inPos, eyePos));
  954. }
  955. // grab connector texcoord register
  956. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
  957. Var *outTex = (Var*)LangElement::find(String::ToString("detCoord%d", detailIndex));
  958. if (outTex == NULL)
  959. {
  960. outTex = connectComp->getElement(RT_TEXCOORD);
  961. outTex->setName(String::ToString("detCoord%d", detailIndex));
  962. outTex->setStructName("OUT");
  963. outTex->setType("vec4");
  964. }
  965. // Get the detail scale and fade info.
  966. Var *detScaleAndFade = (Var*)LangElement::find(String::ToString("detailScaleAndFade%d", detailIndex));
  967. if (detScaleAndFade == NULL)
  968. {
  969. detScaleAndFade->setType("vec4");
  970. detScaleAndFade->setName(String::ToString("detailScaleAndFade%d", detailIndex));
  971. detScaleAndFade->uniform = true;
  972. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  973. }
  974. // Setup the detail coord.
  975. //
  976. // NOTE: You see here we scale the texture coord by 'xyx'
  977. // to generate the detail coord. This y is here because
  978. // its scale is flipped to correct for the non negative y
  979. // in texCoord.
  980. //
  981. // See TerrainBaseMapFeatGLSL::processVert().
  982. //
  983. meta->addStatement(new GenOp(" @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade));
  984. // And sneak the detail fade thru the w detailCoord.
  985. meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  986. outTex, detScaleAndFade, dist, detScaleAndFade));
  987. output = meta;
  988. }
  989. U32 TerrainCompositeMapFeatGLSL::getOutputTargets(const MaterialFeatureData &fd) const
  990. {
  991. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
  992. }
  993. void TerrainCompositeMapFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
  994. const MaterialFeatureData &fd)
  995. {
  996. /// Get the texture coord.
  997. Var *inDet = _getInDetailCoord(componentList);
  998. Var *inTex = getVertTexCoord("texCoord");
  999. const S32 compositeIndex = getProcessIndex();
  1000. Var *compositeMap = _getCompositeMapTex();
  1001. // Sample the normal map.
  1002. //
  1003. // We take two normal samples and lerp between them for
  1004. // side projection layers... else a single sample.
  1005. LangElement *texOp;
  1006. if (fd.features.hasFeature(MFT_TerrainSideProject, compositeIndex))
  1007. {
  1008. texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
  1009. compositeMap, inDet, compositeMap, inDet, inTex);
  1010. }
  1011. else
  1012. texOp = new GenOp("tex2D(@, @.xy)", compositeMap, inDet);
  1013. // search for material var
  1014. Var * pbrConfig;
  1015. OutputTarget targ = RenderTarget1;
  1016. if (fd.features[MFT_isDeferred])
  1017. {
  1018. targ = RenderTarget2;
  1019. }
  1020. pbrConfig = (Var*)LangElement::find(getOutputTargetVarName(targ));
  1021. MultiLine * meta = new MultiLine;
  1022. if (!pbrConfig)
  1023. {
  1024. // create color var
  1025. pbrConfig = new Var;
  1026. pbrConfig->setType("fragout");
  1027. pbrConfig->setName(getOutputTargetVarName(targ));
  1028. pbrConfig->setStructName("OUT");
  1029. }
  1030. Var *detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", compositeIndex));
  1031. AssertFatal(detailBlend, "The detail blend is missing!");
  1032. String matinfoName(String::ToString("matinfoCol%d", compositeIndex));
  1033. Var *matinfoCol = new Var(matinfoName, "vec3");
  1034. Var *priorComp = (Var*)LangElement::find(String::ToString("matinfoCol%d", compositeIndex - 1));
  1035. if (priorComp)
  1036. {
  1037. meta->addStatement(new GenOp(" @ = @.rgb*@;\r\n", new DecOp(matinfoCol), texOp, detailBlend));
  1038. meta->addStatement(new GenOp(" @.bga += @;\r\n", pbrConfig, matinfoCol));
  1039. }
  1040. else
  1041. {
  1042. meta->addStatement(new GenOp(" @ = lerp(vec3(0,1,0),@.rgb,@);\r\n", new DecOp(matinfoCol), texOp, detailBlend));
  1043. meta->addStatement(new GenOp(" @ = vec4(0.0,@);\r\n", pbrConfig, matinfoCol));
  1044. }
  1045. if (!fd.features[MFT_InvertSmoothness])
  1046. {
  1047. meta->addStatement(new GenOp(" @.b = [email protected];\r\n", pbrConfig, pbrConfig));
  1048. }
  1049. output = meta;
  1050. }
  1051. ShaderFeature::Resources TerrainCompositeMapFeatGLSL::getResources(const MaterialFeatureData &fd)
  1052. {
  1053. Resources res;
  1054. res.numTex = 1;
  1055. res.numTexReg += 1;
  1056. return res;
  1057. }
  1058. U32 TerrainBlankInfoMapFeatGLSL::getOutputTargets(const MaterialFeatureData &fd) const
  1059. {
  1060. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
  1061. }
  1062. // reminder, the matinfo buffer is flags, smooth, ao, metal
  1063. void TerrainBlankInfoMapFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
  1064. const MaterialFeatureData &fd)
  1065. {
  1066. // search for material var
  1067. Var *material;
  1068. OutputTarget targ = RenderTarget1;
  1069. if (fd.features[MFT_isDeferred])
  1070. {
  1071. targ = RenderTarget2;
  1072. }
  1073. material = (Var*)LangElement::find(getOutputTargetVarName(targ));
  1074. MultiLine * meta = new MultiLine;
  1075. if (!material)
  1076. {
  1077. // create color var
  1078. material = new Var;
  1079. material->setType("vec4");
  1080. material->setName(getOutputTargetVarName(targ));
  1081. material->setStructName("OUT");
  1082. }
  1083. meta->addStatement(new GenOp(" @ = vec4(0.0,0.0,1.0,0);\r\n", material));
  1084. output = meta;
  1085. }