terrFeatureGLSL.cpp 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346
  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_TerrainAdditive, new TerrainAdditiveFeatGLSL );
  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::_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::_getORMConfigMapTex()
  121. {
  122. String name(String::ToString("ormConfigMap%d", getProcessIndex()));
  123. Var *ormConfigMap = (Var*)LangElement::find(name);
  124. if (!ormConfigMap)
  125. {
  126. ormConfigMap = new Var;
  127. ormConfigMap->setType("sampler2D");
  128. ormConfigMap->setName(name);
  129. ormConfigMap->uniform = true;
  130. ormConfigMap->sampler = true;
  131. ormConfigMap->constNum = Var::getTexUnitNum();
  132. }
  133. return ormConfigMap;
  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. // If this is the last normal map then we
  828. // can test to see the total blend value
  829. // to see if we should clip the result.
  830. Var* blendTotal = (Var*)LangElement::find("blendTotal");
  831. if (blendTotal)
  832. {
  833. if (fd.features.getNextFeatureIndex(MFT_TerrainNormalMap, normalIndex) == -1)
  834. meta->addStatement(new GenOp(" if ( @ > 0.0001f ){\r\n\r\n", blendTotal));
  835. }
  836. // Normalize is done later...
  837. // Note: The reverse mul order is intentional. Affine matrix.
  838. meta->addStatement(new GenOp(" @ = lerp( @, tMul( @.xyz, @ ), min( @, @.w ) );\r\n",
  839. gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet));
  840. if (blendTotal)
  841. {
  842. if (fd.features.getNextFeatureIndex(MFT_TerrainNormalMap, normalIndex) == -1)
  843. meta->addStatement(new GenOp(" }\r\n"));
  844. }
  845. // End the conditional block.
  846. meta->addStatement( new GenOp( " }\r\n" ) );
  847. output = meta;
  848. }
  849. ShaderFeature::Resources TerrainNormalMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  850. {
  851. Resources res;
  852. // We only need to process normals during the deferred.
  853. if ( fd.features.hasFeature( MFT_DeferredConditioner ) )
  854. {
  855. // If this is the first normal map and there
  856. // are no parallax features then we will
  857. // generate the worldToTanget transform.
  858. if ( !fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
  859. ( getProcessIndex() == 0 || !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() - 1 ) ) )
  860. res.numTexReg = 3;
  861. res.numTex = 1;
  862. }
  863. return res;
  864. }
  865. void TerrainLightMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  866. const MaterialFeatureData &fd )
  867. {
  868. // grab connector texcoord register
  869. Var *inTex = (Var*)LangElement::find( "texCoord" );
  870. if ( !inTex )
  871. return;
  872. // Get the lightmap texture.
  873. Var *lightMap = new Var;
  874. lightMap->setType( "sampler2D" );
  875. lightMap->setName( "lightMapTex" );
  876. lightMap->uniform = true;
  877. lightMap->sampler = true;
  878. lightMap->constNum = Var::getTexUnitNum();
  879. MultiLine *meta = new MultiLine;
  880. // Find or create the lightMask value which is read by
  881. // RTLighting to mask out the lights.
  882. //
  883. // The first light is always the sunlight so we apply
  884. // the shadow mask to only the first channel.
  885. //
  886. Var *lightMask = (Var*)LangElement::find( "lightMask" );
  887. if ( !lightMask )
  888. {
  889. lightMask = new Var( "lightMask", "vec4" );
  890. meta->addStatement( new GenOp( " @ = vec4(1);\r\n", new DecOp( lightMask ) ) );
  891. }
  892. meta->addStatement( new GenOp( " @[0] = tex2D( @, @.xy ).r;\r\n", lightMask, lightMap, inTex ) );
  893. output = meta;
  894. }
  895. ShaderFeature::Resources TerrainLightMapFeatGLSL::getResources( const MaterialFeatureData &fd )
  896. {
  897. Resources res;
  898. res.numTex = 1;
  899. return res;
  900. }
  901. void TerrainAdditiveFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  902. const MaterialFeatureData &fd )
  903. {
  904. Var *color = NULL;
  905. Var* norm = NULL;
  906. if (fd.features[MFT_isDeferred])
  907. {
  908. color = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
  909. norm = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
  910. }
  911. color = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
  912. Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
  913. if ( !color || !blendTotal )
  914. return;
  915. MultiLine *meta = new MultiLine;
  916. meta->addStatement( new GenOp( " clip( @ - 0.0001 );\r\n", blendTotal ) );
  917. meta->addStatement( new GenOp( " @.a = @;\r\n", color, blendTotal ) );
  918. if (fd.features[MFT_isDeferred])
  919. {
  920. meta->addStatement(new GenOp(" @.a = @;\r\n", norm, blendTotal));
  921. }
  922. output = meta;
  923. }
  924. //standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO),
  925. //.b = specular strength, a= spec power.
  926. void TerrainORMMapFeatGLSL::processVert(Vector<ShaderComponent*> &componentList,
  927. const MaterialFeatureData &fd)
  928. {
  929. const S32 detailIndex = getProcessIndex();
  930. // Grab incoming texture coords... the base map feature
  931. // made sure this was created.
  932. Var *inTex = (Var*)LangElement::find("texCoord");
  933. AssertFatal(inTex, "The texture coord is missing!");
  934. // Grab the input position.
  935. Var *inPos = (Var*)LangElement::find("inPosition");
  936. if (!inPos)
  937. inPos = (Var*)LangElement::find("position");
  938. // Get the object space eye position.
  939. Var *eyePos = _getUniformVar("eyePos", "vec3", cspPotentialPrimitive);
  940. MultiLine *meta = new MultiLine;
  941. // If we have parallax mapping then make sure we've sent
  942. // the negative view vector to the pixel shader.
  943. if (fd.features.hasFeature(MFT_TerrainParallaxMap) &&
  944. !LangElement::find("outNegViewTS"))
  945. {
  946. // Get the object to tangent transform which
  947. // will consume 3 output registers.
  948. Var *objToTangentSpace = getOutObjToTangentSpace(componentList, meta, fd);
  949. // Now use a single output register to send the negative
  950. // view vector in tangent space to the pixel shader.
  951. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
  952. Var *outNegViewTS = connectComp->getElement(RT_TEXCOORD);
  953. outNegViewTS->setName("outNegViewTS");
  954. outNegViewTS->setStructName("OUT");
  955. outNegViewTS->setType("vec3");
  956. meta->addStatement(new GenOp(" @ = @ * vec3( @ - @.xyz );\r\n",
  957. outNegViewTS, objToTangentSpace, eyePos, inPos));
  958. }
  959. // Get the distance from the eye to this vertex.
  960. Var *dist = (Var*)LangElement::find("dist");
  961. if (!dist)
  962. {
  963. dist = new Var;
  964. dist->setType("float");
  965. dist->setName("dist");
  966. meta->addStatement(new GenOp(" @ = distance( @.xyz, @ );\r\n",
  967. new DecOp(dist), inPos, eyePos));
  968. }
  969. // grab connector texcoord register
  970. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
  971. Var *outTex = (Var*)LangElement::find(String::ToString("detCoord%d", detailIndex));
  972. if (outTex == NULL)
  973. {
  974. outTex = connectComp->getElement(RT_TEXCOORD);
  975. outTex->setName(String::ToString("detCoord%d", detailIndex));
  976. outTex->setStructName("OUT");
  977. outTex->setType("vec4");
  978. }
  979. // Get the detail scale and fade info.
  980. Var *detScaleAndFade = (Var*)LangElement::find(String::ToString("detailScaleAndFade%d", detailIndex));
  981. if (detScaleAndFade == NULL)
  982. {
  983. detScaleAndFade->setType("vec4");
  984. detScaleAndFade->setName(String::ToString("detailScaleAndFade%d", detailIndex));
  985. detScaleAndFade->uniform = true;
  986. detScaleAndFade->constSortPos = cspPotentialPrimitive;
  987. }
  988. // Setup the detail coord.
  989. //
  990. // NOTE: You see here we scale the texture coord by 'xyx'
  991. // to generate the detail coord. This y is here because
  992. // its scale is flipped to correct for the non negative y
  993. // in texCoord.
  994. //
  995. // See TerrainBaseMapFeatGLSL::processVert().
  996. //
  997. meta->addStatement(new GenOp(" @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade));
  998. // And sneak the detail fade thru the w detailCoord.
  999. meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
  1000. outTex, detScaleAndFade, dist, detScaleAndFade));
  1001. output = meta;
  1002. }
  1003. U32 TerrainORMMapFeatGLSL::getOutputTargets(const MaterialFeatureData &fd) const
  1004. {
  1005. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
  1006. }
  1007. void TerrainORMMapFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
  1008. const MaterialFeatureData &fd)
  1009. {
  1010. /// Get the texture coord.
  1011. Var *inDet = _getInDetailCoord(componentList);
  1012. Var *inTex = getVertTexCoord("texCoord");
  1013. const S32 compositeIndex = getProcessIndex();
  1014. Var *ormConfigMap = _getORMConfigMapTex();
  1015. // Sample the normal map.
  1016. //
  1017. // We take two normal samples and lerp between them for
  1018. // side projection layers... else a single sample.
  1019. LangElement *texOp;
  1020. if (fd.features.hasFeature(MFT_TerrainSideProject, compositeIndex))
  1021. {
  1022. texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
  1023. ormConfigMap, inDet, ormConfigMap, inDet, inTex);
  1024. }
  1025. else
  1026. texOp = new GenOp("tex2D(@, @.xy)", ormConfigMap, inDet);
  1027. // search for material var
  1028. Var * ormConfig;
  1029. OutputTarget targ = RenderTarget1;
  1030. if (fd.features[MFT_isDeferred])
  1031. {
  1032. targ = RenderTarget2;
  1033. }
  1034. ormConfig = (Var*)LangElement::find(getOutputTargetVarName(targ));
  1035. MultiLine * meta = new MultiLine;
  1036. if (!ormConfig)
  1037. {
  1038. // create color var
  1039. ormConfig = new Var;
  1040. ormConfig->setType("fragout");
  1041. ormConfig->setName(getOutputTargetVarName(targ));
  1042. ormConfig->setStructName("OUT");
  1043. }
  1044. Var *detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", compositeIndex));
  1045. AssertFatal(detailBlend, "The detail blend is missing!");
  1046. String matinfoName(String::ToString("matinfoCol%d", compositeIndex));
  1047. Var *matinfoCol = new Var(matinfoName, "vec3");
  1048. Var *priorComp = (Var*)LangElement::find(String::ToString("matinfoCol%d", compositeIndex - 1));
  1049. if (priorComp)
  1050. {
  1051. meta->addStatement(new GenOp(" @ = @.rgb*@;\r\n", new DecOp(matinfoCol), texOp, detailBlend));
  1052. meta->addStatement(new GenOp(" @.gba += @;\r\n", ormConfig, matinfoCol));
  1053. }
  1054. else
  1055. {
  1056. meta->addStatement(new GenOp(" @ = lerp(vec3(1.0,1.0,0.0),@.rgb,@);\r\n", new DecOp(matinfoCol), texOp, detailBlend));
  1057. meta->addStatement(new GenOp(" @ = vec4(0.0,@);\r\n", ormConfig, matinfoCol));
  1058. }
  1059. if (fd.features[MFT_InvertRoughness])
  1060. {
  1061. meta->addStatement(new GenOp(" @.b = [email protected];\r\n", ormConfig, ormConfig));
  1062. }
  1063. output = meta;
  1064. }
  1065. ShaderFeature::Resources TerrainORMMapFeatGLSL::getResources(const MaterialFeatureData &fd)
  1066. {
  1067. Resources res;
  1068. res.numTex = 1;
  1069. res.numTexReg += 1;
  1070. return res;
  1071. }
  1072. U32 TerrainBlankInfoMapFeatGLSL::getOutputTargets(const MaterialFeatureData &fd) const
  1073. {
  1074. return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
  1075. }
  1076. // reminder, the matinfo buffer is flags, smooth, ao, metal
  1077. void TerrainBlankInfoMapFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
  1078. const MaterialFeatureData &fd)
  1079. {
  1080. // search for material var
  1081. Var *material;
  1082. OutputTarget targ = RenderTarget1;
  1083. if (fd.features[MFT_isDeferred])
  1084. {
  1085. targ = RenderTarget2;
  1086. }
  1087. material = (Var*)LangElement::find(getOutputTargetVarName(targ));
  1088. MultiLine * meta = new MultiLine;
  1089. if (!material)
  1090. {
  1091. // create color var
  1092. material = new Var;
  1093. material->setType("vec4");
  1094. material->setName(getOutputTargetVarName(targ));
  1095. material->setStructName("OUT");
  1096. }
  1097. meta->addStatement(new GenOp(" @ = vec4(0.0,1.0,1.0,0.0);\r\n", material));
  1098. output = meta;
  1099. }