advancedLightingFeaturesGLSL.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  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/renderDeferredMgr.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_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 DeferredRTLightingFeatGLSL::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( "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_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( "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", "diffuseLightingBuffer" );
  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. // create texture var
  102. Var *lightInfoBuffer = new Var;
  103. lightInfoBuffer->setType( "sampler2D" );
  104. lightInfoBuffer->setName( "diffuseLightingBuffer" );
  105. lightInfoBuffer->uniform = true;
  106. lightInfoBuffer->sampler = true;
  107. lightInfoBuffer->constNum = Var::getTexUnitNum(); // used as texture unit num here
  108. // Declare the RTLighting variables in this feature, they will either be assigned
  109. // in this feature, or in the tonemap/lightmap feature
  110. Var *d_lightcolor = new Var( "d_lightcolor", "vec3" );
  111. meta->addStatement( new GenOp( " @;\r\n", new DecOp( d_lightcolor ) ) );
  112. Var *d_NL_Att = new Var( "d_NL_Att", "float" );
  113. meta->addStatement( new GenOp( " @;\r\n", new DecOp( d_NL_Att ) ) );
  114. Var *d_specular = new Var( "d_specular", "float" );
  115. meta->addStatement( new GenOp( " @;\r\n", new DecOp( d_specular ) ) );
  116. // Perform the uncondition here.
  117. String unconditionLightInfo = String::ToLower( AdvancedLightBinManager::smBufferName ) + "Uncondition";
  118. meta->addStatement( new GenOp( avar( " %s(tex2D(@, @), @, @, @);\r\n",
  119. unconditionLightInfo.c_str() ), lightInfoBuffer, uvScene, d_lightcolor, d_NL_Att, d_specular ) );
  120. // This is kind of weak sauce
  121. if( !fd.features[MFT_VertLit] && !fd.features[MFT_ToneMap] && !fd.features[MFT_LightMap] && !fd.features[MFT_SubSurface] )
  122. meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "vec4(@, 1.0)", d_lightcolor ), Material::Mul ) ) );
  123. output = meta;
  124. }
  125. ShaderFeature::Resources DeferredRTLightingFeatGLSL::getResources( const MaterialFeatureData &fd )
  126. {
  127. // Skip deferred features, and use forward shading instead
  128. if ( !fd.features[MFT_isDeferred] )
  129. return Parent::getResources( fd );
  130. // HACK: See DeferredRTLightingFeatGLSL::setTexData.
  131. mLastTexIndex = 0;
  132. Resources res;
  133. res.numTex = 1;
  134. res.numTexReg = 1;
  135. return res;
  136. }
  137. void DeferredRTLightingFeatGLSL::setTexData( Material::StageData &stageDat,
  138. const MaterialFeatureData &fd,
  139. RenderPassData &passData,
  140. U32 &texIndex )
  141. {
  142. // Skip deferred features, and use forward shading instead
  143. if ( !fd.features[MFT_isDeferred] )
  144. {
  145. Parent::setTexData( stageDat, fd, passData, texIndex );
  146. return;
  147. }
  148. NamedTexTarget *texTarget = NamedTexTarget::find( AdvancedLightBinManager::smBufferName );
  149. if( texTarget )
  150. {
  151. // HACK: We store this for use in DeferredRTLightingFeatGLSL::processPix()
  152. // which cannot deduce the texture unit itself.
  153. mLastTexIndex = texIndex;
  154. passData.mTexType[ texIndex ] = Material::TexTarget;
  155. passData.mSamplerNames[ texIndex ]= "diffuseLightingBuffer";
  156. passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
  157. }
  158. }
  159. void DeferredBumpFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
  160. const MaterialFeatureData &fd )
  161. {
  162. if( fd.features[MFT_DeferredConditioner] )
  163. {
  164. // There is an output conditioner active, so we need to supply a transform
  165. // to the pixel shader.
  166. MultiLine *meta = new MultiLine;
  167. // We need the view to tangent space transform in the pixel shader.
  168. getOutViewToTangent( componentList, meta, fd );
  169. const bool useTexAnim = fd.features[MFT_TexAnim];
  170. // Make sure there are texcoords
  171. if( !fd.features[MFT_Parallax] && !fd.features[MFT_DiffuseMap])
  172. {
  173. getOutTexCoord( "texCoord",
  174. "vec2",
  175. useTexAnim,
  176. meta,
  177. componentList );
  178. }
  179. const bool useFoliageTexCoord = fd.features[MFT_Foliage];
  180. if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
  181. addOutDetailTexCoord( componentList,
  182. meta,
  183. useTexAnim, useFoliageTexCoord);
  184. output = meta;
  185. }
  186. else if ( fd.materialFeatures[MFT_NormalsOut] ||
  187. !fd.features[MFT_isDeferred] ||
  188. !fd.features[MFT_RTLighting] )
  189. {
  190. Parent::processVert( componentList, fd );
  191. return;
  192. }
  193. else
  194. {
  195. output = NULL;
  196. }
  197. }
  198. void DeferredBumpFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
  199. const MaterialFeatureData &fd )
  200. {
  201. // NULL output in case nothing gets handled
  202. output = NULL;
  203. if( fd.features[MFT_DeferredConditioner] )
  204. {
  205. MultiLine *meta = new MultiLine;
  206. Var *viewToTangent = getInViewToTangent( componentList );
  207. // create texture var
  208. Var *bumpMap = getNormalMapTex();
  209. Var *texCoord = getInTexCoord( "texCoord", "vec2", componentList );
  210. LangElement *texOp = new GenOp( "tex2D(@, @)", bumpMap, texCoord );
  211. // create bump normal
  212. Var *bumpNorm = new Var;
  213. bumpNorm->setName( "bumpNormal" );
  214. bumpNorm->setType( "vec4" );
  215. LangElement *bumpNormDecl = new DecOp( bumpNorm );
  216. meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
  217. // If we have a detail normal map we add the xy coords of
  218. // it to the base normal map. This gives us the effect we
  219. // want with few instructions and minial artifacts.
  220. if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
  221. {
  222. bumpMap = new Var;
  223. bumpMap->setType( "sampler2D" );
  224. bumpMap->setName( "detailBumpMap" );
  225. bumpMap->uniform = true;
  226. bumpMap->sampler = true;
  227. bumpMap->constNum = Var::getTexUnitNum();
  228. texCoord = getInTexCoord( "detCoord", "vec2", componentList );
  229. texOp = new GenOp( "tex2D(@, @)", bumpMap, texCoord );
  230. Var *detailBump = new Var;
  231. detailBump->setName( "detailBump" );
  232. detailBump->setType( "vec4" );
  233. meta->addStatement( expandNormalMap( texOp, new DecOp( detailBump ), detailBump, fd ) );
  234. Var *detailBumpScale = new Var;
  235. detailBumpScale->setType( "float" );
  236. detailBumpScale->setName( "detailBumpStrength" );
  237. detailBumpScale->uniform = true;
  238. detailBumpScale->constSortPos = cspPass;
  239. meta->addStatement( new GenOp( " @.xy += @.xy * @;\r\n", bumpNorm, detailBump, detailBumpScale ) );
  240. }
  241. // This var is read from GBufferConditionerGLSL and
  242. // used in the deferred output.
  243. //
  244. // By using the 'half' type here we get a bunch of partial
  245. // precision optimized code on further operations on the normal
  246. // which helps alot on older Geforce cards.
  247. //
  248. Var *gbNormal = new Var;
  249. gbNormal->setName( "gbNormal" );
  250. gbNormal->setType( "half3" );
  251. LangElement *gbNormalDecl = new DecOp( gbNormal );
  252. // Normalize is done later...
  253. // Note: The reverse mul order is intentional. Affine matrix.
  254. meta->addStatement( new GenOp( " @ = half3(tMul( @.xyz, @ ));\r\n", gbNormalDecl, bumpNorm, viewToTangent ) );
  255. output = meta;
  256. return;
  257. }
  258. else if (fd.features[MFT_AccuMap])
  259. {
  260. Var *bumpSample = (Var *)LangElement::find("bumpSample");
  261. if (bumpSample == NULL)
  262. {
  263. MultiLine *meta = new MultiLine;
  264. Var *texCoord = getInTexCoord("texCoord", "vec2", componentList);
  265. Var *bumpMap = getNormalMapTex();
  266. bumpSample = new Var;
  267. bumpSample->setType("vec4");
  268. bumpSample->setName("bumpSample");
  269. LangElement *bumpSampleDecl = new DecOp(bumpSample);
  270. meta->addStatement(new GenOp(" @ = tex2D(@, @);\r\n", bumpSampleDecl, bumpMap, texCoord));
  271. if (fd.features.hasFeature(MFT_DetailNormalMap))
  272. {
  273. bumpMap = (Var*)LangElement::find("detailBumpMap");
  274. if (!bumpMap) {
  275. bumpMap = new Var;
  276. bumpMap->setType("sampler2D");
  277. bumpMap->setName("detailBumpMap");
  278. bumpMap->uniform = true;
  279. bumpMap->sampler = true;
  280. bumpMap->constNum = Var::getTexUnitNum();
  281. }
  282. texCoord = getInTexCoord("detCoord", "vec2", componentList);
  283. LangElement *texOp = new GenOp("tex2D(@, @)", bumpMap, texCoord);
  284. Var *detailBump = new Var;
  285. detailBump->setName("detailBump");
  286. detailBump->setType("vec4");
  287. meta->addStatement(expandNormalMap(texOp, new DecOp(detailBump), detailBump, fd));
  288. Var *detailBumpScale = new Var;
  289. detailBumpScale->setType("float");
  290. detailBumpScale->setName("detailBumpStrength");
  291. detailBumpScale->uniform = true;
  292. detailBumpScale->constSortPos = cspPass;
  293. meta->addStatement(new GenOp(" @.xy += @.xy * @;\r\n", bumpSample, detailBump, detailBumpScale));
  294. }
  295. output = meta;
  296. return;
  297. }
  298. }
  299. else if ( fd.materialFeatures[MFT_NormalsOut] ||
  300. !fd.features[MFT_isDeferred] ||
  301. !fd.features[MFT_RTLighting] )
  302. {
  303. Parent::processPix( componentList, fd );
  304. return;
  305. }
  306. else if (!fd.features[MFT_OrmMap] )
  307. {
  308. Var *bumpSample = (Var *)LangElement::find( "bumpSample" );
  309. if( bumpSample == NULL )
  310. {
  311. Var *texCoord = getInTexCoord( "texCoord", "vec2", componentList );
  312. Var *bumpMap = getNormalMapTex();
  313. bumpSample = new Var;
  314. bumpSample->setType( "vec4" );
  315. bumpSample->setName( "bumpSample" );
  316. LangElement *bumpSampleDecl = new DecOp( bumpSample );
  317. output = new GenOp( " @ = tex2D(@, @);\r\n", bumpSampleDecl, bumpMap, texCoord );
  318. return;
  319. }
  320. }
  321. output = NULL;
  322. }
  323. ShaderFeature::Resources DeferredBumpFeatGLSL::getResources( const MaterialFeatureData &fd )
  324. {
  325. if ( fd.materialFeatures[MFT_NormalsOut] ||
  326. !fd.features[MFT_isDeferred] ||
  327. fd.features[MFT_Parallax] ||
  328. !fd.features[MFT_RTLighting] )
  329. return Parent::getResources( fd );
  330. Resources res;
  331. if(!fd.features[MFT_OrmMap])
  332. {
  333. res.numTex = 1;
  334. res.numTexReg = 1;
  335. if ( fd.features[MFT_DeferredConditioner] &&
  336. fd.features.hasFeature( MFT_DetailNormalMap ) )
  337. {
  338. res.numTex += 1;
  339. if ( !fd.features.hasFeature( MFT_DetailMap ) )
  340. res.numTexReg += 1;
  341. }
  342. }
  343. return res;
  344. }
  345. void DeferredBumpFeatGLSL::setTexData( Material::StageData &stageDat,
  346. const MaterialFeatureData &fd,
  347. RenderPassData &passData,
  348. U32 &texIndex )
  349. {
  350. if ( fd.materialFeatures[MFT_NormalsOut] ||
  351. !fd.features[MFT_isDeferred] ||
  352. !fd.features[MFT_RTLighting] )
  353. {
  354. Parent::setTexData( stageDat, fd, passData, texIndex );
  355. return;
  356. }
  357. if (!fd.features[MFT_DeferredConditioner] && fd.features[MFT_AccuMap])
  358. {
  359. passData.mTexType[texIndex] = Material::Bump;
  360. passData.mSamplerNames[texIndex] = "bumpMap";
  361. passData.mTexSlot[texIndex++].texObject = stageDat.getTex(MFT_NormalMap);
  362. if (fd.features.hasFeature(MFT_DetailNormalMap))
  363. {
  364. passData.mTexType[texIndex] = Material::DetailBump;
  365. passData.mSamplerNames[texIndex] = "detailBumpMap";
  366. passData.mTexSlot[texIndex++].texObject = stageDat.getTex(MFT_DetailNormalMap);
  367. }
  368. }
  369. else if (!fd.features[MFT_Parallax] && !fd.features[MFT_OrmMap] &&
  370. ( fd.features[MFT_DeferredConditioner]) )
  371. {
  372. passData.mTexType[ texIndex ] = Material::Bump;
  373. passData.mSamplerNames[ texIndex ] = "bumpMap";
  374. passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap );
  375. if ( fd.features[MFT_DeferredConditioner] &&
  376. fd.features.hasFeature( MFT_DetailNormalMap ) )
  377. {
  378. passData.mTexType[ texIndex ] = Material::DetailBump;
  379. passData.mSamplerNames[ texIndex ] = "detailBumpMap";
  380. passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap );
  381. }
  382. }
  383. }
  384. ShaderFeature::Resources DeferredMinnaertGLSL::getResources( const MaterialFeatureData &fd )
  385. {
  386. Resources res;
  387. if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] )
  388. {
  389. res.numTex = 1;
  390. res.numTexReg = 1;
  391. }
  392. return res;
  393. }
  394. void DeferredMinnaertGLSL::setTexData( Material::StageData &stageDat,
  395. const MaterialFeatureData &fd,
  396. RenderPassData &passData,
  397. U32 &texIndex )
  398. {
  399. if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] )
  400. {
  401. NamedTexTarget *texTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName);
  402. if ( texTarget )
  403. {
  404. passData.mTexType[texIndex] = Material::TexTarget;
  405. passData.mSamplerNames[texIndex] = "deferredBuffer";
  406. passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
  407. }
  408. }
  409. }
  410. void DeferredMinnaertGLSL::processPixMacros( Vector<GFXShaderMacro> &macros,
  411. const MaterialFeatureData &fd )
  412. {
  413. if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] )
  414. {
  415. // Pull in the uncondition method for the g buffer
  416. NamedTexTarget *texTarget = NamedTexTarget::find( RenderDeferredMgr::BufferName );
  417. if ( texTarget && texTarget->getConditioner() )
  418. {
  419. ConditionerMethodDependency *unconditionMethod = texTarget->getConditioner()->getConditionerMethodDependency(ConditionerFeature::UnconditionMethod);
  420. unconditionMethod->createMethodMacro( String::ToLower(RenderDeferredMgr::BufferName) + "Uncondition", macros );
  421. addDependency(unconditionMethod);
  422. }
  423. }
  424. }
  425. void DeferredMinnaertGLSL::processVert( Vector<ShaderComponent*> &componentList,
  426. const MaterialFeatureData &fd )
  427. {
  428. // If there is no deferred information, bail on this feature
  429. if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
  430. {
  431. output = NULL;
  432. return;
  433. }
  434. // Make sure we pass the world space position to the
  435. // pixel shader so we can calculate a view vector.
  436. MultiLine *meta = new MultiLine;
  437. addOutWsPosition( componentList, fd.features[MFT_UseInstancing], meta );
  438. output = meta;
  439. }
  440. void DeferredMinnaertGLSL::processPix( Vector<ShaderComponent*> &componentList,
  441. const MaterialFeatureData &fd )
  442. {
  443. // If there is no deferred information, bail on this feature
  444. if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
  445. {
  446. output = NULL;
  447. return;
  448. }
  449. Var *minnaertConstant = new Var;
  450. minnaertConstant->setType( "float" );
  451. minnaertConstant->setName( "minnaertConstant" );
  452. minnaertConstant->uniform = true;
  453. minnaertConstant->constSortPos = cspPotentialPrimitive;
  454. // create texture var
  455. Var *deferredBuffer = new Var;
  456. deferredBuffer->setType( "sampler2D" );
  457. deferredBuffer->setName( "deferredBuffer" );
  458. deferredBuffer->uniform = true;
  459. deferredBuffer->sampler = true;
  460. deferredBuffer->constNum = Var::getTexUnitNum(); // used as texture unit num here
  461. // Texture coord
  462. Var *uvScene = (Var*) LangElement::find( "uvScene" );
  463. AssertFatal(uvScene != NULL, "Unable to find UVScene, no RTLighting feature?");
  464. MultiLine *meta = new MultiLine;
  465. // Get the world space view vector.
  466. Var *wsViewVec = getWsView( getInWsPosition( componentList ), meta );
  467. String unconditionDeferredMethod = String::ToLower(RenderDeferredMgr::BufferName) + "Uncondition";
  468. Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
  469. meta->addStatement( new GenOp( avar( " vec4 normalDepth = %s(@, @);\r\n", unconditionDeferredMethod.c_str() ), deferredBuffer, uvScene ) );
  470. meta->addStatement( new GenOp( " float vDotN = dot(normalDepth.xyz, @);\r\n", wsViewVec ) );
  471. meta->addStatement( new GenOp( " float Minnaert = pow( @, @) * pow(vDotN, 1.0 - @);\r\n", d_NL_Att, minnaertConstant, minnaertConstant ) );
  472. meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "vec4(Minnaert, Minnaert, Minnaert, 1.0)" ), Material::Mul ) ) );
  473. output = meta;
  474. }
  475. void DeferredSubSurfaceGLSL::processPix( Vector<ShaderComponent*> &componentList,
  476. const MaterialFeatureData &fd )
  477. {
  478. Var *subSurfaceParams = new Var;
  479. subSurfaceParams->setType( "vec4" );
  480. subSurfaceParams->setName( "subSurfaceParams" );
  481. subSurfaceParams->uniform = true;
  482. subSurfaceParams->constSortPos = cspPotentialPrimitive;
  483. Var *d_lightcolor = (Var*)LangElement::find( "d_lightcolor" );
  484. Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
  485. MultiLine *meta = new MultiLine;
  486. Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
  487. if (fd.features[MFT_isDeferred])
  488. {
  489. targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget3));
  490. meta->addStatement(new GenOp(" @.rgb += @.rgb*@.a;\r\n", targ, subSurfaceParams, subSurfaceParams));
  491. output = meta;
  492. return;
  493. }
  494. output = meta;
  495. }