advancedLightingFeaturesHLSL.cpp 30 KB

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