advancedLightingFeaturesGLSL.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  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 "lighting/advanced/glsl/advancedLightingFeaturesGLSL.h"
  24. #include "lighting/advanced/advancedLightBinManager.h"
  25. #include "shaderGen/langElement.h"
  26. #include "shaderGen/shaderOp.h"
  27. #include "shaderGen/conditionerFeature.h"
  28. #include "renderInstance/renderPrePassMgr.h"
  29. #include "materials/processedMaterial.h"
  30. #include "materials/materialFeatureTypes.h"
  31. void DeferredRTLightingFeatGLSL::processPixMacros( Vector<GFXShaderMacro> &macros,
  32. const MaterialFeatureData &fd )
  33. {
  34. /// TODO: This needs to be done via some sort of material
  35. /// feature and not just allow all translucent elements to
  36. /// read from the light prepass.
  37. /*
  38. if ( fd.features[MFT_IsTranslucent] )
  39. {
  40. Parent::processPixMacros( macros, fd );
  41. return;
  42. }
  43. */
  44. // Pull in the uncondition method for the light info buffer
  45. NamedTexTarget *texTarget = NamedTexTarget::find( AdvancedLightBinManager::smBufferName );
  46. if ( texTarget && texTarget->getConditioner() )
  47. {
  48. ConditionerMethodDependency *unconditionMethod = texTarget->getConditioner()->getConditionerMethodDependency(ConditionerFeature::UnconditionMethod);
  49. unconditionMethod->createMethodMacro( String::ToLower( AdvancedLightBinManager::smBufferName ) + "Uncondition", macros );
  50. addDependency(unconditionMethod);
  51. }
  52. }
  53. void DeferredRTLightingFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  54. const MaterialFeatureData &fd )
  55. {
  56. /// TODO: This needs to be done via some sort of material
  57. /// feature and not just allow all translucent elements to
  58. /// read from the light prepass.
  59. /*
  60. if ( fd.features[MFT_IsTranslucent] )
  61. {
  62. Parent::processVert( componentList, fd );
  63. return;
  64. }
  65. */
  66. // Pass screen space position to pixel shader to compute a full screen buffer uv
  67. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  68. Var *ssPos = connectComp->getElement( RT_TEXCOORD );
  69. ssPos->setName( "screenspacePos" );
  70. ssPos->setType( "vec4" );
  71. // Var *outPosition = (Var*) LangElement::find( "hpos" );
  72. // AssertFatal( outPosition, "No hpos, ohnoes." );
  73. output = new GenOp( " @ = gl_Position;\r\n", ssPos );
  74. }
  75. void DeferredRTLightingFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  76. const MaterialFeatureData &fd )
  77. {
  78. /// TODO: This needs to be done via some sort of material
  79. /// feature and not just allow all translucent elements to
  80. /// read from the light prepass.
  81. /*
  82. if ( fd.features[MFT_IsTranslucent] )
  83. {
  84. Parent::processPix( componentList, fd );
  85. return;
  86. }
  87. */
  88. MultiLine *meta = new MultiLine;
  89. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  90. Var *ssPos = connectComp->getElement( RT_TEXCOORD );
  91. ssPos->setName( "screenspacePos" );
  92. ssPos->setType( "vec4" );
  93. Var *uvScene = new Var;
  94. uvScene->setType( "vec2" );
  95. uvScene->setName( "uvScene" );
  96. LangElement *uvSceneDecl = new DecOp( uvScene );
  97. Var *rtParams = (Var*) LangElement::find( "renderTargetParams" );
  98. if( !rtParams )
  99. {
  100. rtParams = new Var;
  101. rtParams->setType( "vec4" );
  102. rtParams->setName( "renderTargetParams" );
  103. rtParams->uniform = true;
  104. rtParams->constSortPos = cspPass;
  105. }
  106. meta->addStatement( new GenOp( " @ = @.xy / @.w;\r\n", uvSceneDecl, ssPos, ssPos ) ); // get the screen coord... its -1 to +1
  107. meta->addStatement( new GenOp( " @ = ( @ + 1.0 ) / 2.0;\r\n", uvScene, uvScene ) ); // get the screen coord to 0 to 1
  108. meta->addStatement( new GenOp( " @ = ( @ * @.zw ) + @.xy;\r\n", uvScene, uvScene, rtParams, rtParams) ); // scale it down and offset it to the rt size
  109. Var *lightInfoSamp = new Var;
  110. lightInfoSamp->setType( "vec4" );
  111. lightInfoSamp->setName( "lightInfoSample" );
  112. // create texture var
  113. Var *lightInfoBuffer = new Var;
  114. lightInfoBuffer->setType( "sampler2D" );
  115. lightInfoBuffer->setName( "lightInfoBuffer" );
  116. lightInfoBuffer->uniform = true;
  117. lightInfoBuffer->sampler = true;
  118. lightInfoBuffer->constNum = Var::getTexUnitNum(); // used as texture unit num here
  119. String unconditionLightInfo = String::ToLower( AdvancedLightBinManager::smBufferName ) + "Uncondition";
  120. meta->addStatement( new GenOp( " vec3 d_lightcolor;\r\n" ) );
  121. meta->addStatement( new GenOp( " float d_NL_Att;\r\n" ) );
  122. meta->addStatement( new GenOp( " float d_specular;\r\n" ) );
  123. meta->addStatement( new GenOp( avar( " %s(texture2D(@, @), d_lightcolor, d_NL_Att, d_specular);\r\n", unconditionLightInfo.c_str() ),
  124. lightInfoBuffer, uvScene ) );
  125. Var *rtShading = new Var;
  126. rtShading->setType( "vec4" );
  127. rtShading->setName( "rtShading" );
  128. LangElement *rtShadingDecl = new DecOp( rtShading );
  129. meta->addStatement( new GenOp( " @ = vec4( d_lightcolor, 1.0 );\r\n", rtShadingDecl ) );
  130. // This is kind of weak sauce
  131. if( !fd.features[MFT_SubSurface] && !fd.features[MFT_ToneMap] && !fd.features[MFT_LightMap] )
  132. meta->addStatement( new GenOp( " @;\r\n", assignColor( rtShading, Material::Mul ) ) );
  133. output = meta;
  134. }
  135. ShaderFeature::Resources DeferredRTLightingFeatGLSL::getResources( const MaterialFeatureData &fd )
  136. {
  137. /// TODO: This needs to be done via some sort of material
  138. /// feature and not just allow all translucent elements to
  139. /// read from the light prepass.
  140. /*
  141. if( fd.features[MFT_IsTranslucent] )
  142. return Parent::getResources( fd );
  143. */
  144. Resources res;
  145. res.numTex = 1;
  146. res.numTexReg = 1;
  147. return res;
  148. }
  149. void DeferredRTLightingFeatGLSL::setTexData( Material::StageData &stageDat,
  150. const MaterialFeatureData &fd,
  151. RenderPassData &passData,
  152. U32 &texIndex )
  153. {
  154. /// TODO: This needs to be done via some sort of material
  155. /// feature and not just allow all translucent elements to
  156. /// read from the light prepass.
  157. /*
  158. if( fd.features[MFT_IsTranslucent] )
  159. {
  160. Parent::setTexData( stageDat, fd, passData, texIndex );
  161. return;
  162. }
  163. */
  164. NamedTexTarget *texTarget = NamedTexTarget::find( AdvancedLightBinManager::smBufferName );
  165. if( texTarget )
  166. {
  167. passData.mTexType[ texIndex ] = Material::TexTarget;
  168. passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
  169. }
  170. }
  171. void DeferredBumpFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  172. const MaterialFeatureData &fd )
  173. {
  174. if( fd.features[MFT_PrePassConditioner] )
  175. {
  176. // There is an output conditioner active, so we need to supply a transform
  177. // to the pixel shader.
  178. MultiLine *meta = new MultiLine;
  179. // setup texture space matrix
  180. Var *texSpaceMat = (Var*) LangElement::find( "objToTangentSpace" );
  181. if( !texSpaceMat )
  182. {
  183. LangElement * texSpaceSetup = setupTexSpaceMat( componentList, &texSpaceMat );
  184. meta->addStatement( texSpaceSetup );
  185. texSpaceMat = (Var*) LangElement::find( "objToTangentSpace" );
  186. }
  187. // turn obj->tangent into world->tangent
  188. Var *worldToTangent = new Var;
  189. worldToTangent->setType( "mat3" );
  190. worldToTangent->setName( "worldToTangent" );
  191. LangElement *worldToTangentDecl = new DecOp( worldToTangent );
  192. // Get the world->obj transform
  193. Var *worldToObj = new Var;
  194. worldToObj->setType( "mat4" );
  195. worldToObj->setName( "worldToObj" );
  196. worldToObj->uniform = true;
  197. worldToObj->constSortPos = cspPrimitive;
  198. Var *mat3Conversion = new Var;
  199. mat3Conversion->setType( "mat3" );
  200. mat3Conversion->setName( "worldToObjMat3" );
  201. LangElement* mat3Lang = new DecOp(mat3Conversion);
  202. meta->addStatement( new GenOp( " @ = mat3(@[0].xyz, @[1].xyz, @[2].xyz);\r\n ", mat3Lang, worldToObj, worldToObj, worldToObj) );
  203. // assign world->tangent transform
  204. meta->addStatement( new GenOp( " @ = @ * @;\r\n", worldToTangentDecl, texSpaceMat, mat3Conversion ) );
  205. // send transform to pixel shader
  206. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  207. Var *worldToTangentR1 = connectComp->getElement( RT_TEXCOORD );
  208. worldToTangentR1->setName( "worldToTangentR1" );
  209. worldToTangentR1->setType( "vec3" );
  210. meta->addStatement( new GenOp( " @ = @[0];\r\n", worldToTangentR1, worldToTangent ) );
  211. Var *worldToTangentR2 = connectComp->getElement( RT_TEXCOORD );
  212. worldToTangentR2->setName( "worldToTangentR2" );
  213. worldToTangentR2->setType( "vec3" );
  214. meta->addStatement( new GenOp( " @ = @[1];\r\n", worldToTangentR2, worldToTangent ) );
  215. Var *worldToTangentR3 = connectComp->getElement( RT_TEXCOORD );
  216. worldToTangentR3->setName( "worldToTangentR3" );
  217. worldToTangentR3->setType( "vec3" );
  218. meta->addStatement( new GenOp( " @ = @[2];\r\n", worldToTangentR3, worldToTangent ) );
  219. // Make sure there are texcoords
  220. if( !fd.features[MFT_DiffuseMap] )
  221. {
  222. // find incoming texture var
  223. Var *inTex = getVertTexCoord( "texCoord" );
  224. // grab connector texcoord register
  225. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  226. Var *outTex = connectComp->getElement( RT_TEXCOORD );
  227. outTex->setName( "outTexCoord" );
  228. outTex->setType( "vec2" );
  229. outTex->mapsToSampler = true;
  230. if( fd.features[MFT_TexAnim] )
  231. {
  232. inTex->setType( "vec4" );
  233. // create texture mat var
  234. Var *texMat = new Var;
  235. texMat->setType( "mat4" );
  236. texMat->setName( "texMat" );
  237. texMat->uniform = true;
  238. texMat->constSortPos = cspPotentialPrimitive;
  239. meta->addStatement( new GenOp( " @ = @ * @;\r\n", outTex, texMat, inTex ) );
  240. }
  241. else
  242. {
  243. // setup language elements to output incoming tex coords to output
  244. meta->addStatement( new GenOp( " @ = @;\r\n", outTex, inTex ) );
  245. }
  246. }
  247. output = meta;
  248. }
  249. else if ( fd.materialFeatures[MFT_NormalsOut] ||
  250. fd.features[MFT_IsTranslucent] ||
  251. !fd.features[MFT_RTLighting] )
  252. {
  253. Parent::processVert( componentList, fd );
  254. return;
  255. }
  256. else
  257. {
  258. output = NULL;
  259. }
  260. }
  261. void DeferredBumpFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  262. const MaterialFeatureData &fd )
  263. {
  264. // NULL output in case nothing gets handled
  265. output = NULL;
  266. if( fd.features[MFT_PrePassConditioner] )
  267. {
  268. MultiLine *meta = new MultiLine;
  269. // Pull the world->tangent transform from the vertex shader
  270. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  271. Var *worldToTangentR1 = connectComp->getElement( RT_TEXCOORD );
  272. worldToTangentR1->setName( "worldToTangentR1" );
  273. worldToTangentR1->setType( "vec3" );
  274. Var *worldToTangentR2 = connectComp->getElement( RT_TEXCOORD );
  275. worldToTangentR2->setName( "worldToTangentR2" );
  276. worldToTangentR2->setType( "vec3" );
  277. Var *worldToTangentR3 = connectComp->getElement( RT_TEXCOORD );
  278. worldToTangentR3->setName( "worldToTangentR3" );
  279. worldToTangentR3->setType( "vec3" );
  280. Var *worldToTangent = new Var;
  281. worldToTangent->setType( "mat3" );
  282. worldToTangent->setName( "worldToTangent" );
  283. LangElement *worldToTangentDecl = new DecOp( worldToTangent );
  284. // Build world->tangent matrix
  285. meta->addStatement( new GenOp( " @;\r\n", worldToTangentDecl ) );
  286. meta->addStatement( new GenOp( " @[0] = @;\r\n", worldToTangent, worldToTangentR1 ) );
  287. meta->addStatement( new GenOp( " @[1] = @;\r\n", worldToTangent, worldToTangentR2 ) );
  288. meta->addStatement( new GenOp( " @[2] = @;\r\n", worldToTangent, worldToTangentR3 ) );
  289. // create texture var
  290. Var *bumpMap = new Var;
  291. bumpMap->setType( "sampler2D" );
  292. bumpMap->setName( "bumpMap" );
  293. bumpMap->uniform = true;
  294. bumpMap->sampler = true;
  295. bumpMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
  296. Var *texCoord = (Var*) LangElement::find( "outTexCoord" );
  297. if( !texCoord )
  298. {
  299. // grab connector texcoord register
  300. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  301. texCoord = connectComp->getElement( RT_TEXCOORD );
  302. texCoord->setName( "outTexCoord" );
  303. texCoord->setType( "vec2" );
  304. texCoord->mapsToSampler = true;
  305. }
  306. LangElement * texOp = new GenOp( "texture2D(@, @)", bumpMap, texCoord );
  307. // create bump normal
  308. Var *bumpNorm = new Var;
  309. bumpNorm->setName( "bumpNormal" );
  310. bumpNorm->setType( "vec4" );
  311. LangElement *bumpNormDecl = new DecOp( bumpNorm );
  312. meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
  313. // This var is read from GBufferConditionerHLSL and
  314. // used in the prepass output.
  315. Var *gbNormal = new Var;
  316. gbNormal->setName( "gbNormal" );
  317. gbNormal->setType( "vec3" );
  318. LangElement *gbNormalDecl = new DecOp( gbNormal );
  319. // Normalize is done later...
  320. // Note: The reverse mul order is intentional. Affine matrix.
  321. meta->addStatement( new GenOp( " @ = @.xyz * @;\r\n", gbNormalDecl, bumpNorm, worldToTangent ) );
  322. output = meta;
  323. return;
  324. }
  325. else if ( fd.materialFeatures[MFT_NormalsOut] ||
  326. fd.features[MFT_IsTranslucent] ||
  327. !fd.features[MFT_RTLighting] )
  328. {
  329. Parent::processPix( componentList, fd );
  330. return;
  331. }
  332. else if ( fd.features[MFT_PixSpecular] )
  333. {
  334. Var *bumpSample = (Var *)LangElement::find( "bumpSample" );
  335. if( bumpSample == NULL )
  336. {
  337. Var *texCoord = (Var*) LangElement::find( "outTexCoord" );
  338. if( !texCoord )
  339. {
  340. // grab connector texcoord register
  341. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  342. texCoord = connectComp->getElement( RT_TEXCOORD );
  343. texCoord->setName( "outTexCoord" );
  344. texCoord->setType( "vec2" );
  345. texCoord->mapsToSampler = true;
  346. }
  347. Var *bumpMap = new Var;
  348. bumpMap->setType( "sampler2D" );
  349. bumpMap->setName( "bumpMap" );
  350. bumpMap->uniform = true;
  351. bumpMap->sampler = true;
  352. bumpMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
  353. bumpSample = new Var;
  354. bumpSample->setType( "vec4" );
  355. bumpSample->setName( "bumpSample" );
  356. LangElement *bumpSampleDecl = new DecOp( bumpSample );
  357. output = new GenOp( " @ = texture2D(@, @);\r\n", bumpSampleDecl, bumpMap, texCoord );
  358. return;
  359. }
  360. }
  361. output = NULL;
  362. }
  363. ShaderFeature::Resources DeferredBumpFeatGLSL::getResources( const MaterialFeatureData &fd )
  364. {
  365. if ( fd.materialFeatures[MFT_NormalsOut] ||
  366. fd.features[MFT_IsTranslucent] ||
  367. fd.features[MFT_Parallax] ||
  368. !fd.features[MFT_RTLighting] )
  369. return Parent::getResources( fd );
  370. Resources res;
  371. if(!fd.features[MFT_SpecularMap])
  372. {
  373. res.numTex = 1;
  374. res.numTexReg = 1;
  375. }
  376. return res;
  377. }
  378. void DeferredBumpFeatGLSL::setTexData( Material::StageData &stageDat,
  379. const MaterialFeatureData &fd,
  380. RenderPassData &passData,
  381. U32 &texIndex )
  382. {
  383. if ( fd.materialFeatures[MFT_NormalsOut] ||
  384. fd.features[MFT_IsTranslucent] ||
  385. !fd.features[MFT_RTLighting] )
  386. {
  387. Parent::setTexData( stageDat, fd, passData, texIndex );
  388. return;
  389. }
  390. GFXTextureObject *normalMap = stageDat.getTex( MFT_NormalMap );
  391. if ( !fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
  392. ( fd.features[MFT_PrePassConditioner] ||
  393. fd.features[MFT_PixSpecular] ) &&
  394. normalMap )
  395. {
  396. passData.mTexType[ texIndex ] = Material::Bump;
  397. passData.mTexSlot[ texIndex++ ].texObject = normalMap;
  398. }
  399. }
  400. void DeferredPixelSpecularGLSL::processVert( Vector<ShaderComponent*> &componentList,
  401. const MaterialFeatureData &fd )
  402. {
  403. if( fd.features[MFT_IsTranslucent] || !fd.features[MFT_RTLighting] )
  404. {
  405. Parent::processVert( componentList, fd );
  406. return;
  407. }
  408. output = NULL;
  409. }
  410. void DeferredPixelSpecularGLSL::processPix( Vector<ShaderComponent*> &componentList,
  411. const MaterialFeatureData &fd )
  412. {
  413. if( fd.features[MFT_IsTranslucent] || !fd.features[MFT_RTLighting] )
  414. {
  415. Parent::processPix( componentList, fd );
  416. return;
  417. }
  418. MultiLine *meta = new MultiLine;
  419. Var *specular = new Var;
  420. specular->setType( "float" );
  421. specular->setName( "specular" );
  422. LangElement * specDecl = new DecOp( specular );
  423. Var *specCol = (Var*)LangElement::find( "specularColor" );
  424. if(specCol == NULL)
  425. {
  426. specCol = new Var;
  427. specCol->setType( "vec4" );
  428. specCol->setName( "specularColor" );
  429. specCol->uniform = true;
  430. specCol->constSortPos = cspPotentialPrimitive;
  431. }
  432. Var *specPow = new Var;
  433. specPow->setType( "float" );
  434. specPow->setName( "specularPower" );
  435. // If the gloss map flag is set, than the specular power is in the alpha
  436. // channel of the specular map
  437. if( fd.features[ MFT_GlossMap ] )
  438. meta->addStatement( new GenOp( " @ = @.a * 255;\r\n", new DecOp( specPow ), specCol ) );
  439. else
  440. {
  441. specPow->uniform = true;
  442. specPow->constSortPos = cspPotentialPrimitive;
  443. }
  444. Var *specStrength = new Var;
  445. specStrength->setType( "float" );
  446. specStrength->setName( "specularStrength" );
  447. specStrength->uniform = true;
  448. specStrength->constSortPos = cspPotentialPrimitive;
  449. Var *constSpecPow = new Var;
  450. constSpecPow->setType( "float" );
  451. constSpecPow->setName( "constantSpecularPower" );
  452. constSpecPow->uniform = true;
  453. constSpecPow->constSortPos = cspPass;
  454. Var *lightInfoSamp = (Var *)LangElement::find( "lightInfoSample" );
  455. AssertFatal( lightInfoSamp, "Something hosed the deferred features! Can't find lightInfoSample" );
  456. // (a^m)^n = a^(m*n)
  457. meta->addStatement( new GenOp( " @ = pow(d_specular, ceil(@ / @)) * @;\r\n", specDecl, specPow, constSpecPow, specStrength ) );
  458. LangElement *specMul = new GenOp( "@ * @", specCol, specular );
  459. LangElement *final = specMul;
  460. // We we have a normal map then mask the specular
  461. if( !fd.features[MFT_SpecularMap] && fd.features[MFT_NormalMap] )
  462. {
  463. Var *bumpSample = (Var*)LangElement::find( "bumpSample" );
  464. final = new GenOp( "@ * @.a", final, bumpSample );
  465. }
  466. // add to color meta->addStatement( new GenOp( " @;\r\n", assignColor( final, Material::Add ) ) );
  467. output = meta;
  468. }
  469. ShaderFeature::Resources DeferredPixelSpecularGLSL::getResources( const MaterialFeatureData &fd )
  470. {
  471. if( fd.features[MFT_IsTranslucent] || !fd.features[MFT_RTLighting] )
  472. return Parent::getResources( fd );
  473. Resources res;
  474. return res;
  475. }
  476. ShaderFeature::Resources DeferredMinnaertGLSL::getResources( const MaterialFeatureData &fd )
  477. {
  478. Resources res;
  479. if( !fd.features[MFT_IsTranslucent] && fd.features[MFT_RTLighting] )
  480. {
  481. res.numTex = 1;
  482. res.numTexReg = 1;
  483. }
  484. return res;
  485. }
  486. void DeferredMinnaertGLSL::setTexData( Material::StageData &stageDat,
  487. const MaterialFeatureData &fd,
  488. RenderPassData &passData,
  489. U32 &texIndex )
  490. {
  491. if( !fd.features[MFT_IsTranslucent] && fd.features[MFT_RTLighting] )
  492. {
  493. NamedTexTarget *texTarget = NamedTexTarget::find(RenderPrePassMgr::BufferName);
  494. if ( texTarget )
  495. {
  496. passData.mTexType[ texIndex ] = Material::TexTarget;
  497. passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
  498. }
  499. }
  500. }
  501. void DeferredMinnaertGLSL::processPixMacros( Vector<GFXShaderMacro> &macros,
  502. const MaterialFeatureData &fd )
  503. {
  504. if( !fd.features[MFT_IsTranslucent] && fd.features[MFT_RTLighting] )
  505. {
  506. // Pull in the uncondition method for the g buffer
  507. NamedTexTarget *texTarget = NamedTexTarget::find( RenderPrePassMgr::BufferName );
  508. if ( texTarget && texTarget->getConditioner() )
  509. {
  510. ConditionerMethodDependency *unconditionMethod = texTarget->getConditioner()->getConditionerMethodDependency(ConditionerFeature::UnconditionMethod);
  511. unconditionMethod->createMethodMacro( String::ToLower(RenderPrePassMgr::BufferName) + "Uncondition", macros );
  512. addDependency(unconditionMethod);
  513. }
  514. }
  515. }
  516. void DeferredMinnaertGLSL::processVert( Vector<ShaderComponent*> &componentList,
  517. const MaterialFeatureData &fd )
  518. {
  519. // If there is no deferred information, bail on this feature
  520. if( fd.features[MFT_IsTranslucent] || !fd.features[MFT_RTLighting] )
  521. {
  522. output = NULL;
  523. return;
  524. }
  525. // grab incoming vert position
  526. Var *inVertPos = (Var*) LangElement::find( "position" );
  527. AssertFatal( inVertPos, "Something went bad with ShaderGen. The vertex position should be already defined." );
  528. // grab output for gbuffer normal
  529. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  530. Var *outWSEyeVec= connectComp->getElement( RT_TEXCOORD );
  531. outWSEyeVec->setName( "outWSViewVec" );
  532. outWSEyeVec->setType( "vec4" );
  533. // create objToWorld variable
  534. Var *objToWorld = (Var*) LangElement::find( "objTrans" );
  535. if( !objToWorld )
  536. {
  537. objToWorld = new Var;
  538. objToWorld->setType( "mat4x4" );
  539. objToWorld->setName( "objTrans" );
  540. objToWorld->uniform = true;
  541. objToWorld->constSortPos = cspPrimitive;
  542. }
  543. // Eye Pos world
  544. Var *eyePosWorld = (Var*) LangElement::find( "eyePosWorld" );
  545. if( !eyePosWorld )
  546. {
  547. eyePosWorld = new Var;
  548. eyePosWorld->setType( "vec3" );
  549. eyePosWorld->setName( "eyePosWorld" );
  550. eyePosWorld->uniform = true;
  551. eyePosWorld->constSortPos = cspPass;
  552. }
  553. // Kick out the world-space normal
  554. LangElement *statement = new GenOp( " @ = vec4(@, @) - vec4(@, 0.0);\r\n",
  555. outWSEyeVec, objToWorld, inVertPos, eyePosWorld );
  556. output = statement;
  557. }
  558. void DeferredMinnaertGLSL::processPix( Vector<ShaderComponent*> &componentList,
  559. const MaterialFeatureData &fd )
  560. {
  561. // If there is no deferred information, bail on this feature
  562. if( fd.features[MFT_IsTranslucent] || !fd.features[MFT_RTLighting] )
  563. {
  564. output = NULL;
  565. return;
  566. }
  567. Var *minnaertConstant = new Var;
  568. minnaertConstant->setType( "float" );
  569. minnaertConstant->setName( "minnaertConstant" );
  570. minnaertConstant->uniform = true;
  571. minnaertConstant->constSortPos = cspPotentialPrimitive;
  572. // create texture var
  573. Var *prepassBuffer = new Var;
  574. prepassBuffer->setType( "sampler2D" );
  575. prepassBuffer->setName( "prepassBuffer" );
  576. prepassBuffer->uniform = true;
  577. prepassBuffer->sampler = true;
  578. prepassBuffer->constNum = Var::getTexUnitNum(); // used as texture unit num here
  579. // Texture coord
  580. Var *uvScene = (Var*) LangElement::find( "uvScene" );
  581. AssertFatal(uvScene != NULL, "Unable to find UVScene, no RTLighting feature?");
  582. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  583. Var *wsViewVec = (Var*) LangElement::find( "wsPos" );
  584. if( !wsViewVec )
  585. {
  586. wsViewVec = connectComp->getElement( RT_TEXCOORD );
  587. wsViewVec->setName( "outWSViewVec" );
  588. wsViewVec->setType( "vec4" );
  589. wsViewVec->mapsToSampler = false;
  590. wsViewVec->uniform = false;
  591. }
  592. String unconditionPrePassMethod = String::ToLower(RenderPrePassMgr::BufferName) + "Uncondition";
  593. MultiLine *meta = new MultiLine;
  594. meta->addStatement( new GenOp( avar( " vec4 normalDepth = %s(texture2D(@, @));\r\n", unconditionPrePassMethod.c_str() ), prepassBuffer, uvScene ) );
  595. meta->addStatement( new GenOp( " vec3 worldViewVec = normalize(@.xyz / @.w);\r\n", wsViewVec, wsViewVec ) );
  596. meta->addStatement( new GenOp( " float vDotN = dot(normalDepth.xyz, worldViewVec);\r\n" ) );
  597. meta->addStatement( new GenOp( " float Minnaert = pow(d_NL_Att, @) * pow(vDotN, 1.0 - @);\r\n", minnaertConstant, minnaertConstant ) );
  598. meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "vec4(Minnaert, Minnaert, Minnaert, 1.0)" ), Material::Mul ) ) );
  599. output = meta;
  600. }
  601. void DeferredSubSurfaceGLSL::processPix( Vector<ShaderComponent*> &componentList,
  602. const MaterialFeatureData &fd )
  603. {
  604. // If there is no deferred information, bail on this feature
  605. if( fd.features[MFT_IsTranslucent] || !fd.features[MFT_RTLighting] )
  606. {
  607. output = NULL;
  608. return;
  609. }
  610. Var *subSurfaceParams = new Var;
  611. subSurfaceParams->setType( "vec4" );
  612. subSurfaceParams->setName( "subSurfaceParams" );
  613. subSurfaceParams->uniform = true;
  614. subSurfaceParams->constSortPos = cspPotentialPrimitive;
  615. Var *inColor = (Var*) LangElement::find( "rtShading" );
  616. MultiLine *meta = new MultiLine;
  617. meta->addStatement( new GenOp( " float subLamb = smoothstep([email protected], 1.0, d_NL_Att) - smoothstep(0.0, 1.0, d_NL_Att);\r\n", subSurfaceParams ) );
  618. meta->addStatement( new GenOp( " subLamb = max(0.0, subLamb);\r\n" ) );
  619. meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "vec4(@.rgb + (subLamb * @.rgb), 1.0)", inColor, subSurfaceParams ), Material::Mul ) ) );
  620. output = meta;
  621. }