advancedLightingFeaturesHLSL.cpp 28 KB

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