advancedLightingFeaturesGLSL.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  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. // Skip deferred features, and use forward shading instead
  35. if ( fd.features[MFT_ForwardShading] )
  36. {
  37. Parent::processPixMacros( macros, fd );
  38. return;
  39. }
  40. // Pull in the uncondition method for the light info buffer
  41. NamedTexTarget *texTarget = NamedTexTarget::find( AdvancedLightBinManager::smBufferName );
  42. if ( texTarget && texTarget->getConditioner() )
  43. {
  44. ConditionerMethodDependency *unconditionMethod = texTarget->getConditioner()->getConditionerMethodDependency(ConditionerFeature::UnconditionMethod);
  45. unconditionMethod->createMethodMacro( String::ToLower( AdvancedLightBinManager::smBufferName ) + "Uncondition", macros );
  46. addDependency(unconditionMethod);
  47. }
  48. }
  49. void DeferredRTLightingFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  50. const MaterialFeatureData &fd )
  51. {
  52. // Skip deferred features, and use forward shading instead
  53. if ( fd.features[MFT_ForwardShading] )
  54. {
  55. Parent::processVert( componentList, fd );
  56. return;
  57. }
  58. // Pass screen space position to pixel shader to compute a full screen buffer uv
  59. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  60. Var *ssPos = connectComp->getElement( RT_TEXCOORD );
  61. ssPos->setName( "screenspacePos" );
  62. ssPos->setStructName( "OUT" );
  63. ssPos->setType( "vec4" );
  64. Var *outPosition = (Var*) LangElement::find( "gl_Position" );
  65. AssertFatal( outPosition, "No gl_Position, ohnoes." );
  66. output = new GenOp( " @ = @;\r\n", ssPos, outPosition );
  67. }
  68. void DeferredRTLightingFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  69. const MaterialFeatureData &fd )
  70. {
  71. // Skip deferred features, and use forward shading instead
  72. if ( fd.features[MFT_ForwardShading] )
  73. {
  74. Parent::processPix( componentList, fd );
  75. return;
  76. }
  77. MultiLine *meta = new MultiLine;
  78. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
  79. Var *ssPos = connectComp->getElement( RT_TEXCOORD );
  80. ssPos->setName( "screenspacePos" );
  81. ssPos->setStructName( "IN" );
  82. ssPos->setType( "vec4" );
  83. Var *uvScene = new Var;
  84. uvScene->setType( "vec2" );
  85. uvScene->setName( "uvScene" );
  86. LangElement *uvSceneDecl = new DecOp( uvScene );
  87. String rtParamName = String::ToString( "rtParams%s", "lightInfoBuffer" );
  88. Var *rtParams = (Var*) LangElement::find( rtParamName );
  89. if( !rtParams )
  90. {
  91. rtParams = new Var;
  92. rtParams->setType( "vec4" );
  93. rtParams->setName( rtParamName );
  94. rtParams->uniform = true;
  95. rtParams->constSortPos = cspPass;
  96. }
  97. meta->addStatement( new GenOp( " @ = @.xy / @.w;\r\n", uvSceneDecl, ssPos, ssPos ) ); // get the screen coord... its -1 to +1
  98. meta->addStatement( new GenOp( " @ = ( @ + 1.0 ) / 2.0;\r\n", uvScene, uvScene ) ); // get the screen coord to 0 to 1
  99. meta->addStatement( new GenOp( " @.y = 1.0 - @.y;\r\n", uvScene, uvScene ) ); // flip the y axis
  100. meta->addStatement( new GenOp( " @ = ( @ * @.zw ) + @.xy;\r\n", uvScene, uvScene, rtParams, rtParams) ); // scale it down and offset it to the rt size
  101. Var *lightInfoSamp = new Var;
  102. lightInfoSamp->setType( "vec4" );
  103. lightInfoSamp->setName( "lightInfoSample" );
  104. // create texture var
  105. Var *lightInfoBuffer = new Var;
  106. lightInfoBuffer->setType( "sampler2D" );
  107. lightInfoBuffer->setName( "lightInfoBuffer" );
  108. lightInfoBuffer->uniform = true;
  109. lightInfoBuffer->sampler = true;
  110. lightInfoBuffer->constNum = Var::getTexUnitNum(); // used as texture unit num here
  111. // Declare the RTLighting variables in this feature, they will either be assigned
  112. // in this feature, or in the tonemap/lightmap feature
  113. Var *d_lightcolor = new Var( "d_lightcolor", "vec3" );
  114. meta->addStatement( new GenOp( " @;\r\n", new DecOp( d_lightcolor ) ) );
  115. Var *d_NL_Att = new Var( "d_NL_Att", "float" );
  116. meta->addStatement( new GenOp( " @;\r\n", new DecOp( d_NL_Att ) ) );
  117. Var *d_specular = new Var( "d_specular", "float" );
  118. meta->addStatement( new GenOp( " @;\r\n", new DecOp( d_specular ) ) );
  119. // Perform the uncondition here.
  120. String unconditionLightInfo = String::ToLower( AdvancedLightBinManager::smBufferName ) + "Uncondition";
  121. meta->addStatement( new GenOp( avar( " %s(tex2D(@, @), @, @, @);\r\n",
  122. unconditionLightInfo.c_str() ), lightInfoBuffer, uvScene, d_lightcolor, d_NL_Att, d_specular ) );
  123. // If this has an interlaced pre-pass, do averaging here
  124. if( fd.features[MFT_InterlacedPrePass] )
  125. {
  126. Var *oneOverTargetSize = (Var*) LangElement::find( "oneOverTargetSize" );
  127. if( !oneOverTargetSize )
  128. {
  129. oneOverTargetSize = new Var;
  130. oneOverTargetSize->setType( "vec2" );
  131. oneOverTargetSize->setName( "oneOverTargetSize" );
  132. oneOverTargetSize->uniform = true;
  133. oneOverTargetSize->constSortPos = cspPass;
  134. }
  135. meta->addStatement( new GenOp( " float id_NL_Att, id_specular;\r\n vec3 id_lightcolor;\r\n" ) );
  136. meta->addStatement( new GenOp( avar( " %s(tex2D(@, @ + vec2(0.0, @.y)), id_lightcolor, id_NL_Att, id_specular);\r\n",
  137. unconditionLightInfo.c_str() ), lightInfoBuffer, uvScene, oneOverTargetSize ) );
  138. meta->addStatement( new GenOp(" @ = lerp(@, id_lightcolor, 0.5);\r\n", d_lightcolor, d_lightcolor ) );
  139. meta->addStatement( new GenOp(" @ = lerp(@, id_NL_Att, 0.5);\r\n", d_NL_Att, d_NL_Att ) );
  140. meta->addStatement( new GenOp(" @ = lerp(@, id_specular, 0.5);\r\n", d_specular, d_specular ) );
  141. }
  142. // This is kind of weak sauce
  143. if( !fd.features[MFT_VertLit] && !fd.features[MFT_ToneMap] && !fd.features[MFT_LightMap] && !fd.features[MFT_SubSurface] )
  144. meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "vec4(@, 1.0)", d_lightcolor ), Material::Mul ) ) );
  145. output = meta;
  146. }
  147. ShaderFeature::Resources DeferredRTLightingFeatGLSL::getResources( const MaterialFeatureData &fd )
  148. {
  149. // Skip deferred features, and use forward shading instead
  150. if ( fd.features[MFT_ForwardShading] )
  151. return Parent::getResources( fd );
  152. // HACK: See DeferredRTLightingFeatGLSL::setTexData.
  153. mLastTexIndex = 0;
  154. Resources res;
  155. res.numTex = 1;
  156. res.numTexReg = 1;
  157. return res;
  158. }
  159. void DeferredRTLightingFeatGLSL::setTexData( Material::StageData &stageDat,
  160. const MaterialFeatureData &fd,
  161. RenderPassData &passData,
  162. U32 &texIndex )
  163. {
  164. // Skip deferred features, and use forward shading instead
  165. if ( fd.features[MFT_ForwardShading] )
  166. {
  167. Parent::setTexData( stageDat, fd, passData, texIndex );
  168. return;
  169. }
  170. NamedTexTarget *texTarget = NamedTexTarget::find( AdvancedLightBinManager::smBufferName );
  171. if( texTarget )
  172. {
  173. // HACK: We store this for use in DeferredRTLightingFeatGLSL::processPix()
  174. // which cannot deduce the texture unit itself.
  175. mLastTexIndex = texIndex;
  176. passData.mTexType[ texIndex ] = Material::TexTarget;
  177. passData.mSamplerNames[ texIndex ]= "lightInfoBuffer";
  178. passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
  179. }
  180. }
  181. void DeferredBumpFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  182. const MaterialFeatureData &fd )
  183. {
  184. if( fd.features[MFT_PrePassConditioner] )
  185. {
  186. // There is an output conditioner active, so we need to supply a transform
  187. // to the pixel shader.
  188. MultiLine *meta = new MultiLine;
  189. // We need the view to tangent space transform in the pixel shader.
  190. getOutViewToTangent( componentList, meta, fd );
  191. const bool useTexAnim = fd.features[MFT_TexAnim];
  192. // Make sure there are texcoords
  193. if( !fd.features[MFT_Parallax] && !fd.features[MFT_DiffuseMap] )
  194. {
  195. getOutTexCoord( "texCoord",
  196. "vec2",
  197. true,
  198. useTexAnim,
  199. meta,
  200. componentList );
  201. }
  202. if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
  203. addOutDetailTexCoord( componentList,
  204. meta,
  205. useTexAnim );
  206. output = meta;
  207. }
  208. else if ( fd.materialFeatures[MFT_NormalsOut] ||
  209. fd.features[MFT_ForwardShading] ||
  210. !fd.features[MFT_RTLighting] )
  211. {
  212. Parent::processVert( componentList, fd );
  213. return;
  214. }
  215. else
  216. {
  217. output = NULL;
  218. }
  219. }
  220. void DeferredBumpFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  221. const MaterialFeatureData &fd )
  222. {
  223. // NULL output in case nothing gets handled
  224. output = NULL;
  225. if( fd.features[MFT_PrePassConditioner] )
  226. {
  227. MultiLine *meta = new MultiLine;
  228. Var *viewToTangent = getInViewToTangent( componentList );
  229. // create texture var
  230. Var *bumpMap = getNormalMapTex();
  231. Var *texCoord = getInTexCoord( "texCoord", "vec2", true, componentList );
  232. LangElement *texOp = new GenOp( "tex2D(@, @)", bumpMap, texCoord );
  233. // create bump normal
  234. Var *bumpNorm = new Var;
  235. bumpNorm->setName( "bumpNormal" );
  236. bumpNorm->setType( "vec4" );
  237. LangElement *bumpNormDecl = new DecOp( bumpNorm );
  238. meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
  239. // If we have a detail normal map we add the xy coords of
  240. // it to the base normal map. This gives us the effect we
  241. // want with few instructions and minial artifacts.
  242. if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
  243. {
  244. bumpMap = new Var;
  245. bumpMap->setType( "sampler2D" );
  246. bumpMap->setName( "detailBumpMap" );
  247. bumpMap->uniform = true;
  248. bumpMap->sampler = true;
  249. bumpMap->constNum = Var::getTexUnitNum();
  250. texCoord = getInTexCoord( "detCoord", "vec2", true, componentList );
  251. texOp = new GenOp( "tex2D(@, @)", bumpMap, texCoord );
  252. Var *detailBump = new Var;
  253. detailBump->setName( "detailBump" );
  254. detailBump->setType( "vec4" );
  255. meta->addStatement( expandNormalMap( texOp, new DecOp( detailBump ), detailBump, fd ) );
  256. Var *detailBumpScale = new Var;
  257. detailBumpScale->setType( "float" );
  258. detailBumpScale->setName( "detailBumpStrength" );
  259. detailBumpScale->uniform = true;
  260. detailBumpScale->constSortPos = cspPass;
  261. meta->addStatement( new GenOp( " @.xy += @.xy * @;\r\n", bumpNorm, detailBump, detailBumpScale ) );
  262. }
  263. // This var is read from GBufferConditionerGLSL and
  264. // used in the prepass output.
  265. //
  266. // By using the 'half' type here we get a bunch of partial
  267. // precision optimized code on further operations on the normal
  268. // which helps alot on older Geforce cards.
  269. //
  270. Var *gbNormal = new Var;
  271. gbNormal->setName( "gbNormal" );
  272. gbNormal->setType( "half3" );
  273. LangElement *gbNormalDecl = new DecOp( gbNormal );
  274. // Normalize is done later...
  275. // Note: The reverse mul order is intentional. Affine matrix.
  276. meta->addStatement( new GenOp( " @ = half3(tMul( @.xyz, @ ));\r\n", gbNormalDecl, bumpNorm, viewToTangent ) );
  277. output = meta;
  278. return;
  279. }
  280. else if (fd.features[MFT_AccuMap])
  281. {
  282. Var *bumpSample = (Var *)LangElement::find("bumpSample");
  283. if (bumpSample == NULL)
  284. {
  285. MultiLine *meta = new MultiLine;
  286. Var *texCoord = getInTexCoord("texCoord", "vec2", true, componentList);
  287. Var *bumpMap = getNormalMapTex();
  288. bumpSample = new Var;
  289. bumpSample->setType("vec4");
  290. bumpSample->setName("bumpSample");
  291. LangElement *bumpSampleDecl = new DecOp(bumpSample);
  292. meta->addStatement(new GenOp(" @ = tex2D(@, @);\r\n", bumpSampleDecl, bumpMap, texCoord));
  293. if (fd.features.hasFeature(MFT_DetailNormalMap))
  294. {
  295. Var *bumpMap = (Var*)LangElement::find("detailBumpMap");
  296. if (!bumpMap) {
  297. bumpMap = new Var;
  298. bumpMap->setType("sampler2D");
  299. bumpMap->setName("detailBumpMap");
  300. bumpMap->uniform = true;
  301. bumpMap->sampler = true;
  302. bumpMap->constNum = Var::getTexUnitNum();
  303. }
  304. texCoord = getInTexCoord("detCoord", "vec2", true, componentList);
  305. LangElement *texOp = new GenOp("tex2D(@, @)", bumpMap, texCoord);
  306. Var *detailBump = new Var;
  307. detailBump->setName("detailBump");
  308. detailBump->setType("vec4");
  309. meta->addStatement(expandNormalMap(texOp, new DecOp(detailBump), detailBump, fd));
  310. Var *detailBumpScale = new Var;
  311. detailBumpScale->setType("float");
  312. detailBumpScale->setName("detailBumpStrength");
  313. detailBumpScale->uniform = true;
  314. detailBumpScale->constSortPos = cspPass;
  315. meta->addStatement(new GenOp(" @.xy += @.xy * @;\r\n", bumpSample, detailBump, detailBumpScale));
  316. }
  317. output = meta;
  318. return;
  319. }
  320. }
  321. else if ( fd.materialFeatures[MFT_NormalsOut] ||
  322. fd.features[MFT_ForwardShading] ||
  323. !fd.features[MFT_RTLighting] )
  324. {
  325. Parent::processPix( componentList, fd );
  326. return;
  327. }
  328. else if ( fd.features[MFT_PixSpecular] && !fd.features[MFT_SpecularMap] )
  329. {
  330. Var *bumpSample = (Var *)LangElement::find( "bumpSample" );
  331. if( bumpSample == NULL )
  332. {
  333. Var *texCoord = getInTexCoord( "texCoord", "vec2", true, componentList );
  334. Var *bumpMap = getNormalMapTex();
  335. bumpSample = new Var;
  336. bumpSample->setType( "vec4" );
  337. bumpSample->setName( "bumpSample" );
  338. LangElement *bumpSampleDecl = new DecOp( bumpSample );
  339. output = new GenOp( " @ = tex2D(@, @);\r\n", bumpSampleDecl, bumpMap, texCoord );
  340. return;
  341. }
  342. }
  343. output = NULL;
  344. }
  345. ShaderFeature::Resources DeferredBumpFeatGLSL::getResources( const MaterialFeatureData &fd )
  346. {
  347. if ( fd.materialFeatures[MFT_NormalsOut] ||
  348. fd.features[MFT_ForwardShading] ||
  349. fd.features[MFT_Parallax] ||
  350. !fd.features[MFT_RTLighting] )
  351. return Parent::getResources( fd );
  352. Resources res;
  353. if(!fd.features[MFT_SpecularMap])
  354. {
  355. res.numTex = 1;
  356. res.numTexReg = 1;
  357. if ( fd.features[MFT_PrePassConditioner] &&
  358. fd.features.hasFeature( MFT_DetailNormalMap ) )
  359. {
  360. res.numTex += 1;
  361. if ( !fd.features.hasFeature( MFT_DetailMap ) )
  362. res.numTexReg += 1;
  363. }
  364. }
  365. return res;
  366. }
  367. void DeferredBumpFeatGLSL::setTexData( Material::StageData &stageDat,
  368. const MaterialFeatureData &fd,
  369. RenderPassData &passData,
  370. U32 &texIndex )
  371. {
  372. if ( fd.materialFeatures[MFT_NormalsOut] ||
  373. fd.features[MFT_ForwardShading] ||
  374. !fd.features[MFT_RTLighting] )
  375. {
  376. Parent::setTexData( stageDat, fd, passData, texIndex );
  377. return;
  378. }
  379. if (!fd.features[MFT_PrePassConditioner] && fd.features[MFT_AccuMap])
  380. {
  381. passData.mTexType[texIndex] = Material::Bump;
  382. passData.mSamplerNames[texIndex] = "bumpMap";
  383. passData.mTexSlot[texIndex++].texObject = stageDat.getTex(MFT_NormalMap);
  384. if (fd.features.hasFeature(MFT_DetailNormalMap))
  385. {
  386. passData.mTexType[texIndex] = Material::DetailBump;
  387. passData.mSamplerNames[texIndex] = "detailBumpMap";
  388. passData.mTexSlot[texIndex++].texObject = stageDat.getTex(MFT_DetailNormalMap);
  389. }
  390. }
  391. else if (!fd.features[MFT_Parallax] && !fd.features[MFT_SpecularMap] &&
  392. ( fd.features[MFT_PrePassConditioner] ||
  393. fd.features[MFT_PixSpecular] ) )
  394. {
  395. passData.mTexType[ texIndex ] = Material::Bump;
  396. passData.mSamplerNames[ texIndex ] = "bumpMap";
  397. passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap );
  398. if ( fd.features[MFT_PrePassConditioner] &&
  399. fd.features.hasFeature( MFT_DetailNormalMap ) )
  400. {
  401. passData.mTexType[ texIndex ] = Material::DetailBump;
  402. passData.mSamplerNames[ texIndex ] = "detailBumpMap";
  403. passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap );
  404. }
  405. }
  406. }
  407. void DeferredPixelSpecularGLSL::processVert( Vector<ShaderComponent*> &componentList,
  408. const MaterialFeatureData &fd )
  409. {
  410. if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
  411. {
  412. Parent::processVert( componentList, fd );
  413. return;
  414. }
  415. output = NULL;
  416. }
  417. void DeferredPixelSpecularGLSL::processPix( Vector<ShaderComponent*> &componentList,
  418. const MaterialFeatureData &fd )
  419. {
  420. if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
  421. {
  422. Parent::processPix( componentList, fd );
  423. return;
  424. }
  425. MultiLine *meta = new MultiLine;
  426. Var *specular = new Var;
  427. specular->setType( "float" );
  428. specular->setName( "specular" );
  429. LangElement * specDecl = new DecOp( specular );
  430. Var *specCol = (Var*)LangElement::find( "specularColor" );
  431. if(specCol == NULL)
  432. {
  433. specCol = new Var;
  434. specCol->setType( "vec4" );
  435. specCol->setName( "specularColor" );
  436. specCol->uniform = true;
  437. specCol->constSortPos = cspPotentialPrimitive;
  438. }
  439. Var *specPow = new Var;
  440. specPow->setType( "float" );
  441. specPow->setName( "specularPower" );
  442. // If the gloss map flag is set, than the specular power is in the alpha
  443. // channel of the specular map
  444. if( fd.features[ MFT_GlossMap ] )
  445. meta->addStatement( new GenOp( " @ = @.a * 255;\r\n", new DecOp( specPow ), specCol ) );
  446. else
  447. {
  448. specPow->uniform = true;
  449. specPow->constSortPos = cspPotentialPrimitive;
  450. }
  451. Var *specStrength = (Var*)LangElement::find( "specularStrength" );
  452. if (!specStrength)
  453. {
  454. specStrength = new Var( "specularStrength", "float" );
  455. specStrength->uniform = true;
  456. specStrength->constSortPos = cspPotentialPrimitive;
  457. }
  458. Var *lightInfoSamp = (Var *)LangElement::find( "lightInfoSample" );
  459. Var *d_specular = (Var*)LangElement::find( "d_specular" );
  460. Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
  461. AssertFatal( lightInfoSamp && d_specular && d_NL_Att,
  462. "DeferredPixelSpecularGLSL::processPix - Something hosed the deferred features!" );
  463. if (fd.features[MFT_AccuMap]) {
  464. // change specularity where the accu texture is applied
  465. Var *accuPlc = (Var*)LangElement::find("plc");
  466. Var *accuSpecular = (Var*)LangElement::find("accuSpecular");
  467. if (accuPlc != NULL && accuSpecular != NULL)
  468. //d_specular = clamp(lerp( d_specular, accuSpecular * d_specular, plc.a), 0, 1)
  469. meta->addStatement(new GenOp(" @ = clamp( lerp( @, @ * @, @.a), 0, 1);\r\n", d_specular, d_specular, accuSpecular, d_specular, accuPlc));
  470. }
  471. // (a^m)^n = a^(m*n)
  472. meta->addStatement( new GenOp( " @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n",
  473. specDecl, d_specular, specPow, specStrength ) );
  474. LangElement *specMul = new GenOp( "vec4( @.rgb, 0 ) * @", specCol, specular );
  475. LangElement *final = specMul;
  476. // We we have a normal map then mask the specular
  477. if( !fd.features[MFT_SpecularMap] && fd.features[MFT_NormalMap] )
  478. {
  479. Var *bumpSample = (Var*)LangElement::find( "bumpSample" );
  480. final = new GenOp( "@ * @.a", final, bumpSample );
  481. }
  482. // add to color
  483. meta->addStatement( new GenOp( " @;\r\n", assignColor( final, Material::Add ) ) );
  484. output = meta;
  485. }
  486. ShaderFeature::Resources DeferredPixelSpecularGLSL::getResources( const MaterialFeatureData &fd )
  487. {
  488. if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
  489. return Parent::getResources( fd );
  490. Resources res;
  491. return res;
  492. }
  493. ShaderFeature::Resources DeferredMinnaertGLSL::getResources( const MaterialFeatureData &fd )
  494. {
  495. Resources res;
  496. if( !fd.features[MFT_ForwardShading] && fd.features[MFT_RTLighting] )
  497. {
  498. res.numTex = 1;
  499. res.numTexReg = 1;
  500. }
  501. return res;
  502. }
  503. void DeferredMinnaertGLSL::setTexData( Material::StageData &stageDat,
  504. const MaterialFeatureData &fd,
  505. RenderPassData &passData,
  506. U32 &texIndex )
  507. {
  508. if( !fd.features[MFT_ForwardShading] && fd.features[MFT_RTLighting] )
  509. {
  510. NamedTexTarget *texTarget = NamedTexTarget::find(RenderPrePassMgr::BufferName);
  511. if ( texTarget )
  512. {
  513. passData.mTexType[texIndex] = Material::TexTarget;
  514. passData.mSamplerNames[texIndex] = "prepassBuffer";
  515. passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
  516. }
  517. }
  518. }
  519. void DeferredMinnaertGLSL::processPixMacros( Vector<GFXShaderMacro> &macros,
  520. const MaterialFeatureData &fd )
  521. {
  522. if( !fd.features[MFT_ForwardShading] && fd.features[MFT_RTLighting] )
  523. {
  524. // Pull in the uncondition method for the g buffer
  525. NamedTexTarget *texTarget = NamedTexTarget::find( RenderPrePassMgr::BufferName );
  526. if ( texTarget && texTarget->getConditioner() )
  527. {
  528. ConditionerMethodDependency *unconditionMethod = texTarget->getConditioner()->getConditionerMethodDependency(ConditionerFeature::UnconditionMethod);
  529. unconditionMethod->createMethodMacro( String::ToLower(RenderPrePassMgr::BufferName) + "Uncondition", macros );
  530. addDependency(unconditionMethod);
  531. }
  532. }
  533. }
  534. void DeferredMinnaertGLSL::processVert( Vector<ShaderComponent*> &componentList,
  535. const MaterialFeatureData &fd )
  536. {
  537. // If there is no deferred information, bail on this feature
  538. if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
  539. {
  540. output = NULL;
  541. return;
  542. }
  543. // Make sure we pass the world space position to the
  544. // pixel shader so we can calculate a view vector.
  545. MultiLine *meta = new MultiLine;
  546. addOutWsPosition( componentList, fd.features[MFT_UseInstancing], meta );
  547. output = meta;
  548. }
  549. void DeferredMinnaertGLSL::processPix( Vector<ShaderComponent*> &componentList,
  550. const MaterialFeatureData &fd )
  551. {
  552. // If there is no deferred information, bail on this feature
  553. if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
  554. {
  555. output = NULL;
  556. return;
  557. }
  558. Var *minnaertConstant = new Var;
  559. minnaertConstant->setType( "float" );
  560. minnaertConstant->setName( "minnaertConstant" );
  561. minnaertConstant->uniform = true;
  562. minnaertConstant->constSortPos = cspPotentialPrimitive;
  563. // create texture var
  564. Var *prepassBuffer = new Var;
  565. prepassBuffer->setType( "sampler2D" );
  566. prepassBuffer->setName( "prepassBuffer" );
  567. prepassBuffer->uniform = true;
  568. prepassBuffer->sampler = true;
  569. prepassBuffer->constNum = Var::getTexUnitNum(); // used as texture unit num here
  570. // Texture coord
  571. Var *uvScene = (Var*) LangElement::find( "uvScene" );
  572. AssertFatal(uvScene != NULL, "Unable to find UVScene, no RTLighting feature?");
  573. MultiLine *meta = new MultiLine;
  574. // Get the world space view vector.
  575. Var *wsViewVec = getWsView( getInWsPosition( componentList ), meta );
  576. String unconditionPrePassMethod = String::ToLower(RenderPrePassMgr::BufferName) + "Uncondition";
  577. Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
  578. meta->addStatement( new GenOp( avar( " vec4 normalDepth = %s(@, @);\r\n", unconditionPrePassMethod.c_str() ), prepassBuffer, uvScene ) );
  579. meta->addStatement( new GenOp( " float vDotN = dot(normalDepth.xyz, @);\r\n", wsViewVec ) );
  580. meta->addStatement( new GenOp( " float Minnaert = pow( @, @) * pow(vDotN, 1.0 - @);\r\n", d_NL_Att, minnaertConstant, minnaertConstant ) );
  581. meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "vec4(Minnaert, Minnaert, Minnaert, 1.0)" ), Material::Mul ) ) );
  582. output = meta;
  583. }
  584. void DeferredSubSurfaceGLSL::processPix( Vector<ShaderComponent*> &componentList,
  585. const MaterialFeatureData &fd )
  586. {
  587. // If there is no deferred information, bail on this feature
  588. if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
  589. {
  590. output = NULL;
  591. return;
  592. }
  593. Var *subSurfaceParams = new Var;
  594. subSurfaceParams->setType( "vec4" );
  595. subSurfaceParams->setName( "subSurfaceParams" );
  596. subSurfaceParams->uniform = true;
  597. subSurfaceParams->constSortPos = cspPotentialPrimitive;
  598. Var *d_lightcolor = (Var*)LangElement::find( "d_lightcolor" );
  599. Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
  600. MultiLine *meta = new MultiLine;
  601. meta->addStatement( new GenOp( " float subLamb = smoothstep([email protected], 1.0, @) - smoothstep(0.0, 1.0, @);\r\n", subSurfaceParams, d_NL_Att, d_NL_Att ) );
  602. meta->addStatement( new GenOp( " subLamb = max(0.0, subLamb);\r\n" ) );
  603. meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "vec4(@ + (subLamb * @.rgb), 1.0)", d_lightcolor, subSurfaceParams ), Material::Mul ) ) );
  604. output = meta;
  605. }