Advertisement
Guest User

Untitled

a guest
Jul 27th, 2016
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.81 KB | None | 0 0
  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.  
  23. #include "platform/platform.h"
  24. #include "terrain/terrCellMaterial.h"
  25.  
  26. #include "terrain/terrData.h"
  27. #include "terrain/terrCell.h"
  28. #include "materials/materialFeatureTypes.h"
  29. #include "materials/materialManager.h"
  30. #include "terrain/terrFeatureTypes.h"
  31. #include "terrain/terrMaterial.h"
  32. #include "renderInstance/renderDeferredMgr.h"
  33. #include "shaderGen/shaderGen.h"
  34. #include "shaderGen/featureMgr.h"
  35. #include "scene/sceneRenderState.h"
  36. #include "materials/sceneData.h"
  37. #include "gfx/util/screenspace.h"
  38. #include "lighting/advanced/advancedLightBinManager.h"
  39.  
  40. S32 sgMaxTerrainMaterialsPerPass = 3;
  41.  
  42. AFTER_MODULE_INIT( MaterialManager )
  43. {
  44. Con::NotifyDelegate callabck( &TerrainCellMaterial::_updateDefaultAnisotropy );
  45. Con::addVariableNotify( "$pref::Video::defaultAnisotropy", callabck );
  46. }
  47.  
  48. Vector<TerrainCellMaterial*> TerrainCellMaterial::smAllMaterials;
  49.  
  50. Vector<String> _initSamplerNames()
  51. {
  52. Vector<String> samplerNames;
  53. samplerNames.push_back("$baseTexMap");
  54. samplerNames.push_back("$layerTex");
  55. samplerNames.push_back("$macrolayerTex");
  56. samplerNames.push_back("$lightMapTex");
  57. samplerNames.push_back("$lightInfoBuffer");
  58. for(int i = 0; i < 3; ++i)
  59. {
  60. samplerNames.push_back(avar("$normalMap%d",i));
  61. samplerNames.push_back(avar("$detailMap%d",i));
  62. samplerNames.push_back(avar("$macroMap%d",i));
  63. }
  64.  
  65. return samplerNames;
  66. }
  67.  
  68.  
  69. const Vector<String> TerrainCellMaterial::mSamplerNames = _initSamplerNames();
  70.  
  71. TerrainCellMaterial::TerrainCellMaterial()
  72. : mCurrPass( 0 ),
  73. mTerrain( NULL ),
  74. mDeferredMat( NULL ),
  75. mReflectMat( NULL )
  76. {
  77. smAllMaterials.push_back( this );
  78. }
  79.  
  80. TerrainCellMaterial::~TerrainCellMaterial()
  81. {
  82. SAFE_DELETE( mDeferredMat );
  83. SAFE_DELETE( mReflectMat );
  84. smAllMaterials.remove( this );
  85. }
  86.  
  87. void TerrainCellMaterial::_updateDefaultAnisotropy()
  88. {
  89. // TODO: We need to split the stateblock initialization
  90. // from the shader constant lookup and pass setup in a
  91. // future version of terrain materials.
  92. //
  93. // For now use some custom code in a horrible loop to
  94. // change the anisotropy directly and fast.
  95. //
  96.  
  97. const U32 maxAnisotropy = MATMGR->getDefaultAnisotropy();
  98.  
  99. Vector<TerrainCellMaterial*>::iterator iter = smAllMaterials.begin();
  100. for ( ; iter != smAllMaterials.end(); iter++ )
  101. {
  102. for ( U32 p=0; p < (*iter)->mPasses.size(); p++ )
  103. {
  104. Pass &pass = (*iter)->mPasses[p];
  105.  
  106. // Start from the existing state block.
  107. GFXStateBlockDesc desc = pass.stateBlock->getDesc();
  108.  
  109. for ( U32 m=0; m < pass.materials.size(); m++ )
  110. {
  111. const MaterialInfo *matInfo = pass.materials[m];
  112.  
  113. if ( matInfo->detailTexConst->isValid() )
  114. {
  115. const S32 sampler = matInfo->detailTexConst->getSamplerRegister();
  116.  
  117. if ( maxAnisotropy > 1 )
  118. {
  119. desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
  120. desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
  121. }
  122. else
  123. desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
  124. }
  125.  
  126. if ( matInfo->macroTexConst->isValid() )
  127. {
  128. const S32 sampler = matInfo->macroTexConst->getSamplerRegister();
  129.  
  130. if ( maxAnisotropy > 1 )
  131. {
  132. desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
  133. desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
  134. }
  135. else
  136. desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
  137. }
  138.  
  139. if ( matInfo->normalTexConst->isValid() )
  140. {
  141. const S32 sampler = matInfo->normalTexConst->getSamplerRegister();
  142.  
  143. if ( maxAnisotropy > 1 )
  144. {
  145. desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
  146. desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
  147. }
  148. else
  149. desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
  150. }
  151.  
  152. } // for ( U32 m=0; m < pass.materials.size(); m++ )
  153.  
  154. // Set the updated stateblock.
  155. pass.stateBlock = GFX->createStateBlock( desc );
  156.  
  157. // Create the wireframe state blocks.
  158. GFXStateBlockDesc wireframe( desc );
  159. wireframe.fillMode = GFXFillWireframe;
  160. pass.wireframeStateBlock = GFX->createStateBlock( wireframe );
  161.  
  162. } // for ( U32 p=0; i < (*iter)->mPasses.size(); p++ )
  163. }
  164.  
  165. }
  166.  
  167. void TerrainCellMaterial::setTransformAndEye( const MatrixF &modelXfm,
  168. const MatrixF &viewXfm,
  169. const MatrixF &projectXfm,
  170. F32 farPlane )
  171. {
  172. PROFILE_SCOPE( TerrainCellMaterial_SetTransformAndEye );
  173.  
  174. MatrixF modelViewProj = projectXfm * viewXfm * modelXfm;
  175.  
  176. MatrixF invViewXfm( viewXfm );
  177. invViewXfm.inverse();
  178. Point3F eyePos = invViewXfm.getPosition();
  179.  
  180. MatrixF invModelXfm( modelXfm );
  181. invModelXfm.inverse();
  182.  
  183. Point3F objEyePos = eyePos;
  184. invModelXfm.mulP( objEyePos );
  185.  
  186. VectorF vEye = invViewXfm.getForwardVector();
  187. vEye.normalize( 1.0f / farPlane );
  188.  
  189. for ( U32 i=0; i < mPasses.size(); i++ )
  190. {
  191. Pass &pass = mPasses[i];
  192.  
  193. pass.consts->setSafe( pass.modelViewProjConst, modelViewProj );
  194.  
  195. if( pass.viewToObj->isValid() || pass.worldViewOnly->isValid() )
  196. {
  197. MatrixF worldViewOnly = viewXfm * modelXfm;
  198.  
  199. pass.consts->setSafe( pass.worldViewOnly, worldViewOnly );
  200.  
  201. if( pass.viewToObj->isValid() )
  202. {
  203. worldViewOnly.affineInverse();
  204. pass.consts->set( pass.viewToObj, worldViewOnly);
  205. }
  206. }
  207.  
  208. pass.consts->setSafe( pass.eyePosWorldConst, eyePos );
  209. pass.consts->setSafe( pass.eyePosConst, objEyePos );
  210. pass.consts->setSafe( pass.objTransConst, modelXfm );
  211. pass.consts->setSafe( pass.worldToObjConst, invModelXfm );
  212. pass.consts->setSafe( pass.vEyeConst, vEye );
  213. }
  214. }
  215.  
  216. TerrainCellMaterial* TerrainCellMaterial::getDeferredMat()
  217. {
  218. if ( !mDeferredMat )
  219. {
  220. mDeferredMat = new TerrainCellMaterial();
  221. mDeferredMat->init( mTerrain, mMaterials, true, false, mMaterials == 0 );
  222. }
  223.  
  224. return mDeferredMat;
  225. }
  226.  
  227. TerrainCellMaterial* TerrainCellMaterial::getReflectMat()
  228. {
  229. if ( !mReflectMat )
  230. {
  231. mReflectMat = new TerrainCellMaterial();
  232. mReflectMat->init( mTerrain, mMaterials, false, true, true );
  233. }
  234.  
  235. return mReflectMat;
  236. }
  237.  
  238. void TerrainCellMaterial::init( TerrainBlock *block,
  239. U64 activeMaterials,
  240. bool deferredMat,
  241. bool reflectMat,
  242. bool baseOnly )
  243. {
  244. // This isn't allowed for now.
  245. AssertFatal( !( deferredMat && reflectMat ), "TerrainCellMaterial::init - We shouldn't get deferred and reflection in the same material!" );
  246.  
  247. mTerrain = block;
  248. mMaterials = activeMaterials;
  249.  
  250. Vector<MaterialInfo*> materials;
  251.  
  252. for ( U32 i = 0; i < 64; i++ )
  253. {
  254. if ( !( mMaterials & ((U64)1 << i ) ) )
  255. continue;
  256.  
  257. TerrainMaterial *mat = block->getMaterial( i );
  258.  
  259. MaterialInfo *info = new MaterialInfo();
  260. info->layerId = i;
  261. info->mat = mat;
  262. materials.push_back( info );
  263. }
  264.  
  265. mCurrPass = 0;
  266. mPasses.clear();
  267.  
  268. // Ok... loop till we successfully generate all
  269. // the shader passes for the materials.
  270. while ( materials.size() > 0 || baseOnly )
  271. {
  272. mPasses.increment();
  273.  
  274. if ( !_createPass( &materials,
  275. &mPasses.last(),
  276. mPasses.size() == 1,
  277. deferredMat,
  278. reflectMat,
  279. baseOnly ) )
  280. {
  281. Con::errorf( "TerrainCellMaterial::init - Failed to create pass!" );
  282.  
  283. // The pass failed to be generated... give up.
  284. mPasses.last().materials.clear();
  285. mPasses.clear();
  286. for_each( materials.begin(), materials.end(), delete_pointer() );
  287. return;
  288. }
  289.  
  290. if ( baseOnly )
  291. break;
  292. }
  293.  
  294. // Cleanup any remaining matinfo.
  295. for_each( materials.begin(), materials.end(), delete_pointer() );
  296.  
  297. // If we have attached mats then update them too.
  298. if ( mDeferredMat )
  299. mDeferredMat->init( mTerrain, mMaterials, true, false, baseOnly );
  300. if ( mReflectMat )
  301. mReflectMat->init( mTerrain, mMaterials, false, true, baseOnly );
  302. }
  303.  
  304. bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
  305. Pass *pass,
  306. bool firstPass,
  307. bool deferredMat,
  308. bool reflectMat,
  309. bool baseOnly )
  310. {
  311. if ( GFX->getPixelShaderVersion() < 3.0f )
  312. baseOnly = true;
  313.  
  314. // NOTE: At maximum we only try to combine sgMaxTerrainMaterialsPerPass materials
  315. // into a single pass. This is sub-optimal for the simplest
  316. // cases, but the most common case results in much fewer
  317. // shader generation failures and permutations leading to
  318. // faster load time and less hiccups during gameplay.
  319. U32 matCount = getMin( sgMaxTerrainMaterialsPerPass, materials->size() );
  320.  
  321. Vector<GFXTexHandle> normalMaps;
  322.  
  323. // See if we're currently running under the
  324. // basic lighting manager.
  325. //
  326. // TODO: This seems ugly... we should trigger
  327. // features like this differently in the future.
  328. //
  329. bool useBLM = dStrcmp( LIGHTMGR->getId(), "BLM" ) == 0;
  330.  
  331. // Do we need to disable normal mapping?
  332. const bool disableNormalMaps = MATMGR->getExclusionFeatures().hasFeature( MFT_NormalMap ) || useBLM;
  333.  
  334. // How about parallax?
  335. const bool disableParallaxMaps = GFX->getPixelShaderVersion() < 3.0f ||
  336. MATMGR->getExclusionFeatures().hasFeature( MFT_Parallax );
  337.  
  338. // Has advanced lightmap support been enabled for deferred.
  339. bool advancedLightmapSupport = false;
  340. if ( deferredMat )
  341. {
  342. // This sucks... but it works.
  343. AdvancedLightBinManager *lightBin;
  344. if ( Sim::findObject( "AL_LightBinMgr", lightBin ) )
  345. advancedLightmapSupport = lightBin->MRTLightmapsDuringDeferred();
  346. }
  347.  
  348. // Loop till we create a valid shader!
  349. while( true )
  350. {
  351. FeatureSet features;
  352. features.addFeature( MFT_VertTransform );
  353. features.addFeature( MFT_TerrainBaseMap );
  354.  
  355. if ( deferredMat )
  356. {
  357. features.addFeature( MFT_EyeSpaceDepthOut );
  358. features.addFeature( MFT_DeferredConditioner );
  359. features.addFeature(MFT_isDeferred);
  360.  
  361. if ( advancedLightmapSupport )
  362. features.addFeature( MFT_RenderTarget3_Zero );
  363. }
  364. else
  365. {
  366. features.addFeature( MFT_RTLighting );
  367. // The HDR feature is always added... it will compile out
  368. // if HDR is not enabled in the engine.
  369. features.addFeature( MFT_HDROut );
  370. }
  371. features.addFeature(MFT_DeferredTerrainBlankInfoMap);
  372.  
  373. // Enable lightmaps and fogging if we're in BL.
  374. if ( reflectMat || useBLM )
  375. {
  376. features.addFeature( MFT_Fog );
  377. features.addFeature( MFT_ForwardShading );
  378. }
  379. if ( useBLM )
  380. features.addFeature( MFT_TerrainLightMap );
  381.  
  382. // The additional passes need to be lerp blended into the
  383. // target to maintain the results of the previous passes.
  384. if (!firstPass && deferredMat)
  385. features.addFeature( MFT_TerrainAdditive );
  386.  
  387. normalMaps.clear();
  388. pass->materials.clear();
  389.  
  390. // Now add all the material layer features.
  391.  
  392. for ( U32 i=0; i < matCount && !baseOnly; i++ )
  393. {
  394. TerrainMaterial *mat = (*materials)[i]->mat;
  395.  
  396. if ( mat == NULL )
  397. continue;
  398.  
  399. // We only include materials that
  400. // have more than a base texture.
  401. if ( mat->getDetailSize() <= 0 ||
  402. mat->getDetailDistance() <= 0 ||
  403. mat->getDetailMap().isEmpty() )
  404. continue;
  405.  
  406. S32 featureIndex = pass->materials.size();
  407.  
  408. // check for macro detail texture
  409. if ( !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
  410. {
  411. if(deferredMat)
  412. features.addFeature(MFT_isDeferred, featureIndex);
  413. features.addFeature( MFT_TerrainMacroMap, featureIndex );
  414. }
  415.  
  416. if(deferredMat)
  417. features.addFeature(MFT_isDeferred, featureIndex);
  418. features.addFeature( MFT_TerrainDetailMap, featureIndex );
  419.  
  420. pass->materials.push_back( (*materials)[i] );
  421. normalMaps.increment();
  422.  
  423. // Skip normal maps if we need to.
  424. if ( !disableNormalMaps && mat->getNormalMap().isNotEmpty() )
  425. {
  426. features.addFeature( MFT_TerrainNormalMap, featureIndex );
  427.  
  428. normalMaps.last().set( mat->getNormalMap(),
  429. &GFXDefaultStaticNormalMapProfile, "TerrainCellMaterial::_createPass() - NormalMap" );
  430.  
  431. GFXFormat normalFmt = normalMaps.last().getFormat();
  432. if ( normalFmt == GFXFormatBC3 )
  433. features.addFeature( MFT_IsBC3nm, featureIndex );
  434. else if ( normalFmt == GFXFormatBC5)
  435. features.addFeature( MFT_IsBC5nm, featureIndex);
  436.  
  437. // Do we need and can we do parallax mapping?
  438. if ( !disableParallaxMaps &&
  439. mat->getParallaxScale() > 0.0f &&
  440. !mat->useSideProjection() )
  441. features.addFeature( MFT_TerrainParallaxMap, featureIndex );
  442. }
  443.  
  444. // Is this layer got side projection?
  445. if ( mat->useSideProjection() )
  446. features.addFeature( MFT_TerrainSideProject, featureIndex );
  447. }
  448.  
  449. MaterialFeatureData featureData;
  450. featureData.features = features;
  451. featureData.materialFeatures = features;
  452.  
  453. // Check to see how many vertex shader output
  454. // registers we're gonna need.
  455. U32 numTex = 0;
  456. U32 numTexReg = 0;
  457. for ( U32 i=0; i < features.getCount(); i++ )
  458. {
  459. S32 index;
  460. const FeatureType &type = features.getAt( i, &index );
  461. ShaderFeature* sf = FEATUREMGR->getByType( type );
  462. if ( !sf )
  463. continue;
  464.  
  465. sf->setProcessIndex( index );
  466. ShaderFeature::Resources res = sf->getResources( featureData );
  467.  
  468. numTex += res.numTex;
  469. numTexReg += res.numTexReg;
  470. }
  471.  
  472. // Can we build the shader?
  473. //
  474. // NOTE: The 10 is sort of an abitrary SM 3.0
  475. // limit. Its really supposed to be 11, but that
  476. // always fails to compile so far.
  477. //
  478. if ( numTex < GFX->getNumSamplers() &&
  479. numTexReg <= 10 )
  480. {
  481. // NOTE: We really shouldn't be getting errors building the shaders,
  482. // but we can generate more instructions than the ps_2_x will allow.
  483. //
  484. // There is no way to deal with this case that i know of other than
  485. // letting the compile fail then recovering by trying to build it
  486. // with fewer materials.
  487. //
  488. // We normally disable the shader error logging so that the user
  489. // isn't fooled into thinking there is a real bug. That is until
  490. // we get down to a single material. If a single material case
  491. // fails it means it cannot generate any passes at all!
  492. const bool logErrors = matCount == 1;
  493. GFXShader::setLogging(logErrors, true);
  494.  
  495. pass->shader = SHADERGEN->getShader( featureData, getGFXVertexFormat<TerrVertex>(), NULL, mSamplerNames );
  496. }
  497.  
  498. // If we got a shader then we can continue.
  499. if ( pass->shader )
  500. break;
  501.  
  502. // If the material count is already 1 then this
  503. // is a real shader error... give up!
  504. if ( matCount <= 1 )
  505. return false;
  506.  
  507. // If we failed we next try half the input materials
  508. // so that we can more quickly arrive at a valid shader.
  509. matCount -= matCount / 2;
  510. }
  511.  
  512. // Setup the constant buffer.
  513. pass->consts = pass->shader->allocConstBuffer();
  514.  
  515. // Prepare the basic constants.
  516. pass->modelViewProjConst = pass->shader->getShaderConstHandle( "$modelview" );
  517. pass->worldViewOnly = pass->shader->getShaderConstHandle( "$worldViewOnly" );
  518. pass->viewToObj = pass->shader->getShaderConstHandle( "$viewToObj" );
  519. pass->eyePosWorldConst = pass->shader->getShaderConstHandle( "$eyePosWorld" );
  520. pass->eyePosConst = pass->shader->getShaderConstHandle( "$eyePos" );
  521. pass->vEyeConst = pass->shader->getShaderConstHandle( "$vEye" );
  522. pass->layerSizeConst = pass->shader->getShaderConstHandle( "$layerSize" );
  523. pass->objTransConst = pass->shader->getShaderConstHandle( "$objTrans" );
  524. pass->worldToObjConst = pass->shader->getShaderConstHandle( "$worldToObj" );
  525. pass->lightInfoBufferConst = pass->shader->getShaderConstHandle( "$lightInfoBuffer" );
  526. pass->baseTexMapConst = pass->shader->getShaderConstHandle( "$baseTexMap" );
  527. pass->layerTexConst = pass->shader->getShaderConstHandle( "$layerTex" );
  528. pass->fogDataConst = pass->shader->getShaderConstHandle( "$fogData" );
  529. pass->fogColorConst = pass->shader->getShaderConstHandle( "$fogColor" );
  530. pass->lightMapTexConst = pass->shader->getShaderConstHandle( "$lightMapTex" );
  531. pass->oneOverTerrainSize = pass->shader->getShaderConstHandle( "$oneOverTerrainSize" );
  532. pass->squareSize = pass->shader->getShaderConstHandle( "$squareSize" );
  533. pass->lightParamsConst = pass->shader->getShaderConstHandle( "$rtParamslightInfoBuffer" );
  534.  
  535. // Now prepare the basic stateblock.
  536. GFXStateBlockDesc desc;
  537. if ( !firstPass )
  538. {
  539. desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha );
  540.  
  541. // If this is the deferred then we don't want to
  542. // write to the last two color channels (where
  543. // depth is usually encoded).
  544. //
  545. // This trick works in combination with the
  546. // MFT_TerrainAdditive feature to lerp the
  547. // output normal with the previous pass.
  548. //
  549. //if ( deferredMat )
  550. //desc.setColorWrites( true, true, false, false );
  551. }
  552.  
  553. // We write to the zbuffer if this is a deferred
  554. // material or if the deferred is disabled.
  555. desc.setZReadWrite( true, !MATMGR->getDeferredEnabled() ||
  556. deferredMat ||
  557. reflectMat );
  558.  
  559. desc.samplersDefined = true;
  560. if ( pass->baseTexMapConst->isValid() )
  561. desc.samplers[pass->baseTexMapConst->getSamplerRegister()] = GFXSamplerStateDesc::getWrapLinear();
  562.  
  563. if ( pass->layerTexConst->isValid() )
  564. desc.samplers[pass->layerTexConst->getSamplerRegister()] = GFXSamplerStateDesc::getClampPoint();
  565.  
  566. if ( pass->lightInfoBufferConst->isValid() )
  567. desc.samplers[pass->lightInfoBufferConst->getSamplerRegister()] = GFXSamplerStateDesc::getClampPoint();
  568.  
  569. if ( pass->lightMapTexConst->isValid() )
  570. desc.samplers[pass->lightMapTexConst->getSamplerRegister()] = GFXSamplerStateDesc::getWrapLinear();
  571.  
  572. const U32 maxAnisotropy = MATMGR->getDefaultAnisotropy();
  573.  
  574. // Finally setup the material specific shader
  575. // constants and stateblock state.
  576. //
  577. // NOTE: If this changes be sure to check TerrainCellMaterial::_updateDefaultAnisotropy
  578. // to see if it needs the same changes.
  579. //
  580. for ( U32 i=0; i < pass->materials.size(); i++ )
  581. {
  582. MaterialInfo *matInfo = pass->materials[i];
  583.  
  584. matInfo->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) );
  585. matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%d", i ) );
  586.  
  587. matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) );
  588. if ( matInfo->detailTexConst->isValid() )
  589. {
  590. const S32 sampler = matInfo->detailTexConst->getSamplerRegister();
  591.  
  592. desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
  593. desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
  594. desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;
  595.  
  596. if ( maxAnisotropy > 1 )
  597. {
  598. desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
  599. desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
  600. }
  601. else
  602. desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
  603.  
  604. matInfo->detailTex.set( matInfo->mat->getDetailMap(),
  605. &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - DetailMap" );
  606. }
  607.  
  608. matInfo->macroInfoVConst = pass->shader->getShaderConstHandle( avar( "$macroScaleAndFade%d", i ) );
  609. matInfo->macroInfoPConst = pass->shader->getShaderConstHandle( avar( "$macroIdStrengthParallax%d", i ) );
  610.  
  611. matInfo->macroTexConst = pass->shader->getShaderConstHandle( avar( "$macroMap%d", i ) );
  612. if ( matInfo->macroTexConst->isValid() )
  613. {
  614. const S32 sampler = matInfo->macroTexConst->getSamplerRegister();
  615.  
  616. desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
  617. desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
  618. desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;
  619.  
  620. if ( maxAnisotropy > 1 )
  621. {
  622. desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
  623. desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
  624. }
  625. else
  626. desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
  627.  
  628. matInfo->macroTex.set( matInfo->mat->getMacroMap(),
  629. &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - MacroMap" );
  630. }
  631. //end macro texture
  632.  
  633. matInfo->normalTexConst = pass->shader->getShaderConstHandle( avar( "$normalMap%d", i ) );
  634. if ( matInfo->normalTexConst->isValid() )
  635. {
  636. const S32 sampler = matInfo->normalTexConst->getSamplerRegister();
  637.  
  638. desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
  639. desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
  640. desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;
  641.  
  642. if ( maxAnisotropy > 1 )
  643. {
  644. desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
  645. desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
  646. }
  647. else
  648. desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
  649.  
  650. matInfo->normalTex = normalMaps[i];
  651. }
  652. }
  653.  
  654. // Remove the materials we processed and leave the
  655. // ones that remain for the next pass.
  656. for ( U32 i=0; i < matCount; i++ )
  657. {
  658. MaterialInfo *matInfo = materials->first();
  659. if ( baseOnly || pass->materials.find_next( matInfo ) == -1 )
  660. delete matInfo;
  661. materials->pop_front();
  662. }
  663.  
  664. // If we're doing deferred it requires some
  665. // special stencil settings for it to work.
  666. if ( deferredMat )
  667. desc.addDesc( RenderDeferredMgr::getOpaqueStenciWriteDesc( false ) );
  668.  
  669. // Shut off culling for deferred materials (reflection support).
  670. if ( deferredMat )
  671. desc.setCullMode( GFXCullNone );
  672.  
  673. pass->stateBlock = GFX->createStateBlock( desc );
  674.  
  675. // Create the wireframe state blocks.
  676. GFXStateBlockDesc wireframe( desc );
  677. wireframe.fillMode = GFXFillWireframe;
  678. pass->wireframeStateBlock = GFX->createStateBlock( wireframe );
  679.  
  680. return true;
  681. }
  682.  
  683. void TerrainCellMaterial::_updateMaterialConsts( Pass *pass )
  684. {
  685. PROFILE_SCOPE( TerrainCellMaterial_UpdateMaterialConsts );
  686.  
  687. for ( U32 j=0; j < pass->materials.size(); j++ )
  688. {
  689. MaterialInfo *matInfo = pass->materials[j];
  690.  
  691. F32 detailSize = matInfo->mat->getDetailSize();
  692. F32 detailScale = 1.0f;
  693. if ( !mIsZero( detailSize ) )
  694. detailScale = mTerrain->getWorldBlockSize() / detailSize;
  695.  
  696. // Scale the distance by the global scalar.
  697. const F32 distance = mTerrain->smDetailScale * matInfo->mat->getDetailDistance();
  698.  
  699. // NOTE: The negation of the y scale is to make up for
  700. // my mistake early in development and passing the wrong
  701. // y texture coord into the system.
  702. //
  703. // This negation fixes detail, normal, and parallax mapping
  704. // without harming the layer id blending code.
  705. //
  706. // Eventually we should rework this to correct this little
  707. // mistake, but there isn't really a hurry to.
  708. //
  709. Point4F detailScaleAndFade( detailScale,
  710. -detailScale,
  711. distance,
  712. 0 );
  713.  
  714. if ( !mIsZero( distance ) )
  715. detailScaleAndFade.w = 1.0f / distance;
  716.  
  717. Point3F detailIdStrengthParallax( matInfo->layerId,
  718. matInfo->mat->getDetailStrength(),
  719. matInfo->mat->getParallaxScale() );
  720.  
  721. pass->consts->setSafe( matInfo->detailInfoVConst, detailScaleAndFade );
  722. pass->consts->setSafe( matInfo->detailInfoPConst, detailIdStrengthParallax );
  723.  
  724. // macro texture info
  725.  
  726. F32 macroSize = matInfo->mat->getMacroSize();
  727. F32 macroScale = 1.0f;
  728. if ( !mIsZero( macroSize ) )
  729. macroScale = mTerrain->getWorldBlockSize() / macroSize;
  730.  
  731. // Scale the distance by the global scalar.
  732. const F32 macroDistance = mTerrain->smDetailScale * matInfo->mat->getMacroDistance();
  733.  
  734. Point4F macroScaleAndFade( macroScale,
  735. -macroScale,
  736. macroDistance,
  737. 0 );
  738.  
  739. if ( !mIsZero( macroDistance ) )
  740. macroScaleAndFade.w = 1.0f / macroDistance;
  741.  
  742. Point3F macroIdStrengthParallax( matInfo->layerId,
  743. matInfo->mat->getMacroStrength(),
  744. 0 );
  745.  
  746. pass->consts->setSafe( matInfo->macroInfoVConst, macroScaleAndFade );
  747. pass->consts->setSafe( matInfo->macroInfoPConst, macroIdStrengthParallax );
  748. }
  749. }
  750.  
  751. bool TerrainCellMaterial::setupPass( const SceneRenderState *state,
  752. const SceneData &sceneData )
  753. {
  754. PROFILE_SCOPE( TerrainCellMaterial_SetupPass );
  755.  
  756. if ( mCurrPass >= mPasses.size() )
  757. {
  758. mCurrPass = 0;
  759. return false;
  760. }
  761.  
  762. Pass &pass = mPasses[mCurrPass];
  763.  
  764. _updateMaterialConsts( &pass );
  765.  
  766. if ( pass.baseTexMapConst->isValid() )
  767. GFX->setTexture( pass.baseTexMapConst->getSamplerRegister(), mTerrain->mBaseTex.getPointer() );
  768.  
  769. if ( pass.layerTexConst->isValid() )
  770. GFX->setTexture( pass.layerTexConst->getSamplerRegister(), mTerrain->mLayerTex.getPointer() );
  771.  
  772. if ( pass.lightMapTexConst->isValid() )
  773. GFX->setTexture( pass.lightMapTexConst->getSamplerRegister(), mTerrain->getLightMapTex() );
  774.  
  775. if ( sceneData.wireframe )
  776. GFX->setStateBlock( pass.wireframeStateBlock );
  777. else
  778. GFX->setStateBlock( pass.stateBlock );
  779.  
  780. GFX->setShader( pass.shader );
  781. GFX->setShaderConstBuffer( pass.consts );
  782.  
  783. // Let the light manager prepare any light stuff it needs.
  784. LIGHTMGR->setLightInfo( NULL,
  785. NULL,
  786. sceneData,
  787. state,
  788. mCurrPass,
  789. pass.consts );
  790.  
  791. for ( U32 i=0; i < pass.materials.size(); i++ )
  792. {
  793. MaterialInfo *matInfo = pass.materials[i];
  794.  
  795. if ( matInfo->detailTexConst->isValid() )
  796. GFX->setTexture( matInfo->detailTexConst->getSamplerRegister(), matInfo->detailTex );
  797. if ( matInfo->macroTexConst->isValid() )
  798. GFX->setTexture( matInfo->macroTexConst->getSamplerRegister(), matInfo->macroTex );
  799. if ( matInfo->normalTexConst->isValid() )
  800. GFX->setTexture( matInfo->normalTexConst->getSamplerRegister(), matInfo->normalTex );
  801. }
  802.  
  803. pass.consts->setSafe( pass.layerSizeConst, (F32)mTerrain->mLayerTex.getWidth() );
  804.  
  805. if ( pass.oneOverTerrainSize->isValid() )
  806. {
  807. F32 oneOverTerrainSize = 1.0f / mTerrain->getWorldBlockSize();
  808. pass.consts->set( pass.oneOverTerrainSize, oneOverTerrainSize );
  809. }
  810.  
  811. pass.consts->setSafe( pass.squareSize, mTerrain->getSquareSize() );
  812.  
  813. if ( pass.fogDataConst->isValid() )
  814. {
  815. Point3F fogData;
  816. fogData.x = sceneData.fogDensity;
  817. fogData.y = sceneData.fogDensityOffset;
  818. fogData.z = sceneData.fogHeightFalloff;
  819. pass.consts->set( pass.fogDataConst, fogData );
  820. }
  821.  
  822. pass.consts->setSafe( pass.fogColorConst, sceneData.fogColor );
  823.  
  824. if ( pass.lightInfoBufferConst->isValid() &&
  825. pass.lightParamsConst->isValid() )
  826. {
  827. if ( !mLightInfoTarget )
  828. mLightInfoTarget = NamedTexTarget::find( "directLighting" );
  829.  
  830. GFXTextureObject *texObject = mLightInfoTarget->getTexture();
  831.  
  832. // TODO: Sometimes during reset of the light manager we get a
  833. // NULL texture here. This is corrected on the next frame, but
  834. // we should still investigate why that happens.
  835.  
  836. if ( texObject )
  837. {
  838. GFX->setTexture( pass.lightInfoBufferConst->getSamplerRegister(), texObject );
  839.  
  840. const Point3I &targetSz = texObject->getSize();
  841. const RectI &targetVp = mLightInfoTarget->getViewport();
  842. Point4F rtParams;
  843. ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);
  844. pass.consts->setSafe( pass.lightParamsConst, rtParams );
  845. }
  846. }
  847.  
  848. ++mCurrPass;
  849. return true;
  850. }
  851.  
  852. BaseMatInstance* TerrainCellMaterial::getShadowMat()
  853. {
  854. // Find our material which has some settings
  855. // defined on it in script.
  856. Material *mat = MATMGR->getMaterialDefinitionByName( "AL_DefaultShadowMaterial" );
  857.  
  858. // Create the material instance adding the feature which
  859. // handles rendering terrain cut outs.
  860. FeatureSet features = MATMGR->getDefaultFeatures();
  861. BaseMatInstance *matInst = mat->createMatInstance();
  862. if ( !matInst->init( features, getGFXVertexFormat<TerrVertex>() ) )
  863. {
  864. delete matInst;
  865. matInst = NULL;
  866. }
  867.  
  868. return matInst;
  869. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement