RigsofRods
Soft-body Physics Simulation
OgreTerrainPSSMMaterialGenerator.cpp
Go to the documentation of this file.
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2012 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
29 
30 #include <Terrain/OgreTerrain.h>
31 #include <OgreMaterialManager.h>
32 #include <OgreTechnique.h>
33 #include <OgrePass.h>
34 #include <OgreTextureUnitState.h>
35 #include <OgreGpuProgramManager.h>
36 #include <OgreHighLevelGpuProgramManager.h>
37 #include <OgreHardwarePixelBuffer.h>
38 #include <OgreShadowCameraSetupPSSM.h>
39 #include <OgreHighLevelGpuProgram.h>
40 
41 namespace Ogre {
42 //---------------------------------------------------------------------
44 {
45  // define the layers
46  // We expect terrain textures to have no alpha, so we use the alpha channel
47  // in the albedo texture to store specular reflection
48  // similarly we double-up the normal and height (for parallax)
49  mLayerDecl.samplers.push_back(TerrainLayerSampler("albedo_specular", PF_BYTE_RGBA));
50  mLayerDecl.samplers.push_back(TerrainLayerSampler("normal_height", PF_BYTE_RGBA));
51 
52  mLayerDecl.elements.push_back(
53  TerrainLayerSamplerElement(0, TLSS_ALBEDO, 0, 3));
54  mLayerDecl.elements.push_back(
55  TerrainLayerSamplerElement(0, TLSS_SPECULAR, 3, 1));
56  mLayerDecl.elements.push_back(
57  TerrainLayerSamplerElement(1, TLSS_NORMAL, 0, 3));
58  mLayerDecl.elements.push_back(
59  TerrainLayerSamplerElement(1, TLSS_HEIGHT, 3, 1));
60 
61  mProfiles.push_back(OGRE_NEW SM2Profile(this, "SM2", "Profile for rendering on Shader Model 2 capable cards"));
62  // TODO - check hardware capabilities & use fallbacks if required (more profiles needed)
63  setActiveProfile("SM2");
64 }
65 
66 //---------------------------------------------------------------------
68 {
69 }
70 
71 //---------------------------------------------------------------------
72 //---------------------------------------------------------------------
73 TerrainPSSMMaterialGenerator::SM2Profile::SM2Profile(TerrainMaterialGenerator* parent, const String& name, const String& desc)
74  : Profile(parent, name, desc)
75  , mShaderGen(0)
76  , mLayerNormalMappingEnabled(true)
77  , mLayerParallaxMappingEnabled(true)
78  , mLayerSpecularMappingEnabled(true)
79  , mGlobalColourMapEnabled(true)
80  , mLightmapEnabled(true)
81  , mCompositeMapEnabled(true)
82  , mReceiveDynamicShadows(true)
83  , mPSSM(0)
84  , mDepthShadows(false)
85  , mLowLodShadows(false)
86 {
87 }
88 
89 //---------------------------------------------------------------------
91 {
92  OGRE_DELETE mShaderGen;
93 }
94 
95 //---------------------------------------------------------------------
97 {
98  terrain->_setMorphRequired(true);
99  terrain->_setNormalMapRequired(true);
100  terrain->_setLightMapRequired(mLightmapEnabled, true);
101  terrain->_setCompositeMapRequired(mCompositeMapEnabled);
102 }
103 
104 //---------------------------------------------------------------------
106 {
107  return true;
108 }
109 
110 //---------------------------------------------------------------------
112 {
113  if (enabled != mLayerNormalMappingEnabled)
114  {
115  mLayerNormalMappingEnabled = enabled;
116  mParent->_markChanged();
117  }
118 }
119 
120 //---------------------------------------------------------------------
122 {
123  if (enabled != mLayerParallaxMappingEnabled)
124  {
125  mLayerParallaxMappingEnabled = enabled;
126  mParent->_markChanged();
127  }
128 }
129 
130 //---------------------------------------------------------------------
132 {
133  if (enabled != mLayerSpecularMappingEnabled)
134  {
135  mLayerSpecularMappingEnabled = enabled;
136  mParent->_markChanged();
137  }
138 }
139 
140 //---------------------------------------------------------------------
142 {
143  if (enabled != mGlobalColourMapEnabled)
144  {
145  mGlobalColourMapEnabled = enabled;
146  mParent->_markChanged();
147  }
148 }
149 
150 //---------------------------------------------------------------------
152 {
153  if (enabled != mLightmapEnabled)
154  {
155  mLightmapEnabled = enabled;
156  mParent->_markChanged();
157  }
158 }
159 
160 //---------------------------------------------------------------------
162 {
163  if (enabled != mCompositeMapEnabled)
164  {
165  mCompositeMapEnabled = enabled;
166  mParent->_markChanged();
167  }
168 }
169 
170 //---------------------------------------------------------------------
172 {
173  if (enabled != mReceiveDynamicShadows)
174  {
175  mReceiveDynamicShadows = enabled;
176  mParent->_markChanged();
177  }
178 }
179 
180 //---------------------------------------------------------------------
182 {
183  if (pssmSettings != mPSSM)
184  {
185  mPSSM = pssmSettings;
186  mParent->_markChanged();
187  }
188 }
189 
190 //---------------------------------------------------------------------
192 {
193  if (enabled != mDepthShadows)
194  {
195  mDepthShadows = enabled;
196  mParent->_markChanged();
197  }
198 }
199 
200 //---------------------------------------------------------------------
202 {
203  if (enabled != mLowLodShadows)
204  {
205  mLowLodShadows = enabled;
206  mParent->_markChanged();
207  }
208 }
209 
210 //---------------------------------------------------------------------
212 {
213  // count the texture units free
214  uint8 freeTextureUnits = 16;
215  // lightmap
216  --freeTextureUnits;
217  // normalmap
218  --freeTextureUnits;
219  // colourmap
220  if (terrain->getGlobalColourMapEnabled())
221  --freeTextureUnits;
222  if (isShadowingEnabled(HIGH_LOD, terrain))
223  {
224  uint numShadowTextures = 1;
225  if (getReceiveDynamicShadowsPSSM())
226  {
227  numShadowTextures = getReceiveDynamicShadowsPSSM()->getSplitCount();
228  }
229  freeTextureUnits -= numShadowTextures;
230  }
231 
232  // each layer needs 2.25 units (1xdiffusespec, 1xnormalheight, 0.25xblend)
233  return static_cast<uint8>(freeTextureUnits / 2.16f);
234 }
235 
236 //---------------------------------------------------------------------
237 MaterialPtr TerrainPSSMMaterialGenerator::SM2Profile::generate(const Terrain* terrain)
238 {
239  // re-use old material if exists
240  MaterialPtr mat = terrain->_getMaterial();
241  if (mat.isNull())
242  {
243  MaterialManager& matMgr = MaterialManager::getSingleton();
244 
245  // it's important that the names are deterministic for a given terrain, so
246  // use the terrain pointer as an ID
247  const String& matName = terrain->getMaterialName();
248  mat = matMgr.getByName(matName);
249  if (mat.isNull())
250  {
251  mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
252  }
253  }
254  // clear everything
255  mat->removeAllTechniques();
256 
257  // Automatically disable normal & parallax mapping if card cannot handle it
258  // We do this rather than having a specific technique for it since it's simpler
259  GpuProgramManager& gmgr = GpuProgramManager::getSingleton();
260  if (!gmgr.isSyntaxSupported("ps_4_0") && !gmgr.isSyntaxSupported("ps_3_0") && !gmgr.isSyntaxSupported("ps_2_x")
261  && !gmgr.isSyntaxSupported("fp40") && !gmgr.isSyntaxSupported("arbfp1"))
262  {
263  setLayerNormalMappingEnabled(false);
264  setLayerParallaxMappingEnabled(false);
265  }
266 
267  addTechnique(mat, terrain, HIGH_LOD);
268 
269  // LOD
270  if (mCompositeMapEnabled)
271  {
272  addTechnique(mat, terrain, LOW_LOD);
273  Material::LodValueList lodValues;
274  lodValues.push_back(TerrainGlobalOptions::getSingleton().getCompositeMapDistance());
275  mat->setLodLevels(lodValues);
276  Technique* lowLodTechnique = mat->getTechnique(1);
277  lowLodTechnique->setLodIndex(1);
278  }
279 
280  updateParams(mat, terrain);
281 
282  return mat;
283 }
284 
285 //---------------------------------------------------------------------
287 {
288  // re-use old material if exists
289  MaterialPtr mat = terrain->_getCompositeMapMaterial();
290  if (mat.isNull())
291  {
292  MaterialManager& matMgr = MaterialManager::getSingleton();
293 
294  // it's important that the names are deterministic for a given terrain, so
295  // use the terrain pointer as an ID
296  const String& matName = terrain->getMaterialName() + "/comp";
297  mat = matMgr.getByName(matName);
298  if (mat.isNull())
299  {
300  mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
301  }
302  }
303  // clear everything
304  mat->removeAllTechniques();
305 
306  addTechnique(mat, terrain, RENDER_COMPOSITE_MAP);
307 
308  updateParamsForCompositeMap(mat, terrain);
309 
310  return mat;
311 }
312 
313 //---------------------------------------------------------------------
315  const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt)
316 {
317  Technique* tech = mat->createTechnique();
318 
319  // Only supporting one pass
320  Pass* pass = tech->createPass();
321 
322  GpuProgramManager& gmgr = GpuProgramManager::getSingleton();
323  HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton();
324  if (!mShaderGen)
325  {
326  bool check2x = mLayerNormalMappingEnabled || mLayerParallaxMappingEnabled;
327  if (hmgr.isLanguageSupported("cg"))
328  mShaderGen = OGRE_NEW ShaderHelperCg();
329  else if (hmgr.isLanguageSupported("hlsl") &&
330  ((check2x && gmgr.isSyntaxSupported("ps_4_0")) ||
331  (check2x && gmgr.isSyntaxSupported("ps_2_x")) ||
332  (!check2x && gmgr.isSyntaxSupported("ps_2_0"))))
333  mShaderGen = OGRE_NEW ShaderHelperHLSL();
334  else if (hmgr.isLanguageSupported("glsl"))
335  mShaderGen = OGRE_NEW ShaderHelperGLSL();
336  else if (hmgr.isLanguageSupported("glsles"))
337  mShaderGen = OGRE_NEW ShaderHelperGLSLES();
338  else
339  {
340  // todo
341  }
342 
343  // check SM3 features
344  mSM3Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0");
345  mSM4Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0");
346  }
347  HighLevelGpuProgramPtr vprog = mShaderGen->generateVertexProgram(this, terrain, tt);
348  HighLevelGpuProgramPtr fprog = mShaderGen->generateFragmentProgram(this, terrain, tt);
349 
350  pass->setVertexProgram(vprog->getName());
351  pass->setFragmentProgram(fprog->getName());
352 
353  if (tt == HIGH_LOD || tt == RENDER_COMPOSITE_MAP)
354  {
355  // global normal map
356  TextureUnitState* tu = pass->createTextureUnitState();
357  tu->setTextureName(terrain->getTerrainNormalMap()->getName());
358  tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
359 
360  // global colour map
361  if (terrain->getGlobalColourMapEnabled() && isGlobalColourMapEnabled())
362  {
363  tu = pass->createTextureUnitState(terrain->getGlobalColourMap()->getName());
364  tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
365  }
366 
367  // light map
368  if (isLightmapEnabled())
369  {
370  tu = pass->createTextureUnitState(terrain->getLightmap()->getName());
371  tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
372  }
373 
374  // blend maps
375  uint maxLayers = getMaxLayers(terrain);
376  uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount());
377  uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
378  for (uint i = 0; i < numBlendTextures; ++i)
379  {
380  tu = pass->createTextureUnitState(terrain->getBlendTextureName(i));
381  tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
382  }
383 
384  // layer textures
385  for (uint i = 0; i < numLayers; ++i)
386  {
387  // diffuse / specular
388  pass->createTextureUnitState(terrain->getLayerTextureName(i, 0));
389  // normal / height
390  pass->createTextureUnitState(terrain->getLayerTextureName(i, 1));
391  }
392  }
393  else
394  {
395  // LOW_LOD textures
396  // composite map
397  TextureUnitState* tu = pass->createTextureUnitState();
398  tu->setTextureName(terrain->getCompositeMap()->getName());
399  tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
400 
401  // That's it!
402  }
403 
404  // Add shadow textures (always at the end)
405  if (isShadowingEnabled(tt, terrain))
406  {
407  uint numTextures = 1;
408  if (getReceiveDynamicShadowsPSSM())
409  {
410  numTextures = getReceiveDynamicShadowsPSSM()->getSplitCount();
411  }
412  for (uint i = 0; i < numTextures; ++i)
413  {
414  TextureUnitState* tu = pass->createTextureUnitState();
415  tu->setContentType(TextureUnitState::CONTENT_SHADOW);
416  tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
417  tu->setTextureBorderColour(ColourValue::White);
418  }
419  }
420 }
421 
422 //---------------------------------------------------------------------
424 {
425  return getReceiveDynamicShadowsEnabled() && tt != RENDER_COMPOSITE_MAP &&
426  (tt != LOW_LOD || mLowLodShadows) &&
427  terrain->getSceneManager()->isShadowTechniqueTextureBased();
428 }
429 
430 //---------------------------------------------------------------------
431 void TerrainPSSMMaterialGenerator::SM2Profile::updateParams(const MaterialPtr& mat, const Terrain* terrain)
432 {
433  mShaderGen->updateParams(this, mat, terrain, false);
434 }
435 
436 //---------------------------------------------------------------------
437 void TerrainPSSMMaterialGenerator::SM2Profile::updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain)
438 {
439  mShaderGen->updateParams(this, mat, terrain, true);
440 }
441 
442 //---------------------------------------------------------------------
443 //---------------------------------------------------------------------
444 HighLevelGpuProgramPtr
446  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
447 {
448  HighLevelGpuProgramPtr ret = createVertexProgram(prof, terrain, tt);
449 
450  StringUtil::StrStreamType sourceStr;
451  generateVertexProgramSource(prof, terrain, tt, sourceStr);
452  ret->setSource(sourceStr.str());
453  ret->load();
454  defaultVpParams(prof, terrain, tt, ret);
455 #if 0
456  LogManager::getSingleton().stream(LML_TRIVIAL) << "*** Terrain Vertex Program: "
457  << ret->getName() << " ***\n" << ret->getSource() << "\n*** ***";
458 #endif
459 
460  return ret;
461 }
462 
463 //---------------------------------------------------------------------
464 HighLevelGpuProgramPtr
466  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
467 {
468  HighLevelGpuProgramPtr ret = createFragmentProgram(prof, terrain, tt);
469 
470  StringUtil::StrStreamType sourceStr;
471  generateFragmentProgramSource(prof, terrain, tt, sourceStr);
472  ret->setSource(sourceStr.str());
473  ret->load();
474  defaultFpParams(prof, terrain, tt, ret);
475 
476 #if 0
477  LogManager::getSingleton().stream(LML_TRIVIAL) << "*** Terrain Fragment Program: "
478  << ret->getName() << " ***\n" << ret->getSource() << "\n*** ***";
479 #endif
480 
481  return ret;
482 }
483 
484 //---------------------------------------------------------------------
486  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
487 {
488  generateVpHeader(prof, terrain, tt, outStream);
489 
490  if (tt != LOW_LOD)
491  {
492  uint maxLayers = prof->getMaxLayers(terrain);
493  uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
494 
495  for (uint i = 0; i < numLayers; ++i)
496  generateVpLayer(prof, terrain, tt, i, outStream);
497  }
498 
499  generateVpFooter(prof, terrain, tt, outStream);
500 }
501 
502 //---------------------------------------------------------------------
504  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
505 {
506  generateFpHeader(prof, terrain, tt, outStream);
507 
508  if (tt != LOW_LOD)
509  {
510  uint maxLayers = prof->getMaxLayers(terrain);
511  uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
512 
513  for (uint i = 0; i < numLayers; ++i)
514  generateFpLayer(prof, terrain, tt, i, outStream);
515  }
516 
517  generateFpFooter(prof, terrain, tt, outStream);
518 }
519 
520 //---------------------------------------------------------------------
522  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog)
523 {
524  GpuProgramParametersSharedPtr params = prog->getDefaultParameters();
525  params->setIgnoreMissingParams(true);
526  params->setNamedAutoConstant("worldMatrix", GpuProgramParameters::ACT_WORLD_MATRIX);
527  params->setNamedAutoConstant("viewProjMatrix", GpuProgramParameters::ACT_VIEWPROJ_MATRIX);
528  params->setNamedAutoConstant("lodMorph", GpuProgramParameters::ACT_CUSTOM,
529  Terrain::LOD_MORPH_CUSTOM_PARAM);
530  params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
531 
532  if (prof->isShadowingEnabled(tt, terrain))
533  {
534  uint numTextures = 1;
535  if (prof->getReceiveDynamicShadowsPSSM())
536  {
537  numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount();
538  }
539  for (uint i = 0; i < numTextures; ++i)
540  {
541  params->setNamedAutoConstant("texViewProjMatrix" + StringConverter::toString(i),
542  GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i);
543  /*if (prof->getReceiveDynamicShadowsDepth())
544  {
545  params->setNamedAutoConstant("depthRange" + StringConverter::toString(i),
546  GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE, i);
547  }*/
548  }
549  }
550 
551  if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP)
552  {
553  Matrix4 posIndexToObjectSpace;
554  terrain->getPointTransform(&posIndexToObjectSpace);
555  params->setNamedConstant("posIndexToObjectSpace", posIndexToObjectSpace);
556  }
557 }
558 
559 //---------------------------------------------------------------------
561  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog)
562 {
563  GpuProgramParametersSharedPtr params = prog->getDefaultParameters();
564  params->setIgnoreMissingParams(true);
565 
566  params->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
567  params->setNamedAutoConstant("lightPosObjSpace", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, 0);
568  params->setNamedAutoConstant("lightDiffuseColour", GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, 0);
569  params->setNamedAutoConstant("lightSpecularColour", GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, 0);
570  params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
571  params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
572 
573  if (prof->isShadowingEnabled(tt, terrain))
574  {
575  uint numTextures = 1;
576  if (prof->getReceiveDynamicShadowsPSSM())
577  {
578  PSSMShadowCameraSetup* pssm = prof->getReceiveDynamicShadowsPSSM();
579  numTextures = pssm->getSplitCount();
580  Vector4 splitPoints;
581  const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssm->getSplitPoints();
582  // Populate from split point 1, not 0, since split 0 isn't useful (usually 0)
583  for (uint i = 1; i < numTextures; ++i)
584  {
585  splitPoints[i - 1] = splitPointList[i];
586  }
587  params->setNamedConstant("pssmSplitPoints", splitPoints);
588  }
589 
590  if (prof->getReceiveDynamicShadowsDepth())
591  {
592  size_t samplerOffset = (tt == HIGH_LOD) ? mShadowSamplerStartHi : mShadowSamplerStartLo;
593  for (uint i = 0; i < numTextures; ++i)
594  {
595  params->setNamedAutoConstant("inverseShadowmapSize" + StringConverter::toString(i),
596  GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i + samplerOffset);
597  }
598  }
599  }
600 }
601 
602 //---------------------------------------------------------------------
604  const SM2Profile* prof, const MaterialPtr& mat, const Terrain* terrain, bool compositeMap)
605 {
606  Pass* p = mat->getTechnique(0)->getPass(0);
607  if (compositeMap)
608  {
609  updateVpParams(prof, terrain, RENDER_COMPOSITE_MAP, p->getVertexProgramParameters());
610  updateFpParams(prof, terrain, RENDER_COMPOSITE_MAP, p->getFragmentProgramParameters());
611  }
612  else
613  {
614  // high lod
615  updateVpParams(prof, terrain, HIGH_LOD, p->getVertexProgramParameters());
616  updateFpParams(prof, terrain, HIGH_LOD, p->getFragmentProgramParameters());
617 
618  if (prof->isCompositeMapEnabled())
619  {
620  // low lod
621  p = mat->getTechnique(1)->getPass(0);
622  updateVpParams(prof, terrain, LOW_LOD, p->getVertexProgramParameters());
623  updateFpParams(prof, terrain, LOW_LOD, p->getFragmentProgramParameters());
624  }
625  }
626 }
627 
628 //---------------------------------------------------------------------
630  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params)
631 {
632  params->setIgnoreMissingParams(true);
633  uint maxLayers = prof->getMaxLayers(terrain);
634  uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
635  uint numUVMul = numLayers / 4;
636  if (numLayers % 4)
637  ++numUVMul;
638  for (uint i = 0; i < numUVMul; ++i)
639  {
640  Vector4 uvMul(
641  terrain->getLayerUVMultiplier(i * 4),
642  terrain->getLayerUVMultiplier(i * 4 + 1),
643  terrain->getLayerUVMultiplier(i * 4 + 2),
644  terrain->getLayerUVMultiplier(i * 4 + 3)
645  );
646  params->setNamedConstant("uvMul_" + StringConverter::toString(i), uvMul);
647  }
648 
649  if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP)
650  {
651  Real baseUVScale = 1.0f / (terrain->getSize() - 1);
652  params->setNamedConstant("baseUVScale", baseUVScale);
653  }
654 }
655 
656 //---------------------------------------------------------------------
658  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params)
659 {
660  params->setIgnoreMissingParams(true);
661  // TODO - parameterise this?
662  Vector4 scaleBiasSpecular(0.03, -0.04, 32, 1);
663  params->setNamedConstant("scaleBiasSpecular", scaleBiasSpecular);
664 }
665 
666 //---------------------------------------------------------------------
668 {
669  uint rem = idx % 4;
670  switch (rem)
671  {
672  case 0:
673  default:
674  return "r";
675  case 1:
676  return "g";
677  case 2:
678  return "b";
679  case 3:
680  return "a";
681  };
682 }
683 
684 //---------------------------------------------------------------------
686  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
687 {
688  String progName = terrain->getMaterialName() + "/sm2/vp";
689 
690  switch (tt)
691  {
692  case HIGH_LOD:
693  progName += "/hlod";
694  break;
695  case LOW_LOD:
696  progName += "/llod";
697  break;
698  case RENDER_COMPOSITE_MAP:
699  progName += "/comp";
700  break;
701  }
702 
703  return progName;
704 }
705 
706 //---------------------------------------------------------------------
708  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
709 {
710  String progName = terrain->getMaterialName() + "/sm2/fp";
711 
712  switch (tt)
713  {
714  case HIGH_LOD:
715  progName += "/hlod";
716  break;
717  case LOW_LOD:
718  progName += "/llod";
719  break;
720  case RENDER_COMPOSITE_MAP:
721  progName += "/comp";
722  break;
723  }
724 
725  return progName;
726 }
727 
728 //---------------------------------------------------------------------
729 //---------------------------------------------------------------------
730 HighLevelGpuProgramPtr
732  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
733 {
734  HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
735  String progName = getVertexProgramName(prof, terrain, tt);
736  HighLevelGpuProgramPtr ret = mgr.getByName(progName);
737  if (ret.isNull())
738  {
739  ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
740  "cg", GPT_VERTEX_PROGRAM);
741  }
742  else
743  {
744  ret->unload();
745  }
746 
747  ret->setParameter("profiles", "vs_4_0 vs_3_0 vs_2_0 arbvp1");
748  ret->setParameter("entry_point", "main_vp");
749 
750  return ret;
751 }
752 
753 //---------------------------------------------------------------------
754 HighLevelGpuProgramPtr
756  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
757 {
758  HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
759  String progName = getFragmentProgramName(prof, terrain, tt);
760 
761  HighLevelGpuProgramPtr ret = mgr.getByName(progName);
762  if (ret.isNull())
763  {
764  ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
765  "cg", GPT_FRAGMENT_PROGRAM);
766  }
767  else
768  {
769  ret->unload();
770  }
771 
773  ret->setParameter("profiles", "ps_4_0 ps_3_0 ps_2_x fp40 arbfp1");
774  else
775  ret->setParameter("profiles", "ps_4_0 ps_3_0 ps_2_0 fp30 arbfp1");
776  ret->setParameter("entry_point", "main_fp");
777 
778  return ret;
779 }
780 
781 //---------------------------------------------------------------------
783  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
784 {
785  outStream <<
786  "void main_vp(\n";
787  bool compression = terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP;
788  if (compression)
789  {
790  outStream <<
791  "float2 posIndex : POSITION,\n"
792  "float height : TEXCOORD0,\n";
793  }
794  else
795  {
796  outStream <<
797  "float4 pos : POSITION,\n"
798  "float2 uv : TEXCOORD0,\n";
799  }
800  if (tt != RENDER_COMPOSITE_MAP)
801  outStream << "float2 delta : TEXCOORD1,\n"; // lodDelta, lodThreshold
802 
803  outStream <<
804  "uniform float4x4 worldMatrix,\n"
805  "uniform float4x4 viewProjMatrix,\n"
806  "uniform float2 lodMorph,\n"; // morph amount, morph LOD target
807 
808  if (compression)
809  {
810  outStream <<
811  "uniform float4x4 posIndexToObjectSpace,\n"
812  "uniform float baseUVScale,\n";
813  }
814  // uv multipliers
815  uint maxLayers = prof->getMaxLayers(terrain);
816  uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
817  uint numUVMultipliers = (numLayers / 4);
818  if (numLayers % 4)
819  ++numUVMultipliers;
820  for (uint i = 0; i < numUVMultipliers; ++i)
821  outStream << "uniform float4 uvMul_" << i << ", \n";
822 
823  outStream <<
824  "out float4 oPos : POSITION,\n"
825  "out float4 oPosObj : TEXCOORD0 \n";
826 
827  uint texCoordSet = 1;
828  outStream <<
829  ", out float4 oUVMisc : TEXCOORD" << texCoordSet++ << " // xy = uv, z = camDepth\n";
830 
831  // layer UV's premultiplied, packed as xy/zw
832  uint numUVSets = numLayers / 2;
833  if (numLayers % 2)
834  ++numUVSets;
835  if (tt != LOW_LOD)
836  {
837  for (uint i = 0; i < numUVSets; ++i)
838  {
839  outStream <<
840  ", out float4 oUV" << i << " : TEXCOORD" << texCoordSet++ << "\n";
841  }
842  }
843 
844  if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP)
845  {
846  outStream << ", out float2 lodInfo : TEXCOORD" << texCoordSet++ << "\n";
847  }
848 
849  bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
850  if (fog)
851  {
852  outStream <<
853  ", uniform float4 fogParams\n"
854  ", out float fogVal : COLOR\n";
855  }
856 
857  if (prof->isShadowingEnabled(tt, terrain))
858  {
859  texCoordSet = generateVpDynamicShadowsParams(texCoordSet, prof, terrain, tt, outStream);
860  }
861 
862  // check we haven't exceeded texture coordinates
863  if (texCoordSet > 8)
864  {
865  OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
866  "Requested options require too many texture coordinate sets! Try reducing the number of layers.",
867  __FUNCTION__);
868  }
869 
870  outStream <<
871  ")\n"
872  "{\n";
873  if (compression)
874  {
875  outStream <<
876  " float4 pos;\n"
877  " pos = mul(posIndexToObjectSpace, float4(posIndex, height, 1));\n"
878  " float2 uv = float2(posIndex.x * baseUVScale, 1.0 - (posIndex.y * baseUVScale));\n";
879  }
880  outStream <<
881  " float4 worldPos = mul(worldMatrix, pos);\n"
882  " oPosObj = pos;\n";
883 
884  if (tt != RENDER_COMPOSITE_MAP)
885  {
886  // determine whether to apply the LOD morph to this vertex
887  // we store the deltas against all vertices so we only want to apply
888  // the morph to the ones which would disappear. The target LOD which is
889  // being morphed to is stored in lodMorph.y, and the LOD at which
890  // the vertex should be morphed is stored in uv.w. If we subtract
891  // the former from the latter, and arrange to only morph if the
892  // result is negative (it will only be -1 in fact, since after that
893  // the vertex will never be indexed), we will achieve our aim.
894  // sign(vertexLOD - targetLOD) == -1 is to morph
895  outStream <<
896  " float toMorph = -min(0, sign(delta.y - lodMorph.y));\n";
897  // this will either be 1 (morph) or 0 (don't morph)
898  if (prof->getParent()->getDebugLevel())
899  {
900  // x == LOD level (-1 since value is target level, we want to display actual)
901  outStream << "lodInfo.x = (lodMorph.y - 1) / " << terrain->getNumLodLevels() << ";\n";
902  // y == LOD morph
903  outStream << "lodInfo.y = toMorph * lodMorph.x;\n";
904  }
905 
906  // morph
907  switch (terrain->getAlignment())
908  {
909  case Terrain::ALIGN_X_Y:
910  outStream << " worldPos.z += delta.x * toMorph * lodMorph.x;\n";
911  break;
912  case Terrain::ALIGN_X_Z:
913  outStream << " worldPos.y += delta.x * toMorph * lodMorph.x;\n";
914  break;
915  case Terrain::ALIGN_Y_Z:
916  outStream << " worldPos.x += delta.x * toMorph * lodMorph.x;\n";
917  break;
918  };
919  }
920 
921  // generate UVs
922  if (tt != LOW_LOD)
923  {
924  for (uint i = 0; i < numUVSets; ++i)
925  {
926  uint layer = i * 2;
927  uint uvMulIdx = layer / 4;
928 
929  outStream <<
930  " oUV" << i << ".xy = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer) << ";\n";
931  outStream <<
932  " oUV" << i << ".zw = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer + 1) << ";\n";
933  }
934  }
935 }
936 
937 //---------------------------------------------------------------------
939  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
940 {
941  // Main header
942  outStream <<
943  // helpers
944  "float4 expand(float4 v)\n"
945  "{ \n"
946  " return v * 2 - 1;\n"
947  "}\n\n\n";
948 
949  if (prof->isShadowingEnabled(tt, terrain))
950  generateFpDynamicShadowsHelpers(prof, terrain, tt, outStream);
951 
952  outStream <<
953  "float4 main_fp(\n"
954  "float4 vertexPos : POSITION,\n"
955  "float4 position : TEXCOORD0,\n";
956 
957  uint texCoordSet = 1;
958  outStream <<
959  "float4 uvMisc : TEXCOORD" << texCoordSet++ << ",\n";
960 
961  // UV's premultiplied, packed as xy/zw
962  uint maxLayers = prof->getMaxLayers(terrain);
963  uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount());
964  uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
965  uint numUVSets = numLayers / 2;
966  if (numLayers % 2)
967  ++numUVSets;
968  if (tt != LOW_LOD)
969  {
970  for (uint i = 0; i < numUVSets; ++i)
971  {
972  outStream <<
973  "float4 layerUV" << i << " : TEXCOORD" << texCoordSet++ << ", \n";
974  }
975  }
976  if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP)
977  {
978  outStream << "float2 lodInfo : TEXCOORD" << texCoordSet++ << ", \n";
979  }
980 
981  bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
982  if (fog)
983  {
984  outStream <<
985  "uniform float3 fogColour, \n"
986  "float fogVal : COLOR,\n";
987  }
988 
989  uint currentSamplerIdx = 0;
990 
991  outStream <<
992  // Only 1 light supported in this version
993  // deferred shading profile / generator later, ok? :)
994  "uniform float3 ambient,\n"
995  "uniform float4 lightPosObjSpace,\n"
996  "uniform float3 lightDiffuseColour,\n"
997  "uniform float3 lightSpecularColour,\n"
998  "uniform float3 eyePosObjSpace,\n"
999  // pack scale, bias and specular
1000  "uniform float4 scaleBiasSpecular,\n";
1001 
1002  if (tt == LOW_LOD)
1003  {
1004  // single composite map covers all the others below
1005  outStream <<
1006  "uniform sampler2D compositeMap : register(s" << currentSamplerIdx++ << ")\n";
1007  }
1008  else
1009  {
1010  outStream <<
1011  "uniform sampler2D globalNormal : register(s" << currentSamplerIdx++ << ")\n";
1012 
1013  if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled())
1014  {
1015  outStream << ", uniform sampler2D globalColourMap : register(s"
1016  << currentSamplerIdx++ << ")\n";
1017  }
1018  if (prof->isLightmapEnabled())
1019  {
1020  outStream << ", uniform sampler2D lightMap : register(s"
1021  << currentSamplerIdx++ << ")\n";
1022  }
1023  // Blend textures - sampler definitions
1024  for (uint i = 0; i < numBlendTextures; ++i)
1025  {
1026  outStream << ", uniform sampler2D blendTex" << i
1027  << " : register(s" << currentSamplerIdx++ << ")\n";
1028  }
1029 
1030  // Layer textures - sampler definitions & UV multipliers
1031  for (uint i = 0; i < numLayers; ++i)
1032  {
1033  outStream << ", uniform sampler2D difftex" << i
1034  << " : register(s" << currentSamplerIdx++ << ")\n";
1035  outStream << ", uniform sampler2D normtex" << i
1036  << " : register(s" << currentSamplerIdx++ << ")\n";
1037  }
1038  }
1039 
1040  if (prof->isShadowingEnabled(tt, terrain))
1041  {
1042  generateFpDynamicShadowsParams(&texCoordSet, &currentSamplerIdx, prof, terrain, tt, outStream);
1043  }
1044 
1045  // check we haven't exceeded samplers
1046  if (currentSamplerIdx > 16)
1047  {
1048  OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
1049  "Requested options require too many texture samplers! Try reducing the number of layers.",
1050  __FUNCTION__);
1051  }
1052 
1053  outStream <<
1054  ") : COLOR\n"
1055  "{\n"
1056  " float4 outputCol;\n"
1057  " float shadow = 1.0;\n"
1058  " float2 uv = uvMisc.xy;\n"
1059  // base colour
1060  " outputCol = float4(0,0,0,1);\n";
1061 
1062  if (tt != LOW_LOD)
1063  {
1064  outStream <<
1065  // global normal
1066  " float3 normal = expand(tex2D(globalNormal, uv)).rgb;\n";
1067  }
1068 
1069  outStream <<
1070  " float3 lightDir = \n"
1071  " lightPosObjSpace.xyz - (position.xyz * lightPosObjSpace.w);\n"
1072  " float3 eyeDir = eyePosObjSpace - position.xyz;\n"
1073 
1074  // set up accumulation areas
1075  " float3 diffuse = float3(0,0,0);\n"
1076  " float specular = 0;\n";
1077 
1078  if (tt == LOW_LOD)
1079  {
1080  // we just do a single calculation from composite map
1081  outStream <<
1082  " float4 composite = tex2D(compositeMap, uv);\n"
1083  " diffuse = composite.rgb;\n";
1084  // TODO - specular; we'll need normals for this!
1085  }
1086  else
1087  {
1088  // set up the blend values
1089  for (uint i = 0; i < numBlendTextures; ++i)
1090  {
1091  outStream << " float4 blendTexVal" << i << " = tex2D(blendTex" << i << ", uv);\n";
1092  }
1093 
1094  if (prof->isLayerNormalMappingEnabled())
1095  {
1096  // derive the tangent space basis
1097  // we do this in the pixel shader because we don't have per-vertex normals
1098  // because of the LOD, we use a normal map
1099  // tangent is always +x or -z in object space depending on alignment
1100  switch (terrain->getAlignment())
1101  {
1102  case Terrain::ALIGN_X_Y:
1103  case Terrain::ALIGN_X_Z:
1104  outStream << " float3 tangent = float3(1, 0, 0);\n";
1105  break;
1106  case Terrain::ALIGN_Y_Z:
1107  outStream << " float3 tangent = float3(0, 0, -1);\n";
1108  break;
1109  };
1110 
1111  outStream << " float3 binormal = normalize(cross(tangent, normal));\n";
1112  // note, now we need to re-cross to derive tangent again because it wasn't orthonormal
1113  outStream << " tangent = normalize(cross(normal, binormal));\n";
1114  // derive final matrix
1115  outStream << " float3x3 TBN = float3x3(tangent, binormal, normal);\n";
1116 
1117  // set up lighting result placeholders for interpolation
1118  outStream << " float4 litRes, litResLayer;\n";
1119  outStream << " float3 TSlightDir, TSeyeDir, TShalfAngle, TSnormal;\n";
1120  if (prof->isLayerParallaxMappingEnabled())
1121  outStream << " float displacement;\n";
1122  // move
1123  outStream << " TSlightDir = normalize(mul(TBN, lightDir));\n";
1124  outStream << " TSeyeDir = normalize(mul(TBN, eyeDir));\n";
1125  }
1126  else
1127  {
1128  // simple per-pixel lighting with no normal mapping
1129  outStream << " lightDir = normalize(lightDir);\n";
1130  outStream << " eyeDir = normalize(eyeDir);\n";
1131  outStream << " float3 halfAngle = normalize(lightDir + eyeDir);\n";
1132  outStream << " float4 litRes = lit(dot(lightDir, normal), dot(halfAngle, normal), scaleBiasSpecular.z);\n";
1133  }
1134  }
1135 }
1136 
1137 //---------------------------------------------------------------------
1139  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream)
1140 {
1141  // nothing to do
1142 }
1143 
1144 //---------------------------------------------------------------------
1146  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream)
1147 {
1148  uint uvIdx = layer / 2;
1149  String uvChannels = (layer % 2) ? ".zw" : ".xy";
1150  uint blendIdx = (layer - 1) / 4;
1151  String blendChannel = getChannel(layer - 1);
1152  String blendWeightStr = String("blendTexVal") + StringConverter::toString(blendIdx) +
1153  "." + blendChannel;
1154 
1155  // generate early-out conditional
1156  /* Disable - causing some issues even when trying to force the use of texldd
1157  if (layer && prof->_isSM3Available())
1158  outStream << " if (" << blendWeightStr << " > 0.0003)\n { \n";
1159  */
1160 
1161  // generate UV
1162  outStream << " float2 uv" << layer << " = layerUV" << uvIdx << uvChannels << ";\n";
1163 
1164  // calculate lighting here if normal mapping
1165  if (prof->isLayerNormalMappingEnabled())
1166  {
1167  if (prof->isLayerParallaxMappingEnabled() && tt != RENDER_COMPOSITE_MAP)
1168  {
1169  // modify UV - note we have to sample an extra time
1170  outStream << " displacement = tex2D(normtex" << layer << ", uv" << layer << ").a\n"
1171  " * scaleBiasSpecular.x + scaleBiasSpecular.y;\n";
1172  outStream << " uv" << layer << " += TSeyeDir.xy * displacement;\n";
1173  }
1174 
1175  // access TS normal map
1176  outStream << " TSnormal = expand(tex2D(normtex" << layer << ", uv" << layer << ")).rgb;\n";
1177  outStream << " TShalfAngle = normalize(TSlightDir + TSeyeDir);\n";
1178  outStream << " litResLayer = lit(dot(TSlightDir, TSnormal), dot(TShalfAngle, TSnormal), scaleBiasSpecular.z);\n";
1179  if (!layer)
1180  outStream << " litRes = litResLayer;\n";
1181  else
1182  outStream << " litRes = lerp(litRes, litResLayer, " << blendWeightStr << ");\n";
1183  }
1184 
1185  // sample diffuse texture
1186  outStream << " float4 diffuseSpecTex" << layer
1187  << " = tex2D(difftex" << layer << ", uv" << layer << ");\n";
1188 
1189  // apply to common
1190  if (!layer)
1191  {
1192  outStream << " diffuse = diffuseSpecTex0.rgb;\n";
1193  if (prof->isLayerSpecularMappingEnabled())
1194  outStream << " specular = diffuseSpecTex0.a;\n";
1195  }
1196  else
1197  {
1198  outStream << " diffuse = lerp(diffuse, diffuseSpecTex" << layer
1199  << ".rgb, " << blendWeightStr << ");\n";
1200  if (prof->isLayerSpecularMappingEnabled())
1201  outStream << " specular = lerp(specular, diffuseSpecTex" << layer
1202  << ".a, " << blendWeightStr << ");\n";
1203  }
1204 
1205  // End early-out
1206  /* Disable - causing some issues even when trying to force the use of texldd
1207  if (layer && prof->_isSM3Available())
1208  outStream << " } // early-out blend value\n";
1209  */
1210 }
1211 
1212 //---------------------------------------------------------------------
1214  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
1215 {
1216  outStream <<
1217  " oPos = mul(viewProjMatrix, worldPos);\n"
1218  " oUVMisc.xy = uv.xy;\n";
1219 
1220  bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
1221  if (fog)
1222  {
1223  if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR)
1224  {
1225  outStream <<
1226  " fogVal = saturate((oPos.z - fogParams.y) * fogParams.w);\n";
1227  }
1228  else
1229  {
1230  outStream <<
1231  " fogVal = 1 - saturate(1 / (exp(oPos.z * fogParams.x)));\n";
1232  }
1233  }
1234 
1235  if (prof->isShadowingEnabled(tt, terrain))
1236  generateVpDynamicShadows(prof, terrain, tt, outStream);
1237 
1238  outStream <<
1239  "}\n";
1240 }
1241 
1242 //---------------------------------------------------------------------
1244  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
1245 {
1246  if (tt == LOW_LOD)
1247  {
1248  if (prof->isShadowingEnabled(tt, terrain))
1249  {
1250  generateFpDynamicShadows(prof, terrain, tt, outStream);
1251  outStream <<
1252  " outputCol.rgb = diffuse * rtshadow;\n";
1253  }
1254  else
1255  {
1256  outStream <<
1257  " outputCol.rgb = diffuse;\n";
1258  }
1259  }
1260  else
1261  {
1262  if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled())
1263  {
1264  // sample colour map and apply to diffuse
1265  outStream << " diffuse *= tex2D(globalColourMap, uv).rgb;\n";
1266  }
1267  if (prof->isLightmapEnabled())
1268  {
1269  // sample lightmap
1270  outStream << " shadow = tex2D(lightMap, uv).r;\n";
1271  }
1272 
1273  if (prof->isShadowingEnabled(tt, terrain))
1274  {
1275  generateFpDynamicShadows(prof, terrain, tt, outStream);
1276  }
1277 
1278  // diffuse lighting
1279  outStream << " outputCol.rgb += ambient * diffuse + litRes.y * lightDiffuseColour * diffuse * shadow;\n";
1280 
1281  // specular default
1282  if (!prof->isLayerSpecularMappingEnabled())
1283  outStream << " specular = 1.0;\n";
1284 
1285  if (tt == RENDER_COMPOSITE_MAP)
1286  {
1287  // Lighting embedded in alpha
1288  outStream <<
1289  " outputCol.a = shadow;\n";
1290  }
1291  else
1292  {
1293  // Apply specular
1294  outStream << " outputCol.rgb += litRes.z * lightSpecularColour * specular * shadow;\n";
1295 
1296  if (prof->getParent()->getDebugLevel())
1297  {
1298  outStream << " outputCol.rg += lodInfo.xy;\n";
1299  }
1300  }
1301  }
1302 
1303  bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
1304  if (fog)
1305  {
1306  outStream << " outputCol.rgb = lerp(outputCol.rgb, fogColour, fogVal);\n";
1307  }
1308 
1309  // Final return
1310  outStream << " return outputCol;\n"
1311  << "}\n";
1312 }
1313 
1314 //---------------------------------------------------------------------
1316  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
1317 {
1318  // TODO make filtering configurable
1319  outStream <<
1320  "// Simple PCF \n"
1321  "// Number of samples in one dimension (square for total samples) \n"
1322  "#define NUM_SHADOW_SAMPLES_1D 2.0 \n"
1323  "#define SHADOW_FILTER_SCALE 1 \n"
1324 
1325  "#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D \n"
1326 
1327  "float4 offsetSample(float4 uv, float2 offset, float invMapSize) \n"
1328  "{ \n"
1329  " return float4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w); \n"
1330  "} \n";
1331 
1332  if (prof->getReceiveDynamicShadowsDepth())
1333  {
1334  outStream <<
1335  "float calcDepthShadow(sampler2D shadowMap, float4 uv, float invShadowMapSize) \n"
1336  "{ \n"
1337  " // 4-sample PCF \n"
1338 
1339  " float shadow = 0.0; \n"
1340  " float offset = (NUM_SHADOW_SAMPLES_1D/2 - 0.5) * SHADOW_FILTER_SCALE; \n"
1341  " for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE) \n"
1342  " for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE) \n"
1343  " { \n"
1344  " float4 newUV = offsetSample(uv, float2(x, y), invShadowMapSize);\n"
1345  " // manually project and assign derivatives \n"
1346  " // to avoid gradient issues inside loops \n"
1347  " newUV = newUV / newUV.w; \n"
1348  " float depth = tex2D(shadowMap, newUV.xy, 1, 1).x; \n"
1349  " if (depth >= 1 || depth >= uv.z)\n"
1350  " shadow += 1.0;\n"
1351  " } \n"
1352 
1353  " shadow /= SHADOW_SAMPLES; \n"
1354 
1355  " return shadow; \n"
1356  "} \n";
1357  }
1358  else
1359  {
1360  outStream <<
1361  "float calcSimpleShadow(sampler2D shadowMap, float4 shadowMapPos) \n"
1362  "{ \n"
1363  " return tex2Dproj(shadowMap, shadowMapPos).x; \n"
1364  "} \n";
1365  }
1366 
1367  if (prof->getReceiveDynamicShadowsPSSM())
1368  {
1369  uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount();
1370 
1371  if (prof->getReceiveDynamicShadowsDepth())
1372  {
1373  outStream <<
1374  "float calcPSSMDepthShadow(";
1375  }
1376  else
1377  {
1378  outStream <<
1379  "float calcPSSMSimpleShadow(";
1380  }
1381 
1382  outStream << "\n ";
1383  for (uint i = 0; i < numTextures; ++i)
1384  outStream << "sampler2D shadowMap" << i << ", ";
1385  outStream << "\n ";
1386  for (uint i = 0; i < numTextures; ++i)
1387  outStream << "float4 lsPos" << i << ", ";
1388  if (prof->getReceiveDynamicShadowsDepth())
1389  {
1390  outStream << "\n ";
1391  for (uint i = 0; i < numTextures; ++i)
1392  outStream << "float invShadowmapSize" << i << ", ";
1393  }
1394  outStream << "\n"
1395  " float4 pssmSplitPoints, float camDepth) \n"
1396  "{ \n"
1397  " float shadow; \n"
1398  " // calculate shadow \n";
1399 
1400  for (uint i = 0; i < numTextures; ++i)
1401  {
1402  if (!i)
1403  outStream << " if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n";
1404  else if (i < numTextures - 1)
1405  outStream << " else if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n";
1406  else
1407  outStream << " else \n";
1408 
1409  outStream <<
1410  " { \n";
1411  if (prof->getReceiveDynamicShadowsDepth())
1412  {
1413  outStream <<
1414  " shadow = calcDepthShadow(shadowMap" << i << ", lsPos" << i << ", invShadowmapSize" << i << "); \n";
1415  }
1416  else
1417  {
1418  outStream <<
1419  " shadow = calcSimpleShadow(shadowMap" << i << ", lsPos" << i << "); \n";
1420  }
1421  outStream <<
1422  " } \n";
1423  }
1424 
1425  outStream <<
1426  " return shadow; \n"
1427  "} \n\n\n";
1428  }
1429 }
1430 
1431 //---------------------------------------------------------------------
1433  uint texCoord, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
1434 {
1435  // out semantics & params
1436  uint numTextures = 1;
1437  if (prof->getReceiveDynamicShadowsPSSM())
1438  {
1439  numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount();
1440  }
1441  for (uint i = 0; i < numTextures; ++i)
1442  {
1443  outStream <<
1444  ", out float4 oLightSpacePos" << i << " : TEXCOORD" << texCoord++ << " \n" <<
1445  ", uniform float4x4 texViewProjMatrix" << i << " \n";
1446 
1447  /*if (prof->getReceiveDynamicShadowsDepth())
1448  {
1449  outStream <<
1450  ", uniform float4 depthRange" << i << " // x = min, y = max, z = range, w = 1/range \n";
1451  }*/
1452  }
1453 
1454  return texCoord;
1455 }
1456 
1457 //---------------------------------------------------------------------
1459  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
1460 {
1461  uint numTextures = 1;
1462  if (prof->getReceiveDynamicShadowsPSSM())
1463  {
1464  numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount();
1465  }
1466 
1467  // Calculate the position of vertex in light space
1468  for (uint i = 0; i < numTextures; ++i)
1469  {
1470  outStream <<
1471  " oLightSpacePos" << i << " = mul(texViewProjMatrix" << i << ", worldPos); \n";
1472  /*if (prof->getReceiveDynamicShadowsDepth())
1473  {
1474  // make linear
1475  outStream <<
1476  "oLightSpacePos" << i << ".z = (oLightSpacePos" << i << ".z - depthRange" << i << ".x) * depthRange" << i << ".w;\n";
1477 
1478  }*/
1479  }
1480 
1481  if (prof->getReceiveDynamicShadowsPSSM())
1482  {
1483  outStream <<
1484  " // pass cam depth\n"
1485  " oUVMisc.z = oPos.z;\n";
1486  }
1487 }
1488 
1489 //---------------------------------------------------------------------
1491  uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
1492 {
1493  if (tt == HIGH_LOD)
1494  mShadowSamplerStartHi = *sampler;
1495  else if (tt == LOW_LOD)
1496  mShadowSamplerStartLo = *sampler;
1497 
1498  // in semantics & params
1499  uint numTextures = 1;
1500  if (prof->getReceiveDynamicShadowsPSSM())
1501  {
1502  numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount();
1503  outStream <<
1504  ", uniform float4 pssmSplitPoints \n";
1505  }
1506  for (uint i = 0; i < numTextures; ++i)
1507  {
1508  outStream <<
1509  ", float4 lightSpacePos" << i << " : TEXCOORD" << *texCoord << " \n" <<
1510  ", uniform sampler2D shadowMap" << i << " : register(s" << *sampler << ") \n";
1511  *sampler = *sampler + 1;
1512  *texCoord = *texCoord + 1;
1513  if (prof->getReceiveDynamicShadowsDepth())
1514  {
1515  outStream <<
1516  ", uniform float inverseShadowmapSize" << i << " \n";
1517  }
1518  }
1519 }
1520 
1521 //---------------------------------------------------------------------
1523  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream)
1524 {
1525  if (prof->getReceiveDynamicShadowsPSSM())
1526  {
1527  uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount();
1528  outStream <<
1529  " float camDepth = uvMisc.z;\n";
1530 
1531  if (prof->getReceiveDynamicShadowsDepth())
1532  {
1533  outStream <<
1534  " float rtshadow = calcPSSMDepthShadow(";
1535  }
1536  else
1537  {
1538  outStream <<
1539  " float rtshadow = calcPSSMSimpleShadow(";
1540  }
1541  for (uint i = 0; i < numTextures; ++i)
1542  outStream << "shadowMap" << i << ", ";
1543  outStream << "\n ";
1544 
1545  for (uint i = 0; i < numTextures; ++i)
1546  outStream << "lightSpacePos" << i << ", ";
1547  if (prof->getReceiveDynamicShadowsDepth())
1548  {
1549  outStream << "\n ";
1550  for (uint i = 0; i < numTextures; ++i)
1551  outStream << "inverseShadowmapSize" << i << ", ";
1552  }
1553  outStream << "\n" <<
1554  " pssmSplitPoints, camDepth);\n";
1555  }
1556  else
1557  {
1558  if (prof->getReceiveDynamicShadowsDepth())
1559  {
1560  outStream <<
1561  " float rtshadow = calcDepthShadow(shadowMap0, lightSpacePos0, inverseShadowmapSize0);";
1562  }
1563  else
1564  {
1565  outStream <<
1566  " float rtshadow = calcSimpleShadow(shadowMap0, lightSpacePos0);";
1567  }
1568  }
1569 
1570  outStream <<
1571  " shadow = min(shadow, rtshadow);\n";
1572 }
1573 
1574 //---------------------------------------------------------------------
1575 //---------------------------------------------------------------------
1576 HighLevelGpuProgramPtr
1578  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
1579 {
1580  HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1581  String progName = getVertexProgramName(prof, terrain, tt);
1582 
1583  HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1584  if (ret.isNull())
1585  {
1586  ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1587  "hlsl", GPT_VERTEX_PROGRAM);
1588  }
1589  else
1590  {
1591  ret->unload();
1592  }
1593 
1594  if (prof->_isSM4Available())
1595  ret->setParameter("target", "vs_4_0");
1596  else if (prof->_isSM3Available())
1597  ret->setParameter("target", "vs_3_0");
1598  else
1599  ret->setParameter("target", "vs_2_0");
1600  ret->setParameter("entry_point", "main_vp");
1601 
1602  return ret;
1603 }
1604 
1605 //---------------------------------------------------------------------
1606 HighLevelGpuProgramPtr
1608  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
1609 {
1610  HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1611  String progName = getFragmentProgramName(prof, terrain, tt);
1612 
1613  HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1614  if (ret.isNull())
1615  {
1616  ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1617  "hlsl", GPT_FRAGMENT_PROGRAM);
1618  }
1619  else
1620  {
1621  ret->unload();
1622  }
1623 
1624  if (prof->_isSM4Available())
1625  ret->setParameter("target", "ps_4_0");
1626  else if (prof->_isSM3Available())
1627  ret->setParameter("target", "ps_3_0");
1628  else
1629  ret->setParameter("target", "ps_2_x");
1630  ret->setParameter("entry_point", "main_fp");
1631 
1632  return ret;
1633 }
1634 
1635 //---------------------------------------------------------------------
1636 //---------------------------------------------------------------------
1637 HighLevelGpuProgramPtr
1639  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
1640 {
1641  HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1642  String progName = getVertexProgramName(prof, terrain, tt);
1643 
1644  switch (tt)
1645  {
1646  case HIGH_LOD:
1647  progName += "/hlod";
1648  break;
1649  case LOW_LOD:
1650  progName += "/llod";
1651  break;
1652  case RENDER_COMPOSITE_MAP:
1653  progName += "/comp";
1654  break;
1655  }
1656 
1657  HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1658  if (ret.isNull())
1659  {
1660  ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1661  "glsl", GPT_VERTEX_PROGRAM);
1662  }
1663  else
1664  {
1665  ret->unload();
1666  }
1667 
1668  return ret;
1669 }
1670 
1671 //---------------------------------------------------------------------
1672 HighLevelGpuProgramPtr
1674  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
1675 {
1676  HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1677  String progName = getFragmentProgramName(prof, terrain, tt);
1678 
1679  HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1680  if (ret.isNull())
1681  {
1682  ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1683  "glsl", GPT_FRAGMENT_PROGRAM);
1684  }
1685  else
1686  {
1687  ret->unload();
1688  }
1689 
1690  return ret;
1691 }
1692 
1693 //---------------------------------------------------------------------
1694 //---------------------------------------------------------------------
1695 HighLevelGpuProgramPtr
1697  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
1698 {
1699  HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1700  String progName = getVertexProgramName(prof, terrain, tt);
1701 
1702  switch (tt)
1703  {
1704  case HIGH_LOD:
1705  progName += "/hlod";
1706  break;
1707  case LOW_LOD:
1708  progName += "/llod";
1709  break;
1710  case RENDER_COMPOSITE_MAP:
1711  progName += "/comp";
1712  break;
1713  }
1714 
1715  HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1716  if (ret.isNull())
1717  {
1718  ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1719  "glsles", GPT_VERTEX_PROGRAM);
1720  }
1721  else
1722  {
1723  ret->unload();
1724  }
1725 
1726  return ret;
1727 }
1728 
1729 //---------------------------------------------------------------------
1730 HighLevelGpuProgramPtr
1732  const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
1733 {
1734  HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1735  String progName = getFragmentProgramName(prof, terrain, tt);
1736 
1737  HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1738  if (ret.isNull())
1739  {
1740  ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1741  "glsles", GPT_FRAGMENT_PROGRAM);
1742  }
1743  else
1744  {
1745  ret->unload();
1746  }
1747 
1748  return ret;
1749 }
1750 
1751 }
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperHLSL
Definition: OgreTerrainPSSMMaterialGenerator.h:218
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperGLSLES::createFragmentProgram
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1731
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::defaultVpParams
virtual void defaultVpParams(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, const HighLevelGpuProgramPtr &prog)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:521
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::getChannel
static String getChannel(uint idx)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:667
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setLayerNormalMappingEnabled
void setLayerNormalMappingEnabled(bool enabled)
Whether to support normal mapping per layer in the shader (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:111
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::isLayerNormalMappingEnabled
bool isLayerNormalMappingEnabled() const
Whether to support normal mapping per layer in the shader (default true).
Definition: OgreTerrainPSSMMaterialGenerator.h:67
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::isCompositeMapEnabled
bool isCompositeMapEnabled() const
Whether to use the composite map to provide a lower LOD technique in the distance (default true).
Definition: OgreTerrainPSSMMaterialGenerator.h:107
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::updateVpParams
virtual void updateVpParams(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, const GpuProgramParametersSharedPtr &params)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:629
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setGlobalColourMapEnabled
void setGlobalColourMapEnabled(bool enabled)
Whether to support a global colour map over the terrain in the shader, if it's present (default true)...
Definition: OgreTerrainPSSMMaterialGenerator.cpp:141
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperGLSLES
Utility class to help with generating shaders for GLSL ES.
Definition: OgreTerrainPSSMMaterialGenerator.h:246
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::isShadowingEnabled
bool isShadowingEnabled(TechniqueType tt, const Terrain *terrain) const
Definition: OgreTerrainPSSMMaterialGenerator.cpp:423
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::defaultFpParams
virtual void defaultFpParams(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, const HighLevelGpuProgramPtr &prog)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:560
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::createVertexProgram
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:731
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::isLayerParallaxMappingEnabled
bool isLayerParallaxMappingEnabled() const
Whether to support parallax mapping per layer in the shader (default true).
Definition: OgreTerrainPSSMMaterialGenerator.h:74
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::_isSM3Available
bool _isSM3Available() const
Internal.
Definition: OgreTerrainPSSMMaterialGenerator.h:147
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateFpFooter
void generateFpFooter(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1243
OgreTerrainPSSMMaterialGenerator.h
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::updateParams
void updateParams(const MaterialPtr &mat, const Terrain *terrain)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:431
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateVpFooter
void generateVpFooter(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1213
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::generateFragmentProgram
virtual HighLevelGpuProgramPtr generateFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:465
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateFpDynamicShadows
void generateFpDynamicShadows(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1522
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::_isSM4Available
bool _isSM4Available() const
Definition: OgreTerrainPSSMMaterialGenerator.h:148
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::createFragmentProgram
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:755
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperHLSL::createVertexProgram
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1577
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg
Utility class to help with generating shaders for Cg / HLSL.
Definition: OgreTerrainPSSMMaterialGenerator.h:200
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setLightmapEnabled
void setLightmapEnabled(bool enabled)
Whether to support a light map over the terrain in the shader, if it's present (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:151
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateVpLayer
void generateVpLayer(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1138
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::getReceiveDynamicShadowsPSSM
PSSMShadowCameraSetup * getReceiveDynamicShadowsPSSM() const
Whether to use PSSM support dynamic texture shadows, and if so the settings to use (default 0).
Definition: OgreTerrainPSSMMaterialGenerator.h:130
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::isVertexCompressionSupported
bool isVertexCompressionSupported() const
Definition: OgreTerrainPSSMMaterialGenerator.cpp:105
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::addTechnique
void addTechnique(const MaterialPtr &mat, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:314
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::~SM2Profile
~SM2Profile()
Definition: OgreTerrainPSSMMaterialGenerator.cpp:90
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperGLSL
Utility class to help with generating shaders for GLSL.
Definition: OgreTerrainPSSMMaterialGenerator.h:226
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setLayerParallaxMappingEnabled
void setLayerParallaxMappingEnabled(bool enabled)
Whether to support parallax mapping per layer in the shader (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:121
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::generateFragmentProgramSource
virtual void generateFragmentProgramSource(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:503
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::TechniqueType
TechniqueType
Definition: OgreTerrainPSSMMaterialGenerator.h:152
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::getMaxLayers
uint8 getMaxLayers(const Terrain *terrain) const
Definition: OgreTerrainPSSMMaterialGenerator.cpp:211
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::generateVertexProgram
virtual HighLevelGpuProgramPtr generateVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:445
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setReceiveDynamicShadowsDepth
void setReceiveDynamicShadowsDepth(bool enabled)
Whether to use depth shadows (default false).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:191
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setReceiveDynamicShadowsPSSM
void setReceiveDynamicShadowsPSSM(PSSMShadowCameraSetup *pssmSettings)
Whether to use PSSM support dynamic texture shadows, and if so the settings to use (default 0).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:181
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateFpDynamicShadowsHelpers
void generateFpDynamicShadowsHelpers(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1315
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setLayerSpecularMappingEnabled
void setLayerSpecularMappingEnabled(bool enabled)
Whether to support specular mapping per layer in the shader (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:131
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::getVertexProgramName
virtual String getVertexProgramName(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:685
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setReceiveDynamicShadowsLowLod
void setReceiveDynamicShadowsLowLod(bool enabled)
Whether to use shadows on low LOD material rendering (when using composite map) (default false).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:201
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateVpDynamicShadows
void generateVpDynamicShadows(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1458
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::requestOptions
void requestOptions(Terrain *terrain)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:96
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::generateVertexProgramSource
virtual void generateVertexProgramSource(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:485
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::isLayerSpecularMappingEnabled
bool isLayerSpecularMappingEnabled() const
Whether to support specular mapping per layer in the shader (default true).
Definition: OgreTerrainPSSMMaterialGenerator.h:81
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::generateForCompositeMap
MaterialPtr generateForCompositeMap(const Terrain *terrain)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:286
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::updateFpParams
virtual void updateFpParams(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, const GpuProgramParametersSharedPtr &params)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:657
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateVpHeader
void generateVpHeader(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:782
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::generate
MaterialPtr generate(const Terrain *terrain)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:237
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::isGlobalColourMapEnabled
bool isGlobalColourMapEnabled() const
Whether to support a global colour map over the terrain in the shader, if it's present (default true)...
Definition: OgreTerrainPSSMMaterialGenerator.h:89
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::getFragmentProgramName
virtual String getFragmentProgramName(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:707
Ogre::TerrainPSSMMaterialGenerator::TerrainPSSMMaterialGenerator
TerrainPSSMMaterialGenerator()
Definition: OgreTerrainPSSMMaterialGenerator.cpp:43
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelper::updateParams
virtual void updateParams(const SM2Profile *prof, const MaterialPtr &mat, const Terrain *terrain, bool compositeMap)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:603
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperGLSL::createVertexProgram
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1638
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setReceiveDynamicShadowsEnabled
void setReceiveDynamicShadowsEnabled(bool enabled)
Whether to support dynamic texture shadows received from other objects, on the terrain (default true)...
Definition: OgreTerrainPSSMMaterialGenerator.cpp:171
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperGLSL::createFragmentProgram
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1673
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::getReceiveDynamicShadowsDepth
bool getReceiveDynamicShadowsDepth() const
Whether to use depth shadows (default false).
Definition: OgreTerrainPSSMMaterialGenerator.h:137
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperHLSL::createFragmentProgram
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1607
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::updateParamsForCompositeMap
void updateParamsForCompositeMap(const MaterialPtr &mat, const Terrain *terrain)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:437
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateFpHeader
void generateFpHeader(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:938
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateFpLayer
void generateFpLayer(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1145
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::SM2Profile
SM2Profile(TerrainMaterialGenerator *parent, const String &name, const String &desc)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:73
Ogre
Definition: ExtinguishableFireAffector.cpp:35
Ogre::TerrainPSSMMaterialGenerator::SM2Profile
Shader model 2 profile target.
Definition: OgreTerrainPSSMMaterialGenerator.h:52
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateFpDynamicShadowsParams
void generateFpDynamicShadowsParams(uint *texCoord, uint *sampler, const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1490
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperCg::generateVpDynamicShadowsParams
uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, StringUtil::StrStreamType &outStream)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1432
Ogre::TerrainPSSMMaterialGenerator::~TerrainPSSMMaterialGenerator
~TerrainPSSMMaterialGenerator()
Definition: OgreTerrainPSSMMaterialGenerator.cpp:67
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setCompositeMapEnabled
void setCompositeMapEnabled(bool enabled)
Whether to use the composite map to provide a lower LOD technique in the distance (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:161
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::ShaderHelperGLSLES::createVertexProgram
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Definition: OgreTerrainPSSMMaterialGenerator.cpp:1696
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::isLightmapEnabled
bool isLightmapEnabled() const
Whether to support a light map over the terrain in the shader, if it's present (default true).
Definition: OgreTerrainPSSMMaterialGenerator.h:98