terrFeatureGLSL.cpp 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643
  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 NamedFeatureGLSL("TerrainMacroMap Deprecated")); // new TerrainMacroMapFeatGLSL);
  45. FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatGLSL );
  46. FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureGLSL( "Terrain Side Projection" ) );
  47. FEATUREMGR->registerFeature(MFT_TerrainHeightBlend, new TerrainHeightMapBlendGLSL);
  48. FEATUREMGR->registerFeature( MFT_TerrainORMMap, new TerrainORMMapFeatGLSL );
  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::_getDetailMapSampler()
  106. {
  107. String name("detailMapSampler");
  108. Var* detailMapSampler = (Var*)LangElement::find(name);
  109. if (!detailMapSampler)
  110. {
  111. detailMapSampler = new Var;
  112. detailMapSampler->setName(name);
  113. detailMapSampler->setType("sampler2DArray");
  114. detailMapSampler->uniform = true;
  115. detailMapSampler->sampler = true;
  116. detailMapSampler->constNum = Var::getTexUnitNum();
  117. }
  118. return detailMapSampler;
  119. }
  120. Var* TerrainFeatGLSL::_getNormalMapSampler()
  121. {
  122. String name("normalMapSampler");
  123. Var* normalMapSampler = (Var*)LangElement::find(name);
  124. if (!normalMapSampler)
  125. {
  126. normalMapSampler = new Var;
  127. normalMapSampler->setName(name);
  128. normalMapSampler->setType("sampler2DArray");
  129. normalMapSampler->uniform = true;
  130. normalMapSampler->sampler = true;
  131. normalMapSampler->constNum = Var::getTexUnitNum();
  132. }
  133. return normalMapSampler;
  134. }
  135. Var* TerrainFeatGLSL::_getOrmMapSampler()
  136. {
  137. String name("ormMapSampler");
  138. Var* ormMapSampler = (Var*)LangElement::find(name);
  139. if (!ormMapSampler)
  140. {
  141. ormMapSampler = new Var;
  142. ormMapSampler->setName(name);
  143. ormMapSampler->setType("sampler2DArray");
  144. ormMapSampler->uniform = true;
  145. ormMapSampler->sampler = true;
  146. ormMapSampler->constNum = Var::getTexUnitNum();
  147. }
  148. return ormMapSampler;
  149. }
  150. Var* TerrainFeatGLSL::_getDetailIdStrengthParallax()
  151. {
  152. String name(String::ToString("detailIdStrengthParallax", getProcessIndex()));
  153. Var* detailInfo = (Var*)LangElement::find(name);
  154. if (!detailInfo)
  155. {
  156. detailInfo = new Var;
  157. detailInfo->setType("vec4");
  158. detailInfo->setName(name);
  159. detailInfo->uniform = true;
  160. detailInfo->constSortPos = cspPotentialPrimitive;
  161. detailInfo->arraySize = getProcessIndex();
  162. }
  163. detailInfo->arraySize = mMax(detailInfo->arraySize, getProcessIndex() + 1);
  164. return detailInfo;
  165. }
  166. Var* TerrainFeatGLSL::_getMacroIdStrengthParallax()
  167. {
  168. String name(String::ToString("macroIdStrengthParallax%d", getProcessIndex()));
  169. Var* detailInfo = (Var*)LangElement::find(name);
  170. if (!detailInfo)
  171. {
  172. detailInfo = new Var;
  173. detailInfo->setType("vec3");
  174. detailInfo->setName(name);
  175. detailInfo->uniform = true;
  176. detailInfo->constSortPos = cspPotentialPrimitive;
  177. }
  178. return detailInfo;
  179. }
  180. void TerrainBaseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  181. const MaterialFeatureData &fd )
  182. {
  183. MultiLine *meta = new MultiLine;
  184. output = meta;
  185. // Generate the incoming texture var.
  186. Var *inTex;
  187. {
  188. Var *inPos = (Var*)LangElement::find( "inPosition" );
  189. if ( !inPos )
  190. inPos = (Var*)LangElement::find( "position" );
  191. inTex = new Var( "texCoord", "vec3" );
  192. Var *oneOverTerrainSize = _getUniformVar( "oneOverTerrainSize", "float", cspPass );
  193. // NOTE: The y coord here should be negative to have
  194. // the texture maps not end up flipped which also caused
  195. // normal and parallax mapping to be incorrect.
  196. //
  197. // This mistake early in development means that the layer
  198. // id bilinear blend depends on it being that way.
  199. //
  200. // So instead i fixed this by flipping the base and detail
  201. // coord y scale to compensate when rendering.
  202. //
  203. meta->addStatement( new GenOp( " @ = @.xyz * vec3( @, @, -@ );\r\n",
  204. new DecOp( inTex ), inPos, oneOverTerrainSize, oneOverTerrainSize, oneOverTerrainSize ) );
  205. }
  206. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  207. // Pass the texture coord to the pixel shader.
  208. Var *outTex = connectComp->getElement( RT_TEXCOORD );
  209. outTex->setName( "outTexCoord" );
  210. outTex->setStructName( "OUT" );
  211. outTex->setType( "vec3" );
  212. meta->addStatement( new GenOp( " @.xy = @.xy;\r\n", outTex, inTex ) );
  213. // If this shader has a side projected layer then we
  214. // pass the dot product between the +Y and the normal
  215. // thru outTexCoord.z for use in blending the textures.
  216. if ( fd.features.hasFeature( MFT_TerrainSideProject ) )
  217. {
  218. Var *inNormal = (Var*)LangElement::find( "normal" );
  219. meta->addStatement(
  220. new GenOp( " @.z = pow( abs( dot( normalize( vec3( @.x, @.y, 0 ) ), vec3( 0, 1, 0 ) ) ), 10.0 );\r\n",
  221. outTex, inNormal, inNormal ) );
  222. }
  223. else
  224. meta->addStatement( new GenOp( " @.z = 0;\r\n", outTex ) );
  225. // HACK: This is sort of lazy... we generate the tanget
  226. // vector here so that we're sure it exists in the parallax
  227. // and normal features which will expect "T" to exist.
  228. //
  229. // If this shader doesn't use it the shader compiler will
  230. // optimize away this code.
  231. //
  232. Var *inTangentZ = getVertTexCoord( "tcTangentZ" );
  233. Var *inTanget = new Var( "T", "vec3" );
  234. Var *squareSize = _getUniformVar( "squareSize", "float", cspPass );
  235. meta->addStatement( new GenOp( " @ = normalize( vec3( @, 0, @ ) );\r\n",
  236. new DecOp( inTanget ), squareSize, inTangentZ ) );
  237. }
  238. void TerrainBaseMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  239. const MaterialFeatureData &fd )
  240. {
  241. // grab connector texcoord register
  242. Var *texCoord = getInTexCoord( "texCoord", "vec3", componentList );
  243. // create texture var
  244. Var *diffuseMap = new Var;
  245. diffuseMap->setType( "sampler2D" );
  246. diffuseMap->setName( "baseTexMap" );
  247. diffuseMap->uniform = true;
  248. diffuseMap->sampler = true;
  249. diffuseMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
  250. MultiLine *meta = new MultiLine;
  251. Var *baseColor = new Var;
  252. baseColor->setType( "vec4" );
  253. baseColor->setName( "baseColor" );
  254. meta->addStatement( new GenOp( " @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
  255. ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
  256. if(fd.features.hasFeature(MFT_isDeferred))
  257. {
  258. target= ShaderFeature::RenderTarget1;
  259. }
  260. meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul,NULL,target ) ) );
  261. // Set base ORM info
  262. Var* ormConfig;
  263. OutputTarget targ = RenderTarget1;
  264. if (fd.features[MFT_isDeferred])
  265. {
  266. targ = RenderTarget2;
  267. }
  268. ormConfig = (Var*)LangElement::find(getOutputTargetVarName(targ));
  269. if (!ormConfig)
  270. {
  271. // create color var
  272. ormConfig = new Var;
  273. ormConfig->setType("fragout");
  274. ormConfig->setName(getOutputTargetVarName(targ));
  275. ormConfig->setStructName("OUT");
  276. }
  277. meta->addStatement(new GenOp(" @ = float4(0.0, 1.0, 1.0, 0.0);\r\n", ormConfig));
  278. output = meta;
  279. }
  280. ShaderFeature::Resources TerrainBaseMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  281. {
  282. Resources res;
  283. // Sample base texture
  284. res.numTexReg = 1;
  285. res.numTex = 1;
  286. return res;
  287. }
  288. U32 TerrainBaseMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
  289. {
  290. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 | ShaderFeature::RenderTarget2 : ShaderFeature::DefaultTarget | ShaderFeature::RenderTarget1;
  291. }
  292. TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL()
  293. : mTorqueDep(ShaderGen::smCommonShaderPath + String("/gl/torque.glsl" )),
  294. mTerrainDep(ShaderGen::smCommonShaderPath + String("/terrain/terrain.glsl" ))
  295. {
  296. addDependency( &mTorqueDep );
  297. addDependency( &mTerrainDep );
  298. }
  299. void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  300. const MaterialFeatureData &fd )
  301. {
  302. const S32 detailIndex = getProcessIndex();
  303. // Grab incoming texture coords... the base map feature
  304. // made sure this was created.
  305. Var *inTex = (Var*)LangElement::find( "texCoord" );
  306. AssertFatal( inTex, "The texture coord is missing!" );
  307. // Grab the input position.
  308. Var *inPos = (Var*)LangElement::find( "inPosition" );
  309. if ( !inPos )
  310. inPos = (Var*)LangElement::find( "position" );
  311. // Get the object space eye position.
  312. Var *eyePos = _getUniformVar( "eyePos", "vec3", cspPotentialPrimitive );
  313. MultiLine *meta = new MultiLine;
  314. // If we have parallax mapping then make sure we've sent
  315. // the negative view vector to the pixel shader.
  316. if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
  317. !LangElement::find( "outNegViewTS" ) )
  318. {
  319. // Get the object to tangent transform which
  320. // will consume 3 output registers.
  321. Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta, fd );
  322. // Now use a single output register to send the negative
  323. // view vector in tangent space to the pixel shader.
  324. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  325. Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD );
  326. outNegViewTS->setName( "outNegViewTS" );
  327. outNegViewTS->setStructName( "OUT" );
  328. outNegViewTS->setType( "vec3" );
  329. meta->addStatement( new GenOp( " @ = tMul( @, vec3( @ - @.xyz ) );\r\n",
  330. outNegViewTS, objToTangentSpace, eyePos, inPos ) );
  331. }
  332. // Get the distance from the eye to this vertex.
  333. Var *dist = (Var*)LangElement::find( "dist" );
  334. if ( !dist )
  335. {
  336. dist = new Var;
  337. dist->setType( "float" );
  338. dist->setName( "dist" );
  339. meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n",
  340. new DecOp( dist ), inPos, eyePos ) );
  341. }
  342. // grab connector texcoord register
  343. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  344. Var *outTex = connectComp->getElement( RT_TEXCOORD );
  345. outTex->setName( String::ToString( "detCoord%d", detailIndex ) );
  346. outTex->setStructName( "OUT" );
  347. outTex->setType( "vec4" );
  348. // Get the detail scale and fade info.
  349. Var *detScaleAndFade = (Var*)LangElement::find("detailScaleAndFade");
  350. if (!detScaleAndFade)
  351. {
  352. detScaleAndFade = new Var;
  353. detScaleAndFade->setType("vec4");
  354. detScaleAndFade->setName("detailScaleAndFade");
  355. detScaleAndFade->uniform = true;
  356. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  357. }
  358. detScaleAndFade->arraySize = mMax(detScaleAndFade->arraySize, detailIndex + 1);
  359. // Setup the detail coord.
  360. //
  361. // NOTE: You see here we scale the texture coord by 'xyx'
  362. // to generate the detail coord. This y is here because
  363. // its scale is flipped to correct for the non negative y
  364. // in texCoord.
  365. //
  366. // See TerrainBaseMapFeatGLSL::processVert().
  367. //
  368. meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(detScaleAndFade, detailIndex) ) );
  369. // And sneak the detail fade thru the w detailCoord.
  370. meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  371. outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)) );
  372. output = meta;
  373. }
  374. void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  375. const MaterialFeatureData &fd )
  376. {
  377. const S32 detailIndex = getProcessIndex();
  378. Var *inTex = getVertTexCoord( "texCoord" );
  379. MultiLine *meta = new MultiLine;
  380. // We need the negative tangent space view vector
  381. // as in parallax mapping we step towards the camera.
  382. Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
  383. if ( !negViewTS &&
  384. fd.features.hasFeature( MFT_TerrainParallaxMap ) )
  385. {
  386. Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
  387. if ( !inNegViewTS )
  388. {
  389. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  390. inNegViewTS = connectComp->getElement( RT_TEXCOORD );
  391. inNegViewTS->setName( "outNegViewTS" );
  392. inNegViewTS->setStructName( "IN" );
  393. inNegViewTS->setType( "vec3" );
  394. }
  395. negViewTS = new Var( "negViewTS", "vec3" );
  396. meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
  397. }
  398. // Get the layer samples.
  399. Var *layerSample = (Var*)LangElement::find( "layerSample" );
  400. if ( !layerSample )
  401. {
  402. layerSample = new Var;
  403. layerSample->setType( "vec4" );
  404. layerSample->setName( "layerSample" );
  405. // Get the layer texture var
  406. Var *layerTex = new Var;
  407. layerTex->setType( "sampler2D" );
  408. layerTex->setName( "layerTex" );
  409. layerTex->uniform = true;
  410. layerTex->sampler = true;
  411. layerTex->constNum = Var::getTexUnitNum();
  412. // Read the layer texture to get the samples.
  413. meta->addStatement( new GenOp( " @ = round( tex2D( @, @.xy ) * 255.0f );\r\n",
  414. new DecOp( layerSample ), layerTex, inTex ) );
  415. }
  416. Var *layerSize = (Var*)LangElement::find( "layerSize" );
  417. if ( !layerSize )
  418. {
  419. layerSize = new Var;
  420. layerSize->setType( "float" );
  421. layerSize->setName( "layerSize" );
  422. layerSize->uniform = true;
  423. layerSize->constSortPos = cspPass;
  424. }
  425. // Grab the incoming detail coord.
  426. Var *inDet = _getInDetailCoord( componentList );
  427. // Get the detail id.
  428. Var *detailInfo = _getDetailIdStrengthParallax();
  429. // Create the detail blend var.
  430. Var *detailBlend = new Var;
  431. detailBlend->setType( "float" );
  432. detailBlend->setName( String::ToString( "detailBlend%d", detailIndex ) );
  433. // Calculate the blend for this detail texture.
  434. meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
  435. new DecOp( detailBlend ), new IndexOp(detailInfo, detailIndex), inTex, layerSize, layerSample ) );
  436. // If we had a parallax feature... then factor in the parallax
  437. // amount so that it fades out with the layer blending.
  438. if (fd.features.hasFeature(MFT_TerrainParallaxMap, detailIndex))
  439. {
  440. // Get the normal map texture.
  441. Var* normalMap = _getNormalMapSampler();
  442. // Call the library function to do the rest.
  443. if (fd.features.hasFeature(MFT_IsBC3nm, detailIndex))
  444. {
  445. meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, vec3(@.xy, @.x), @, @.z * @ );\r\n",
  446. inDet, normalMap, inDet, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend));
  447. }
  448. else
  449. {
  450. meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, vec3(@.xy, @.x), @, @.z * @ );\r\n",
  451. inDet, normalMap, inDet, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend));
  452. }
  453. }
  454. Var* detailColor = (Var*)LangElement::find(String::ToString("detailColor%d", detailIndex));
  455. if (!detailColor)
  456. {
  457. detailColor = new Var;
  458. detailColor->setType("vec4");
  459. detailColor->setName(String::ToString("detailColor%d", detailIndex));
  460. meta->addStatement(new GenOp(" @;\r\n", new DecOp(detailColor)));
  461. }
  462. // Get the detail texture.
  463. Var *detailMap = _getDetailMapSampler();
  464. // If we had a parallax feature... then factor in the parallax
  465. // amount so that it fades out with the layer blending.
  466. if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
  467. {
  468. meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z ) * 2.0 ) - 1.0;\r\n",
  469. detailColor, detailMap, inDet, new IndexOp(detailInfo, detailIndex), detailMap, inDet, new IndexOp(detailInfo, detailIndex), inTex));
  470. }
  471. else
  472. {
  473. meta->addStatement(new GenOp(" @ = ( tex2D( @, vec3(@.xy, @.x) ) * 2.0 ) - 1.0;\r\n",
  474. detailColor, detailMap, inDet, new IndexOp(detailInfo, detailIndex)));
  475. }
  476. meta->addStatement(new GenOp(" @ *= @.y * @.w;\r\n",
  477. detailColor, new IndexOp(detailInfo, detailIndex), inDet));
  478. if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
  479. {
  480. // Check to see if we have a gbuffer normal.
  481. Var* gbNormal = (Var*)LangElement::find("gbNormal");
  482. // If we have a gbuffer normal and we don't have a
  483. // normal map feature then we need to lerp in a
  484. // default normal else the normals below this layer
  485. // will show thru.
  486. if (gbNormal &&
  487. !fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex))
  488. {
  489. Var* viewToTangent = getInViewToTangent(componentList);
  490. meta->addStatement(new GenOp(" @ = lerp( @, tGetMatrix3Row(@, 2), min( @, @.w ) );\r\n",
  491. gbNormal, gbNormal, viewToTangent, detailBlend, inDet));
  492. }
  493. // If we're using SM 3.0 then take advantage of
  494. // dynamic branching to skip layers per-pixel.
  495. if (GFX->getPixelShaderVersion() >= 3.0f)
  496. meta->addStatement(new GenOp(" if ( @ > 0.0f )\r\n", detailBlend));
  497. meta->addStatement(new GenOp(" {\r\n"));
  498. ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
  499. if (fd.features.hasFeature(MFT_isDeferred))
  500. target = ShaderFeature::RenderTarget1;
  501. Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target));
  502. meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n", outColor, outColor));
  503. meta->addStatement(new GenOp(" @ += @ * @;\r\n",
  504. outColor, detailColor, detailBlend));
  505. meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n", outColor, outColor));
  506. meta->addStatement(new GenOp(" }\r\n"));
  507. }
  508. output = meta;
  509. }
  510. ShaderFeature::Resources TerrainDetailMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  511. {
  512. Resources res;
  513. if ( getProcessIndex() == 0 )
  514. {
  515. // If this is the first detail pass then we
  516. // samples from the layer tex.
  517. res.numTex = 1;
  518. res.numTexReg = 1;
  519. // Add Detail TextureArray
  520. res.numTex += 1;
  521. res.numTexReg += 1;
  522. }
  523. return res;
  524. }
  525. U32 TerrainDetailMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
  526. {
  527. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
  528. }
  529. TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL()
  530. : mTorqueDep(ShaderGen::smCommonShaderPath + String("/gl/torque.glsl" )),
  531. mTerrainDep(ShaderGen::smCommonShaderPath + String("/terrain/terrain.glsl" ))
  532. {
  533. addDependency( &mTorqueDep );
  534. addDependency( &mTerrainDep );
  535. }
  536. void TerrainMacroMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  537. const MaterialFeatureData &fd )
  538. {
  539. const S32 detailIndex = getProcessIndex();
  540. // Grab incoming texture coords... the base map feature
  541. // made sure this was created.
  542. Var *inTex = (Var*)LangElement::find( "texCoord" );
  543. AssertFatal( inTex, "The texture coord is missing!" );
  544. // Grab the input position.
  545. Var *inPos = (Var*)LangElement::find( "inPosition" );
  546. if ( !inPos )
  547. inPos = (Var*)LangElement::find( "position" );
  548. // Get the object space eye position.
  549. Var *eyePos = _getUniformVar( "eyePos", "vec3", cspPotentialPrimitive );
  550. MultiLine *meta = new MultiLine;
  551. // Get the distance from the eye to this vertex.
  552. Var *dist = (Var*)LangElement::find( "macroDist" );
  553. if ( !dist )
  554. {
  555. dist = new Var;
  556. dist->setType( "float" );
  557. dist->setName( "macroDist" );
  558. meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n",
  559. new DecOp( dist ), inPos, eyePos ) );
  560. }
  561. // grab connector texcoord register
  562. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  563. Var *outTex = connectComp->getElement( RT_TEXCOORD );
  564. outTex->setName( String::ToString( "macroCoord%d", detailIndex ) );
  565. outTex->setStructName( "OUT" );
  566. outTex->setType( "vec4" );
  567. // Get the detail scale and fade info.
  568. Var *detScaleAndFade = new Var;
  569. detScaleAndFade->setType( "vec4" );
  570. detScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) );
  571. detScaleAndFade->uniform = true;
  572. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  573. // Setup the detail coord.
  574. meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) );
  575. // And sneak the detail fade thru the w detailCoord.
  576. meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  577. outTex, detScaleAndFade, dist, detScaleAndFade ) );
  578. output = meta;
  579. }
  580. void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  581. const MaterialFeatureData &fd )
  582. {
  583. const S32 detailIndex = getProcessIndex();
  584. Var *inTex = getVertTexCoord( "texCoord" );
  585. MultiLine *meta = new MultiLine;
  586. // We need the negative tangent space view vector
  587. // as in parallax mapping we step towards the camera.
  588. Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
  589. if ( !negViewTS &&
  590. fd.features.hasFeature( MFT_TerrainParallaxMap ) )
  591. {
  592. Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
  593. if ( !inNegViewTS )
  594. {
  595. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  596. inNegViewTS = connectComp->getElement( RT_TEXCOORD );
  597. inNegViewTS->setName( "outNegViewTS" );
  598. inNegViewTS->setStructName( "IN" );
  599. inNegViewTS->setType( "vec3" );
  600. }
  601. negViewTS = new Var( "negViewTS", "vec3" );
  602. meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
  603. }
  604. // Get the layer samples.
  605. Var *layerSample = (Var*)LangElement::find( "layerSample" );
  606. if ( !layerSample )
  607. {
  608. layerSample = new Var;
  609. layerSample->setType( "vec4" );
  610. layerSample->setName( "layerSample" );
  611. // Get the layer texture var
  612. Var *layerTex = new Var;
  613. layerTex->setType( "sampler2D" );
  614. layerTex->setName( "macrolayerTex" );
  615. layerTex->uniform = true;
  616. layerTex->sampler = true;
  617. layerTex->constNum = Var::getTexUnitNum();
  618. // Read the layer texture to get the samples.
  619. meta->addStatement( new GenOp( " @ = round( tex2D( @, @.xy ) * 255.0f );\r\n",
  620. new DecOp( layerSample ), layerTex, inTex ) );
  621. }
  622. Var *layerSize = (Var*)LangElement::find( "layerSize" );
  623. if ( !layerSize )
  624. {
  625. layerSize = new Var;
  626. layerSize->setType( "float" );
  627. layerSize->setName( "layerSize" );
  628. layerSize->uniform = true;
  629. layerSize->constSortPos = cspPass;
  630. }
  631. // Grab the incoming detail coord.
  632. Var *inDet = _getInMacroCoord( componentList );
  633. // Get the detail id.
  634. Var *detailInfo = _getMacroIdStrengthParallax();
  635. // Create the detail blend var.
  636. Var *detailBlend = new Var;
  637. detailBlend->setType( "float" );
  638. detailBlend->setName( String::ToString( "macroBlend%d", detailIndex ) );
  639. // Calculate the blend for this detail texture.
  640. meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
  641. new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
  642. Var *detailColor = (Var*)LangElement::find( "macroColor" );
  643. if ( !detailColor )
  644. {
  645. detailColor = new Var;
  646. detailColor->setType( "vec4" );
  647. detailColor->setName( "macroColor" );
  648. meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
  649. }
  650. // Get the detail texture.
  651. Var *detailMap = new Var;
  652. detailMap->setType( "sampler2D" );
  653. detailMap->setName( String::ToString( "macroMap%d", detailIndex ) );
  654. detailMap->uniform = true;
  655. detailMap->sampler = true;
  656. detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
  657. // If we're using SM 3.0 then take advantage of
  658. // dynamic branching to skip layers per-pixel.
  659. if ( GFX->getPixelShaderVersion() >= 3.0f )
  660. meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
  661. meta->addStatement( new GenOp( " {\r\n" ) );
  662. // Note that we're doing the standard greyscale detail
  663. // map technique here which can darken and lighten the
  664. // diffuse texture.
  665. //
  666. // We take two color samples and lerp between them for
  667. // side projection layers... else a single sample.
  668. //
  669. if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
  670. {
  671. meta->addStatement( new GenOp( " @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
  672. detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
  673. }
  674. else
  675. {
  676. meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
  677. detailColor, detailMap, inDet ) );
  678. }
  679. meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
  680. detailColor, detailInfo, inDet ) );
  681. ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
  682. if (fd.features.hasFeature(MFT_isDeferred))
  683. target= ShaderFeature::RenderTarget1;
  684. Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
  685. meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n", outColor, outColor));
  686. meta->addStatement(new GenOp(" @ += @ * @;\r\n",
  687. outColor, detailColor, detailBlend));
  688. meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n", outColor, outColor));
  689. meta->addStatement( new GenOp( " }\r\n" ) );
  690. output = meta;
  691. }
  692. ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  693. {
  694. Resources res;
  695. if ( getProcessIndex() == 0 )
  696. {
  697. // If this is the first detail pass then we
  698. // samples from the layer tex.
  699. res.numTex += 1;
  700. }
  701. res.numTex += 1;
  702. // Finally we always send the detail texture
  703. // coord to the pixel shader.
  704. res.numTexReg += 1;
  705. return res;
  706. }
  707. U32 TerrainMacroMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
  708. {
  709. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
  710. }
  711. void TerrainNormalMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  712. const MaterialFeatureData &fd )
  713. {
  714. // We only need to process normals during the deferred.
  715. if ( !fd.features.hasFeature( MFT_DeferredConditioner ) )
  716. return;
  717. MultiLine *meta = new MultiLine;
  718. if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
  719. {
  720. // Make sure the world to tangent transform
  721. // is created and available for the pixel shader.
  722. getOutViewToTangent(componentList, meta, fd);
  723. }
  724. output = meta;
  725. }
  726. void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  727. const MaterialFeatureData &fd )
  728. {
  729. // We only need to process normals during the deferred.
  730. if (!fd.features.hasFeature(MFT_DeferredConditioner))
  731. return;
  732. MultiLine *meta = new MultiLine;
  733. const S32 normalIndex = getProcessIndex();
  734. Var *detailBlend = (Var*)LangElement::find( String::ToString( "detailBlend%d", normalIndex ) );
  735. AssertFatal( detailBlend, "The detail blend is missing!" );
  736. // Get the normal map texture.
  737. Var *normalMap = _getNormalMapSampler();
  738. /// Get the texture coord.
  739. Var *inDet = _getInDetailCoord( componentList );
  740. Var *inTex = getVertTexCoord( "texCoord" );
  741. Var* detailInfo = _getDetailIdStrengthParallax();
  742. // Sample the normal map.
  743. //
  744. // We take two normal samples and lerp between them for
  745. // side projection layers... else a single sample.
  746. LangElement *texOp;
  747. if ( fd.features.hasFeature( MFT_TerrainSideProject, normalIndex ) )
  748. {
  749. texOp = new GenOp( "lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z )",
  750. normalMap, inDet, new IndexOp(detailInfo, normalIndex), normalMap, inDet, inTex, new IndexOp(detailInfo, normalIndex));
  751. }
  752. else
  753. texOp = new GenOp( String::ToString("tex2D(@, vec3(@.xy, @.x))", normalIndex), normalMap, inDet, new IndexOp(detailInfo, normalIndex));
  754. // create bump normal
  755. Var *bumpNorm = new Var;
  756. bumpNorm->setName( String::ToString("bumpNormal%d", normalIndex) );
  757. bumpNorm->setType( "vec4" );
  758. LangElement *bumpNormDecl = new DecOp( bumpNorm );
  759. meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
  760. if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
  761. {
  762. Var* viewToTangent = getInViewToTangent(componentList);
  763. // This var is read from GBufferConditionerGLSL and
  764. // used in the deferred output.
  765. Var* gbNormal = (Var*)LangElement::find("gbNormal");
  766. if (!gbNormal)
  767. {
  768. gbNormal = new Var;
  769. gbNormal->setName("gbNormal");
  770. gbNormal->setType("vec3");
  771. meta->addStatement(new GenOp(" @ = tGetMatrix3Row(@, 2);\r\n", new DecOp(gbNormal), viewToTangent));
  772. }
  773. // If we're using SM 3.0 then take advantage of
  774. // dynamic branching to skip layers per-pixel.
  775. if (GFX->getPixelShaderVersion() >= 3.0f)
  776. meta->addStatement(new GenOp(" if ( @ > 0.0f )\r\n", detailBlend));
  777. meta->addStatement(new GenOp(" {\r\n"));
  778. // Normalize is done later...
  779. // Note: The reverse mul order is intentional. Affine matrix.
  780. meta->addStatement(new GenOp(" @ = lerp( @, tMul( @.xyz, @ ), min( @, @.w ) );\r\n",
  781. gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet));
  782. // End the conditional block.
  783. meta->addStatement(new GenOp(" }\r\n"));
  784. }
  785. output = meta;
  786. }
  787. ShaderFeature::Resources TerrainNormalMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  788. {
  789. Resources res;
  790. // We only need to process normals during the deferred.
  791. if (!fd.features.hasFeature(MFT_DeferredConditioner))
  792. {
  793. return res;
  794. }
  795. S32 featureIndex = 0, firstNormalMapIndex = 0;
  796. for (int idx = 0; idx < fd.features.getCount(); ++idx) {
  797. const FeatureType& type = fd.features.getAt(idx, &featureIndex);
  798. if (type == MFT_TerrainNormalMap) {
  799. firstNormalMapIndex = getMin(firstNormalMapIndex, featureIndex);
  800. }
  801. }
  802. // We only need to process normals during the deferred.
  803. if (getProcessIndex() == firstNormalMapIndex)
  804. {
  805. // Normal Texture Array
  806. res.numTexReg += 1;
  807. res.numTex += 1;
  808. }
  809. return res;
  810. }
  811. void TerrainLightMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  812. const MaterialFeatureData &fd )
  813. {
  814. // grab connector texcoord register
  815. Var *inTex = (Var*)LangElement::find( "texCoord" );
  816. if ( !inTex )
  817. return;
  818. // Get the lightmap texture.
  819. Var *lightMap = new Var;
  820. lightMap->setType( "sampler2D" );
  821. lightMap->setName( "lightMapTex" );
  822. lightMap->uniform = true;
  823. lightMap->sampler = true;
  824. lightMap->constNum = Var::getTexUnitNum();
  825. MultiLine *meta = new MultiLine;
  826. // Find or create the lightMask value which is read by
  827. // RTLighting to mask out the lights.
  828. //
  829. // The first light is always the sunlight so we apply
  830. // the shadow mask to only the first channel.
  831. //
  832. Var *lightMask = (Var*)LangElement::find( "lightMask" );
  833. if ( !lightMask )
  834. {
  835. lightMask = new Var( "lightMask", "vec4" );
  836. meta->addStatement( new GenOp( " @ = vec4(1);\r\n", new DecOp( lightMask ) ) );
  837. }
  838. meta->addStatement( new GenOp( " @[0] = tex2D( @, @.xy ).r;\r\n", lightMask, lightMap, inTex ) );
  839. output = meta;
  840. }
  841. ShaderFeature::Resources TerrainLightMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  842. {
  843. Resources res;
  844. res.numTex = 1;
  845. return res;
  846. }
  847. //standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO),
  848. //.b = specular strength, a= spec power.
  849. void TerrainORMMapFeatGLSL::processVert(Vector<ShaderComponent*> &componentList,
  850. const MaterialFeatureData &fd)
  851. {
  852. const S32 detailIndex = getProcessIndex();
  853. // Grab incoming texture coords... the base map feature
  854. // made sure this was created.
  855. Var *inTex = (Var*)LangElement::find("texCoord");
  856. AssertFatal(inTex, "The texture coord is missing!");
  857. // Grab the input position.
  858. Var *inPos = (Var*)LangElement::find("inPosition");
  859. if (!inPos)
  860. inPos = (Var*)LangElement::find("position");
  861. // Get the object space eye position.
  862. Var *eyePos = _getUniformVar("eyePos", "vec3", cspPotentialPrimitive);
  863. MultiLine *meta = new MultiLine;
  864. // If we have parallax mapping then make sure we've sent
  865. // the negative view vector to the pixel shader.
  866. if (fd.features.hasFeature(MFT_TerrainParallaxMap) &&
  867. !LangElement::find("outNegViewTS"))
  868. {
  869. // Get the object to tangent transform which
  870. // will consume 3 output registers.
  871. Var *objToTangentSpace = getOutObjToTangentSpace(componentList, meta, fd);
  872. // Now use a single output register to send the negative
  873. // view vector in tangent space to the pixel shader.
  874. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
  875. Var *outNegViewTS = connectComp->getElement(RT_TEXCOORD);
  876. outNegViewTS->setName("outNegViewTS");
  877. outNegViewTS->setStructName("OUT");
  878. outNegViewTS->setType("vec3");
  879. meta->addStatement(new GenOp(" @ = @ * vec3( @ - @.xyz );\r\n",
  880. outNegViewTS, objToTangentSpace, eyePos, inPos));
  881. }
  882. // Get the distance from the eye to this vertex.
  883. Var *dist = (Var*)LangElement::find("dist");
  884. if (!dist)
  885. {
  886. dist = new Var;
  887. dist->setType("float");
  888. dist->setName("dist");
  889. meta->addStatement(new GenOp(" @ = distance( @.xyz, @ );\r\n",
  890. new DecOp(dist), inPos, eyePos));
  891. }
  892. // grab connector texcoord register
  893. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
  894. Var *outTex = (Var*)LangElement::find(String::ToString("detCoord%d", detailIndex));
  895. if (outTex == NULL)
  896. {
  897. outTex = new Var;
  898. outTex = connectComp->getElement(RT_TEXCOORD);
  899. outTex->setName(String::ToString("detCoord%d", detailIndex));
  900. outTex->setStructName("OUT");
  901. outTex->setType("vec4");
  902. }
  903. // Get the detail scale and fade info.
  904. Var *detScaleAndFade = (Var*)LangElement::find("detailScaleAndFade");
  905. if (detScaleAndFade == NULL)
  906. {
  907. detScaleAndFade = new Var;
  908. detScaleAndFade->setType("vec4");
  909. detScaleAndFade->setName("detailScaleAndFade");
  910. detScaleAndFade->uniform = true;
  911. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  912. }
  913. detScaleAndFade->arraySize = mMax(detScaleAndFade->arraySize, detailIndex + 1);
  914. // Setup the detail coord.
  915. //
  916. // NOTE: You see here we scale the texture coord by 'xyx'
  917. // to generate the detail coord. This y is here because
  918. // its scale is flipped to correct for the non negative y
  919. // in texCoord.
  920. //
  921. // See TerrainBaseMapFeatGLSL::processVert().
  922. //
  923. meta->addStatement(new GenOp(" @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(detScaleAndFade, detailIndex)));
  924. // And sneak the detail fade thru the w detailCoord.
  925. meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  926. outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)));
  927. output = meta;
  928. }
  929. U32 TerrainORMMapFeatGLSL::getOutputTargets(const MaterialFeatureData &fd) const
  930. {
  931. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
  932. }
  933. void TerrainORMMapFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
  934. const MaterialFeatureData &fd)
  935. {
  936. /// Get the texture coord.
  937. Var *inDet = _getInDetailCoord(componentList);
  938. Var *inTex = getVertTexCoord("texCoord");
  939. Var* detailInfo = _getDetailIdStrengthParallax();
  940. const S32 compositeIndex = getProcessIndex();
  941. Var *ormConfigMap = _getOrmMapSampler();
  942. // Sample the normal map.
  943. //
  944. // We take two normal samples and lerp between them for
  945. // side projection layers... else a single sample.
  946. LangElement *texOp;
  947. if (fd.features.hasFeature(MFT_TerrainSideProject, compositeIndex))
  948. {
  949. texOp = new GenOp("lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z )",
  950. ormConfigMap, inDet, new IndexOp(detailInfo, compositeIndex), ormConfigMap, inDet, new IndexOp(detailInfo, compositeIndex), inTex);
  951. }
  952. else
  953. texOp = new GenOp("tex2D(@, vec3(@.xy, @.x))", ormConfigMap, inDet, new IndexOp(detailInfo, compositeIndex));
  954. // search for material var
  955. Var * ormConfig;
  956. OutputTarget targ = RenderTarget1;
  957. if (fd.features[MFT_isDeferred])
  958. {
  959. targ = RenderTarget2;
  960. }
  961. ormConfig = (Var*)LangElement::find(getOutputTargetVarName(targ));
  962. MultiLine * meta = new MultiLine;
  963. if (!ormConfig)
  964. {
  965. // create color var
  966. ormConfig = new Var;
  967. ormConfig->setType("fragout");
  968. ormConfig->setName(getOutputTargetVarName(targ));
  969. ormConfig->setStructName("OUT");
  970. }
  971. Var *detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", compositeIndex));
  972. AssertFatal(detailBlend, "The detail blend is missing!");
  973. String matinfoName(String::ToString("matinfoCol%d", compositeIndex));
  974. Var *matinfoCol = new Var(matinfoName, "vec3");
  975. if (compositeIndex == 0)
  976. {
  977. meta->addStatement(new GenOp(" @ = vec4(0.0, 0.0, 0.0, 0.0);\r\n", ormConfig));
  978. }
  979. meta->addStatement(new GenOp(" @ = @.rgb;\r\n", new DecOp(matinfoCol), texOp));
  980. if (fd.features.hasFeature(MFT_InvertRoughness, compositeIndex))
  981. {
  982. meta->addStatement(new GenOp(" @.b = 1.0 - @.b;\r\n", matinfoCol, matinfoCol));
  983. }
  984. meta->addStatement(new GenOp(" @ = lerp(float3(1.0, 1.0, 0.0), @, @.y * @.w);\r\n", matinfoCol, matinfoCol, new IndexOp(detailInfo, compositeIndex), inDet));
  985. if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
  986. {
  987. meta->addStatement(new GenOp(" @.gba += @ * @;\r\n", ormConfig, matinfoCol, detailBlend));
  988. }
  989. output = meta;
  990. }
  991. ShaderFeature::Resources TerrainORMMapFeatGLSL::getResources(const MaterialFeatureData &fd)
  992. {
  993. Resources res;
  994. S32 featureIndex = 0, firstOrmMapIndex = 0;
  995. for (int idx = 0; idx < fd.features.getCount(); ++idx) {
  996. const FeatureType& type = fd.features.getAt(idx, &featureIndex);
  997. if (type == MFT_TerrainORMMap) {
  998. firstOrmMapIndex = getMin(firstOrmMapIndex, featureIndex);
  999. }
  1000. }
  1001. // We only need to process normals during the deferred.
  1002. if (getProcessIndex() == firstOrmMapIndex)
  1003. {
  1004. res.numTexReg = 1;
  1005. res.numTex = 1;
  1006. }
  1007. return res;
  1008. }
  1009. U32 TerrainBlankInfoMapFeatGLSL::getOutputTargets(const MaterialFeatureData &fd) const
  1010. {
  1011. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
  1012. }
  1013. // reminder, the matinfo buffer is flags, smooth, ao, metal
  1014. void TerrainBlankInfoMapFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
  1015. const MaterialFeatureData &fd)
  1016. {
  1017. S32 compositeIndex = getProcessIndex();
  1018. // search for material var
  1019. Var *material;
  1020. OutputTarget targ = DefaultTarget;
  1021. if (fd.features[MFT_isDeferred])
  1022. {
  1023. targ = RenderTarget2;
  1024. }
  1025. material = (Var*)LangElement::find(getOutputTargetVarName(targ));
  1026. MultiLine * meta = new MultiLine;
  1027. if (!material)
  1028. {
  1029. // create color var
  1030. material = new Var;
  1031. material->setType("vec4");
  1032. material->setName(getOutputTargetVarName(targ));
  1033. material->setStructName("OUT");
  1034. }
  1035. if (compositeIndex == 0)
  1036. {
  1037. meta->addStatement(new GenOp(" @ = vec4(0.0, 0.0, 0.0, 0.0);\r\n", material));
  1038. }
  1039. Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", compositeIndex));
  1040. AssertFatal(detailBlend, "The detail blend is missing!");
  1041. String matinfoName(String::ToString("matinfoCol%d", compositeIndex));
  1042. meta->addStatement(new GenOp(" @.gba += vec3(@, @, 0.0);\r\n", material, detailBlend, detailBlend));
  1043. output = meta;
  1044. }
  1045. void TerrainHeightMapBlendGLSL::processVert(
  1046. Vector<ShaderComponent *> &componentList, const MaterialFeatureData &fd) {
  1047. // We only need to process normals during the deferred.
  1048. if (!fd.features.hasFeature(MFT_DeferredConditioner))
  1049. return;
  1050. MultiLine* meta = new MultiLine;
  1051. // Handle an edge-case when there are no detail-maps available
  1052. if (fd.features.getNextFeatureIndex(MFT_TerrainDetailMap, -1) >= 0)
  1053. {
  1054. // Make sure the world to tangent transform
  1055. // is created and available for the pixel shader.
  1056. getOutViewToTangent(componentList, meta, fd);
  1057. }
  1058. output = meta;
  1059. }
  1060. void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentList,
  1061. const MaterialFeatureData& fd)
  1062. {
  1063. ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
  1064. if (fd.features.hasFeature(MFT_isDeferred))
  1065. target = ShaderFeature::RenderTarget1;
  1066. Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target));
  1067. if (!outColor)
  1068. return;
  1069. MultiLine* meta = new MultiLine;
  1070. // Count the number of detail textures
  1071. int detailCount = 0;
  1072. while (true)
  1073. {
  1074. if (LangElement::find(String::ToString("detailBlend%d", detailCount)) == NULL)
  1075. {
  1076. break;
  1077. }
  1078. ++detailCount;
  1079. }
  1080. if (detailCount == 0)
  1081. {
  1082. return;
  1083. }
  1084. // Compute the "height" of each detail layer and store it detailHX
  1085. for (S32 idx = 0; idx < detailCount; ++idx)
  1086. {
  1087. Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
  1088. Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx));
  1089. Var* blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", idx));
  1090. if (!blendDepth)
  1091. {
  1092. blendDepth = new Var;
  1093. blendDepth->setType("float");
  1094. blendDepth->setName(String::ToString("blendDepth%d", idx));
  1095. blendDepth->uniform = true;
  1096. blendDepth->constSortPos = cspPrimitive;
  1097. }
  1098. Var* blendContrast = (Var*)LangElement::find(String::ToString("blendContrast%d", idx));
  1099. if (!blendContrast)
  1100. {
  1101. blendContrast = new Var;
  1102. blendContrast->setType("float");
  1103. blendContrast->setName(String::ToString("blendContrast%d", idx));
  1104. blendContrast->uniform = true;
  1105. blendContrast->constSortPos = cspPrimitive;
  1106. }
  1107. Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
  1108. if (!detailH)
  1109. {
  1110. detailH = new Var;
  1111. detailH->setType("float");
  1112. detailH->setName(String::ToString("detailH%d", idx));
  1113. meta->addStatement(new GenOp(" @ = 0;\r\n",
  1114. new DecOp(detailH)));
  1115. meta->addStatement(new GenOp(" if (@ > 0.0f) {\r\n", detailBlend));
  1116. if (bumpNormal != NULL)
  1117. {
  1118. meta->addStatement(new GenOp(" @ = clamp(@.a + @, 0.0, 1.0);\r\n",
  1119. detailH, bumpNormal, blendDepth));
  1120. }
  1121. else
  1122. {
  1123. meta->addStatement(new GenOp(" @ = clamp(0.5 + @, 0.0, 1.0);\r\n",
  1124. detailH, blendDepth));
  1125. }
  1126. meta->addStatement(new GenOp(" @ = max((@ * 2.0f - 1.0f) * @ + 0.5f, 0.0f);\r\n",
  1127. detailH, detailH, blendContrast));
  1128. meta->addStatement(new GenOp(" }\r\n"));
  1129. }
  1130. }
  1131. meta->addStatement(new GenOp("\r\n"));
  1132. // Compute blending factors
  1133. Var* depth = (Var*)LangElement::find("baseBlendDepth");
  1134. if (depth == NULL)
  1135. {
  1136. depth = new Var;
  1137. depth->setType("float");
  1138. depth->setName("baseBlendDepth");
  1139. depth->uniform = true;
  1140. depth->constSortPos = cspPrimitive;
  1141. }
  1142. Var* ma = (Var*)LangElement::find("ma");
  1143. if (ma == NULL)
  1144. {
  1145. ma = new Var;
  1146. ma->setType("float");
  1147. ma->setName("ma");
  1148. meta->addStatement(new GenOp(" @ = 0;\r\n",
  1149. new DecOp(ma)));
  1150. }
  1151. for (S32 idx = 0; idx < detailCount; ++idx)
  1152. {
  1153. Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
  1154. Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
  1155. meta->addStatement(new GenOp(" @ = max(@, @ + @);\r\n",
  1156. ma, ma, detailH, detailBlend));
  1157. }
  1158. meta->addStatement(new GenOp(" @ -= @;\r\n",
  1159. ma, depth));
  1160. meta->addStatement(new GenOp("\r\n"));
  1161. for (S32 idx = 0; idx < detailCount; ++idx)
  1162. {
  1163. Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
  1164. Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
  1165. Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
  1166. if (!detailB)
  1167. {
  1168. detailB = new Var;
  1169. detailB->setType("float");
  1170. detailB->setName(String::ToString("detailB%d", idx));
  1171. meta->addStatement(new GenOp(" @ = max(@ + @ - @, 0);\r\n",
  1172. new DecOp(detailB), detailH, detailBlend, ma));
  1173. }
  1174. }
  1175. meta->addStatement(new GenOp("\r\n"));
  1176. // Compute albedo
  1177. meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n",
  1178. outColor, outColor));
  1179. meta->addStatement(new GenOp(" @.rgb += (",
  1180. outColor));
  1181. for (S32 idx = 0; idx < detailCount; ++idx)
  1182. {
  1183. Var* detailColor = (Var*)LangElement::find(String::ToString("detailColor%d", idx));
  1184. Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
  1185. if (idx > 0)
  1186. {
  1187. meta->addStatement(new GenOp(" + "));
  1188. }
  1189. meta->addStatement(new GenOp("@.rgb * @", detailColor, detailB));
  1190. }
  1191. meta->addStatement(new GenOp(") / ("));
  1192. for (S32 idx = 0; idx < detailCount; ++idx)
  1193. {
  1194. Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
  1195. if (idx > 0)
  1196. {
  1197. meta->addStatement(new GenOp(" + "));
  1198. }
  1199. meta->addStatement(new GenOp("@", detailB));
  1200. }
  1201. meta->addStatement(new GenOp(");\r\n"));
  1202. meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n",
  1203. outColor, outColor));
  1204. meta->addStatement(new GenOp("\r\n"));
  1205. // Compute ORM
  1206. Var* ormOutput;
  1207. OutputTarget targ = DefaultTarget;
  1208. if (fd.features[MFT_isDeferred])
  1209. {
  1210. targ = RenderTarget2;
  1211. }
  1212. ormOutput = (Var*)LangElement::find(getOutputTargetVarName(targ));
  1213. meta->addStatement(new GenOp(" @.gba = (",
  1214. ormOutput));
  1215. for (S32 idx = 0; idx < detailCount; ++idx)
  1216. {
  1217. Var* matinfoCol = (Var*)LangElement::find(String::ToString("matinfoCol%d", idx));
  1218. Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
  1219. if (idx > 0)
  1220. {
  1221. meta->addStatement(new GenOp(" + "));
  1222. }
  1223. if (matinfoCol)
  1224. {
  1225. meta->addStatement(new GenOp("@ * @", matinfoCol, detailB));
  1226. }
  1227. else
  1228. {
  1229. meta->addStatement(new GenOp("vec3(1.0, 1.0, 0.0) * @", detailB));
  1230. }
  1231. }
  1232. meta->addStatement(new GenOp(") / ("));
  1233. for (S32 idx = 0; idx < detailCount; ++idx)
  1234. {
  1235. Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
  1236. if (idx > 0)
  1237. {
  1238. meta->addStatement(new GenOp(" + "));
  1239. }
  1240. meta->addStatement(new GenOp("@", detailB));
  1241. }
  1242. meta->addStatement(new GenOp(");\r\n"));
  1243. meta->addStatement(new GenOp("\r\n"));
  1244. // Compute normal-specific blending factors
  1245. // LukasPJ: I'm not sure why this is necessary, it might not be.
  1246. Var* normalMa = (Var*)LangElement::find("normalMa");
  1247. if (normalMa == NULL)
  1248. {
  1249. normalMa = new Var;
  1250. normalMa->setType("float");
  1251. normalMa->setName("normalMa");
  1252. meta->addStatement(new GenOp(" @ = 0;\r\n",
  1253. new DecOp(normalMa)));
  1254. }
  1255. for (S32 idx = 0; idx < detailCount; ++idx)
  1256. {
  1257. Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx));
  1258. Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
  1259. Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
  1260. meta->addStatement(new GenOp(" @ = max(@, @ + min(@, @.w));\r\n",
  1261. normalMa, normalMa, detailH, detailBlend, detCoord));
  1262. }
  1263. meta->addStatement(new GenOp(" @ -= @;\r\n",
  1264. normalMa, depth));
  1265. meta->addStatement(new GenOp("\r\n"));
  1266. for (S32 idx = 0; idx < detailCount; ++idx)
  1267. {
  1268. Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx));
  1269. Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
  1270. Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
  1271. Var* normalDetailB = (Var*)LangElement::find(String::ToString("normalDetailB%d", idx));
  1272. if (!normalDetailB)
  1273. {
  1274. normalDetailB = new Var;
  1275. normalDetailB->setType("float");
  1276. normalDetailB->setName(String::ToString("normalDetailB%d", idx));
  1277. meta->addStatement(new GenOp(" @ = max(@ + min(@, @.w) - @, 0);\r\n",
  1278. new DecOp(normalDetailB), detailH, detailBlend, detCoord, normalMa));
  1279. }
  1280. }
  1281. // Compute normals
  1282. Var* gbNormal = (Var*)LangElement::find("gbNormal");
  1283. if (!gbNormal)
  1284. {
  1285. gbNormal = new Var;
  1286. gbNormal->setName("gbNormal");
  1287. gbNormal->setType("vec3");
  1288. meta->addStatement(new GenOp(" @;\r\n", new DecOp(gbNormal)));
  1289. }
  1290. if (gbNormal != NULL)
  1291. {
  1292. meta->addStatement(new GenOp(" @ = (",
  1293. gbNormal));
  1294. for (S32 idx = 0; idx < detailCount; ++idx)
  1295. {
  1296. Var* normalDetailB = (Var*)LangElement::find(String::ToString("normalDetailB%d", idx));
  1297. Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx));
  1298. Var* viewToTangent = getInViewToTangent(componentList);
  1299. if (idx > 0)
  1300. {
  1301. meta->addStatement(new GenOp(" + "));
  1302. }
  1303. if (bumpNormal != NULL)
  1304. {
  1305. meta->addStatement(new GenOp("tMul(@.xyz, @) * @", bumpNormal, viewToTangent, normalDetailB));
  1306. }
  1307. else
  1308. {
  1309. meta->addStatement(new GenOp("tGetMatrix3Row(@, 2) * @", viewToTangent, normalDetailB));
  1310. }
  1311. }
  1312. meta->addStatement(new GenOp(") / ("));
  1313. for (S32 idx = 0; idx < detailCount; ++idx)
  1314. {
  1315. Var* normalDetailB = (Var*)LangElement::find(String::ToString("normalDetailB%d", idx));
  1316. if (idx > 0)
  1317. {
  1318. meta->addStatement(new GenOp(" + "));
  1319. }
  1320. meta->addStatement(new GenOp("@", normalDetailB));
  1321. }
  1322. meta->addStatement(new GenOp(");\r\n"));
  1323. }
  1324. output = meta;
  1325. }