30#include <Terrain/OgreTerrain.h>
31#include <OgreMaterialManager.h>
32#include <OgreTechnique.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>
49 mLayerDecl.samplers.push_back(TerrainLayerSampler(
"albedo_specular", PF_BYTE_RGBA));
50 mLayerDecl.samplers.push_back(TerrainLayerSampler(
"normal_height", PF_BYTE_RGBA));
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));
61 mProfiles.push_back(OGRE_NEW
SM2Profile(
this,
"SM2",
"Profile for rendering on Shader Model 2 capable cards"));
63 setActiveProfile(
"SM2");
74 : Profile(parent, name, desc)
76 , mLayerNormalMappingEnabled(true)
77 , mLayerParallaxMappingEnabled(true)
78 , mLayerSpecularMappingEnabled(true)
79 , mGlobalColourMapEnabled(true)
80 , mLightmapEnabled(true)
81 , mCompositeMapEnabled(true)
82 , mReceiveDynamicShadows(true)
84 , mDepthShadows(false)
85 , mLowLodShadows(false)
92 OGRE_DELETE mShaderGen;
98 terrain->_setMorphRequired(
true);
99 terrain->_setNormalMapRequired(
true);
100 terrain->_setLightMapRequired(mLightmapEnabled,
true);
101 terrain->_setCompositeMapRequired(mCompositeMapEnabled);
113 if (enabled != mLayerNormalMappingEnabled)
115 mLayerNormalMappingEnabled = enabled;
116 mParent->_markChanged();
123 if (enabled != mLayerParallaxMappingEnabled)
125 mLayerParallaxMappingEnabled = enabled;
126 mParent->_markChanged();
133 if (enabled != mLayerSpecularMappingEnabled)
135 mLayerSpecularMappingEnabled = enabled;
136 mParent->_markChanged();
143 if (enabled != mGlobalColourMapEnabled)
145 mGlobalColourMapEnabled = enabled;
146 mParent->_markChanged();
153 if (enabled != mLightmapEnabled)
155 mLightmapEnabled = enabled;
156 mParent->_markChanged();
163 if (enabled != mCompositeMapEnabled)
165 mCompositeMapEnabled = enabled;
166 mParent->_markChanged();
173 if (enabled != mReceiveDynamicShadows)
175 mReceiveDynamicShadows = enabled;
176 mParent->_markChanged();
183 if (pssmSettings != mPSSM)
185 mPSSM = pssmSettings;
186 mParent->_markChanged();
193 if (enabled != mDepthShadows)
195 mDepthShadows = enabled;
196 mParent->_markChanged();
203 if (enabled != mLowLodShadows)
205 mLowLodShadows = enabled;
206 mParent->_markChanged();
214 uint8 freeTextureUnits = 16;
220 if (terrain->getGlobalColourMapEnabled())
222 if (isShadowingEnabled(HIGH_LOD, terrain))
224 uint numShadowTextures = 1;
225 if (getReceiveDynamicShadowsPSSM())
227 numShadowTextures = getReceiveDynamicShadowsPSSM()->getSplitCount();
229 freeTextureUnits -= numShadowTextures;
233 return static_cast<uint8
>(freeTextureUnits / 2.16f);
240 MaterialPtr mat = terrain->_getMaterial();
243 MaterialManager& matMgr = MaterialManager::getSingleton();
247 const String& matName = terrain->getMaterialName();
248 mat = matMgr.getByName(matName);
251 mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
255 mat->removeAllTechniques();
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"))
263 setLayerNormalMappingEnabled(
false);
264 setLayerParallaxMappingEnabled(
false);
267 addTechnique(mat, terrain, HIGH_LOD);
270 if (mCompositeMapEnabled)
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);
280 updateParams(mat, terrain);
289 MaterialPtr mat = terrain->_getCompositeMapMaterial();
292 MaterialManager& matMgr = MaterialManager::getSingleton();
296 const String& matName = terrain->getMaterialName() +
"/comp";
297 mat = matMgr.getByName(matName);
300 mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
304 mat->removeAllTechniques();
306 addTechnique(mat, terrain, RENDER_COMPOSITE_MAP);
308 updateParamsForCompositeMap(mat, terrain);
315 const MaterialPtr& mat,
const Terrain* terrain,
TechniqueType tt)
317 Technique* tech = mat->createTechnique();
320 Pass* pass = tech->createPass();
322 GpuProgramManager& gmgr = GpuProgramManager::getSingleton();
323 HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton();
326 bool check2x = mLayerNormalMappingEnabled || mLayerParallaxMappingEnabled;
327 if (hmgr.isLanguageSupported(
"cg"))
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"))))
334 else if (hmgr.isLanguageSupported(
"glsl"))
336 else if (hmgr.isLanguageSupported(
"glsles"))
344 mSM3Available = GpuProgramManager::getSingleton().isSyntaxSupported(
"ps_3_0");
345 mSM4Available = GpuProgramManager::getSingleton().isSyntaxSupported(
"ps_4_0");
347 HighLevelGpuProgramPtr vprog = mShaderGen->generateVertexProgram(
this, terrain, tt);
348 HighLevelGpuProgramPtr fprog = mShaderGen->generateFragmentProgram(
this, terrain, tt);
350 pass->setVertexProgram(vprog->getName());
351 pass->setFragmentProgram(fprog->getName());
353 if (tt == HIGH_LOD || tt == RENDER_COMPOSITE_MAP)
356 TextureUnitState* tu = pass->createTextureUnitState();
357 tu->setTextureName(terrain->getTerrainNormalMap()->getName());
358 tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
361 if (terrain->getGlobalColourMapEnabled() && isGlobalColourMapEnabled())
363 tu = pass->createTextureUnitState(terrain->getGlobalColourMap()->getName());
364 tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
368 if (isLightmapEnabled())
370 tu = pass->createTextureUnitState(terrain->getLightmap()->getName());
371 tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
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)
380 tu = pass->createTextureUnitState(terrain->getBlendTextureName(i));
381 tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
385 for (uint i = 0; i < numLayers; ++i)
388 pass->createTextureUnitState(terrain->getLayerTextureName(i, 0));
390 pass->createTextureUnitState(terrain->getLayerTextureName(i, 1));
397 TextureUnitState* tu = pass->createTextureUnitState();
398 tu->setTextureName(terrain->getCompositeMap()->getName());
399 tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
405 if (isShadowingEnabled(tt, terrain))
407 uint numTextures = 1;
408 if (getReceiveDynamicShadowsPSSM())
410 numTextures = getReceiveDynamicShadowsPSSM()->getSplitCount();
412 for (uint i = 0; i < numTextures; ++i)
414 TextureUnitState* tu = pass->createTextureUnitState();
415 tu->setContentType(TextureUnitState::CONTENT_SHADOW);
416 tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
417 tu->setTextureBorderColour(ColourValue::White);
425 return getReceiveDynamicShadowsEnabled() && tt != RENDER_COMPOSITE_MAP &&
426 (tt != LOW_LOD || mLowLodShadows) &&
427 terrain->getSceneManager()->isShadowTechniqueTextureBased();
433 mShaderGen->updateParams(
this, mat, terrain,
false);
439 mShaderGen->updateParams(
this, mat, terrain,
true);
444HighLevelGpuProgramPtr
448 HighLevelGpuProgramPtr ret = createVertexProgram(prof, terrain, tt);
450 Ogre::StringStream sourceStr;
451 generateVertexProgramSource(prof, terrain, tt, sourceStr);
452 ret->setSource(sourceStr.str());
454 defaultVpParams(prof, terrain, tt, ret);
456 LogManager::getSingleton().stream(LML_TRIVIAL) <<
"*** Terrain Vertex Program: "
457 << ret->getName() <<
" ***\n" << ret->getSource() <<
"\n*** ***";
464HighLevelGpuProgramPtr
468 HighLevelGpuProgramPtr ret = createFragmentProgram(prof, terrain, tt);
470 Ogre::StringStream sourceStr;
471 generateFragmentProgramSource(prof, terrain, tt, sourceStr);
472 ret->setSource(sourceStr.str());
474 defaultFpParams(prof, terrain, tt, ret);
477 LogManager::getSingleton().stream(LML_TRIVIAL) <<
"*** Terrain Fragment Program: "
478 << ret->getName() <<
" ***\n" << ret->getSource() <<
"\n*** ***";
488 generateVpHeader(prof, terrain, tt, outStream);
493 uint numLayers = std::min(maxLayers,
static_cast<uint
>(terrain->getLayerCount()));
495 for (uint i = 0; i < numLayers; ++i)
496 generateVpLayer(prof, terrain, tt, i, outStream);
499 generateVpFooter(prof, terrain, tt, outStream);
506 generateFpHeader(prof, terrain, tt, outStream);
511 uint numLayers = std::min(maxLayers,
static_cast<uint
>(terrain->getLayerCount()));
513 for (uint i = 0; i < numLayers; ++i)
514 generateFpLayer(prof, terrain, tt, i, outStream);
517 generateFpFooter(prof, terrain, tt, outStream);
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);
534 uint numTextures = 1;
539 for (uint i = 0; i < numTextures; ++i)
541 params->setNamedAutoConstant(
"texViewProjMatrix" + StringConverter::toString(i),
542 GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i);
551 if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP)
553 Matrix4 posIndexToObjectSpace;
554 terrain->getPointTransform(&posIndexToObjectSpace);
555 params->setNamedConstant(
"posIndexToObjectSpace", posIndexToObjectSpace);
563 GpuProgramParametersSharedPtr params = prog->getDefaultParameters();
564 params->setIgnoreMissingParams(
true);
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);
575 uint numTextures = 1;
579 numTextures = pssm->getSplitCount();
581 const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssm->getSplitPoints();
583 for (uint i = 1; i < numTextures; ++i)
585 splitPoints[i - 1] = splitPointList[i];
587 params->setNamedConstant(
"pssmSplitPoints", splitPoints);
592 size_t samplerOffset = (tt == HIGH_LOD) ? mShadowSamplerStartHi : mShadowSamplerStartLo;
593 for (uint i = 0; i < numTextures; ++i)
595 params->setNamedAutoConstant(
"inverseShadowmapSize" + StringConverter::toString(i),
596 GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i + samplerOffset);
604 const SM2Profile* prof,
const MaterialPtr& mat,
const Terrain* terrain,
bool compositeMap)
606 Pass* p = mat->getTechnique(0)->getPass(0);
609 updateVpParams(prof, terrain, RENDER_COMPOSITE_MAP, p->getVertexProgramParameters());
610 updateFpParams(prof, terrain, RENDER_COMPOSITE_MAP, p->getFragmentProgramParameters());
615 updateVpParams(prof, terrain, HIGH_LOD, p->getVertexProgramParameters());
616 updateFpParams(prof, terrain, HIGH_LOD, p->getFragmentProgramParameters());
621 p = mat->getTechnique(1)->getPass(0);
622 updateVpParams(prof, terrain, LOW_LOD, p->getVertexProgramParameters());
623 updateFpParams(prof, terrain, LOW_LOD, p->getFragmentProgramParameters());
632 params->setIgnoreMissingParams(
true);
634 uint numLayers = std::min(maxLayers,
static_cast<uint
>(terrain->getLayerCount()));
635 uint numUVMul = numLayers / 4;
638 for (uint i = 0; i < numUVMul; ++i)
641 terrain->getLayerUVMultiplier(i * 4),
642 terrain->getLayerUVMultiplier(i * 4 + 1),
643 terrain->getLayerUVMultiplier(i * 4 + 2),
644 terrain->getLayerUVMultiplier(i * 4 + 3)
646 params->setNamedConstant(
"uvMul_" + StringConverter::toString(i), uvMul);
649 if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP)
651 Real baseUVScale = 1.0f / (terrain->getSize() - 1);
652 params->setNamedConstant(
"baseUVScale", baseUVScale);
660 params->setIgnoreMissingParams(
true);
662 Vector4 scaleBiasSpecular(0.03, -0.04, 32, 1);
663 params->setNamedConstant(
"scaleBiasSpecular", scaleBiasSpecular);
688 String progName = terrain->getMaterialName() +
"/sm2/vp";
698 case RENDER_COMPOSITE_MAP:
710 String progName = terrain->getMaterialName() +
"/sm2/fp";
720 case RENDER_COMPOSITE_MAP:
730HighLevelGpuProgramPtr
734 HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
735 String progName = getVertexProgramName(prof, terrain, tt);
736 HighLevelGpuProgramPtr ret = mgr.getByName(progName);
739 ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
740 "cg", GPT_VERTEX_PROGRAM);
747 ret->setParameter(
"profiles",
"vs_4_0 vs_3_0 vs_2_0 arbvp1");
748 ret->setParameter(
"entry_point",
"main_vp");
754HighLevelGpuProgramPtr
758 HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
759 String progName = getFragmentProgramName(prof, terrain, tt);
761 HighLevelGpuProgramPtr ret = mgr.getByName(progName);
764 ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
765 "cg", GPT_FRAGMENT_PROGRAM);
773 ret->setParameter(
"profiles",
"ps_4_0 ps_3_0 ps_2_x fp40 arbfp1");
775 ret->setParameter(
"profiles",
"ps_4_0 ps_3_0 ps_2_0 fp30 arbfp1");
776 ret->setParameter(
"entry_point",
"main_fp");
787 bool compression = terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP;
791 "float2 posIndex : POSITION,\n"
792 "float height : TEXCOORD0,\n";
797 "float4 pos : POSITION,\n"
798 "float2 uv : TEXCOORD0,\n";
800 if (tt != RENDER_COMPOSITE_MAP)
801 outStream <<
"float2 delta : TEXCOORD1,\n";
804 "uniform float4x4 worldMatrix,\n"
805 "uniform float4x4 viewProjMatrix,\n"
806 "uniform float2 lodMorph,\n";
811 "uniform float4x4 posIndexToObjectSpace,\n"
812 "uniform float baseUVScale,\n";
816 uint numLayers = std::min(maxLayers,
static_cast<uint
>(terrain->getLayerCount()));
817 uint numUVMultipliers = (numLayers / 4);
820 for (uint i = 0; i < numUVMultipliers; ++i)
821 outStream <<
"uniform float4 uvMul_" << i <<
", \n";
824 "out float4 oPos : POSITION,\n"
825 "out float4 oPosObj : TEXCOORD0 \n";
827 uint texCoordSet = 1;
829 ", out float4 oUVMisc : TEXCOORD" << texCoordSet++ <<
" // xy = uv, z = camDepth\n";
832 uint numUVSets = numLayers / 2;
837 for (uint i = 0; i < numUVSets; ++i)
840 ", out float4 oUV" << i <<
" : TEXCOORD" << texCoordSet++ <<
"\n";
844 if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP)
846 outStream <<
", out float2 lodInfo : TEXCOORD" << texCoordSet++ <<
"\n";
849 bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
853 ", uniform float4 fogParams\n"
854 ", out float fogVal : COLOR\n";
859 texCoordSet = generateVpDynamicShadowsParams(texCoordSet, prof, terrain, tt, outStream);
865 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
866 "Requested options require too many texture coordinate sets! Try reducing the number of layers.",
877 " pos = mul(posIndexToObjectSpace, float4(posIndex, height, 1));\n"
878 " float2 uv = float2(posIndex.x * baseUVScale, 1.0 - (posIndex.y * baseUVScale));\n";
881 " float4 worldPos = mul(worldMatrix, pos);\n"
884 if (tt != RENDER_COMPOSITE_MAP)
896 " float toMorph = -min(0, sign(delta.y - lodMorph.y));\n";
898 if (prof->getParent()->getDebugLevel())
901 outStream <<
"lodInfo.x = (lodMorph.y - 1) / " << terrain->getNumLodLevels() <<
";\n";
903 outStream <<
"lodInfo.y = toMorph * lodMorph.x;\n";
907 switch (terrain->getAlignment())
909 case Terrain::ALIGN_X_Y:
910 outStream <<
" worldPos.z += delta.x * toMorph * lodMorph.x;\n";
912 case Terrain::ALIGN_X_Z:
913 outStream <<
" worldPos.y += delta.x * toMorph * lodMorph.x;\n";
915 case Terrain::ALIGN_Y_Z:
916 outStream <<
" worldPos.x += delta.x * toMorph * lodMorph.x;\n";
924 for (uint i = 0; i < numUVSets; ++i)
927 uint uvMulIdx = layer / 4;
930 " oUV" << i <<
".xy = " <<
" uv.xy * uvMul_" << uvMulIdx <<
"." << getChannel(layer) <<
";\n";
932 " oUV" << i <<
".zw = " <<
" uv.xy * uvMul_" << uvMulIdx <<
"." << getChannel(layer + 1) <<
";\n";
944 "float4 expand(float4 v)\n"
946 " return v * 2 - 1;\n"
950 generateFpDynamicShadowsHelpers(prof, terrain, tt, outStream);
954 "float4 vertexPos : POSITION,\n"
955 "float4 position : TEXCOORD0,\n";
957 uint texCoordSet = 1;
959 "float4 uvMisc : TEXCOORD" << texCoordSet++ <<
",\n";
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;
970 for (uint i = 0; i < numUVSets; ++i)
973 "float4 layerUV" << i <<
" : TEXCOORD" << texCoordSet++ <<
", \n";
976 if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP)
978 outStream <<
"float2 lodInfo : TEXCOORD" << texCoordSet++ <<
", \n";
981 bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
985 "uniform float3 fogColour, \n"
986 "float fogVal : COLOR,\n";
989 uint currentSamplerIdx = 0;
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"
1000 "uniform float4 scaleBiasSpecular,\n";
1006 "uniform sampler2D compositeMap : register(s" << currentSamplerIdx++ <<
")\n";
1011 "uniform sampler2D globalNormal : register(s" << currentSamplerIdx++ <<
")\n";
1015 outStream <<
", uniform sampler2D globalColourMap : register(s"
1016 << currentSamplerIdx++ <<
")\n";
1020 outStream <<
", uniform sampler2D lightMap : register(s"
1021 << currentSamplerIdx++ <<
")\n";
1024 for (uint i = 0; i < numBlendTextures; ++i)
1026 outStream <<
", uniform sampler2D blendTex" << i
1027 <<
" : register(s" << currentSamplerIdx++ <<
")\n";
1031 for (uint i = 0; i < numLayers; ++i)
1033 outStream <<
", uniform sampler2D difftex" << i
1034 <<
" : register(s" << currentSamplerIdx++ <<
")\n";
1035 outStream <<
", uniform sampler2D normtex" << i
1036 <<
" : register(s" << currentSamplerIdx++ <<
")\n";
1042 generateFpDynamicShadowsParams(&texCoordSet, ¤tSamplerIdx, prof, terrain, tt, outStream);
1046 if (currentSamplerIdx > 16)
1048 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
1049 "Requested options require too many texture samplers! Try reducing the number of layers.",
1056 " float4 outputCol;\n"
1057 " float shadow = 1.0;\n"
1058 " float2 uv = uvMisc.xy;\n"
1060 " outputCol = float4(0,0,0,1);\n";
1066 " float3 normal = expand(tex2D(globalNormal, uv)).rgb;\n";
1070 " float3 lightDir = \n"
1071 " lightPosObjSpace.xyz - (position.xyz * lightPosObjSpace.w);\n"
1072 " float3 eyeDir = eyePosObjSpace - position.xyz;\n"
1075 " float3 diffuse = float3(0,0,0);\n"
1076 " float specular = 0;\n";
1082 " float4 composite = tex2D(compositeMap, uv);\n"
1083 " diffuse = composite.rgb;\n";
1089 for (uint i = 0; i < numBlendTextures; ++i)
1091 outStream <<
" float4 blendTexVal" << i <<
" = tex2D(blendTex" << i <<
", uv);\n";
1100 switch (terrain->getAlignment())
1102 case Terrain::ALIGN_X_Y:
1103 case Terrain::ALIGN_X_Z:
1104 outStream <<
" float3 tangent = float3(1, 0, 0);\n";
1106 case Terrain::ALIGN_Y_Z:
1107 outStream <<
" float3 tangent = float3(0, 0, -1);\n";
1111 outStream <<
" float3 binormal = normalize(cross(tangent, normal));\n";
1113 outStream <<
" tangent = normalize(cross(normal, binormal));\n";
1115 outStream <<
" float3x3 TBN = float3x3(tangent, binormal, normal);\n";
1118 outStream <<
" float4 litRes, litResLayer;\n";
1119 outStream <<
" float3 TSlightDir, TSeyeDir, TShalfAngle, TSnormal;\n";
1121 outStream <<
" float displacement;\n";
1123 outStream <<
" TSlightDir = normalize(mul(TBN, lightDir));\n";
1124 outStream <<
" TSeyeDir = normalize(mul(TBN, eyeDir));\n";
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";
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) +
1162 outStream <<
" float2 uv" << layer <<
" = layerUV" << uvIdx << uvChannels <<
";\n";
1170 outStream <<
" displacement = tex2D(normtex" << layer <<
", uv" << layer <<
").a\n"
1171 " * scaleBiasSpecular.x + scaleBiasSpecular.y;\n";
1172 outStream <<
" uv" << layer <<
" += TSeyeDir.xy * displacement;\n";
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";
1180 outStream <<
" litRes = litResLayer;\n";
1182 outStream <<
" litRes = lerp(litRes, litResLayer, " << blendWeightStr <<
");\n";
1186 outStream <<
" float4 diffuseSpecTex" << layer
1187 <<
" = tex2D(difftex" << layer <<
", uv" << layer <<
");\n";
1192 outStream <<
" diffuse = diffuseSpecTex0.rgb;\n";
1194 outStream <<
" specular = diffuseSpecTex0.a;\n";
1198 outStream <<
" diffuse = lerp(diffuse, diffuseSpecTex" << layer
1199 <<
".rgb, " << blendWeightStr <<
");\n";
1201 outStream <<
" specular = lerp(specular, diffuseSpecTex" << layer
1202 <<
".a, " << blendWeightStr <<
");\n";
1217 " oPos = mul(viewProjMatrix, worldPos);\n"
1218 " oUVMisc.xy = uv.xy;\n";
1220 bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
1223 if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR)
1226 " fogVal = saturate((oPos.z - fogParams.y) * fogParams.w);\n";
1231 " fogVal = 1 - saturate(1 / (exp(oPos.z * fogParams.x)));\n";
1236 generateVpDynamicShadows(prof, terrain, tt, outStream);
1250 generateFpDynamicShadows(prof, terrain, tt, outStream);
1252 " outputCol.rgb = diffuse * rtshadow;\n";
1257 " outputCol.rgb = diffuse;\n";
1265 outStream <<
" diffuse *= tex2D(globalColourMap, uv).rgb;\n";
1270 outStream <<
" shadow = tex2D(lightMap, uv).r;\n";
1275 generateFpDynamicShadows(prof, terrain, tt, outStream);
1279 outStream <<
" outputCol.rgb += ambient * diffuse + litRes.y * lightDiffuseColour * diffuse * shadow;\n";
1283 outStream <<
" specular = 1.0;\n";
1285 if (tt == RENDER_COMPOSITE_MAP)
1289 " outputCol.a = shadow;\n";
1294 outStream <<
" outputCol.rgb += litRes.z * lightSpecularColour * specular * shadow;\n";
1296 if (prof->getParent()->getDebugLevel())
1298 outStream <<
" outputCol.rg += lodInfo.xy;\n";
1303 bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
1306 outStream <<
" outputCol.rgb = lerp(outputCol.rgb, fogColour, fogVal);\n";
1310 outStream <<
" return outputCol;\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"
1325 "#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D \n"
1327 "float4 offsetSample(float4 uv, float2 offset, float invMapSize) \n"
1329 " return float4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w); \n"
1335 "float calcDepthShadow(sampler2D shadowMap, float4 uv, float invShadowMapSize) \n"
1337 " // 4-sample PCF \n"
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"
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"
1353 " shadow /= SHADOW_SAMPLES; \n"
1355 " return shadow; \n"
1361 "float calcSimpleShadow(sampler2D shadowMap, float4 shadowMapPos) \n"
1363 " return tex2Dproj(shadowMap, shadowMapPos).x; \n"
1374 "float calcPSSMDepthShadow(";
1379 "float calcPSSMSimpleShadow(";
1383 for (uint i = 0; i < numTextures; ++i)
1384 outStream <<
"sampler2D shadowMap" << i <<
", ";
1386 for (uint i = 0; i < numTextures; ++i)
1387 outStream <<
"float4 lsPos" << i <<
", ";
1391 for (uint i = 0; i < numTextures; ++i)
1392 outStream <<
"float invShadowmapSize" << i <<
", ";
1395 " float4 pssmSplitPoints, float camDepth) \n"
1398 " // calculate shadow \n";
1400 for (uint i = 0; i < numTextures; ++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";
1407 outStream <<
" else \n";
1414 " shadow = calcDepthShadow(shadowMap" << i <<
", lsPos" << i <<
", invShadowmapSize" << i <<
"); \n";
1419 " shadow = calcSimpleShadow(shadowMap" << i <<
", lsPos" << i <<
"); \n";
1426 " return shadow; \n"
1433 uint texCoord,
const SM2Profile* prof,
const Terrain* terrain,
TechniqueType tt, Ogre::StringStream& outStream)
1436 uint numTextures = 1;
1441 for (uint i = 0; i < numTextures; ++i)
1444 ", out float4 oLightSpacePos" << i <<
" : TEXCOORD" << texCoord++ <<
" \n" <<
1445 ", uniform float4x4 texViewProjMatrix" << i <<
" \n";
1461 uint numTextures = 1;
1468 for (uint i = 0; i < numTextures; ++i)
1471 " oLightSpacePos" << i <<
" = mul(texViewProjMatrix" << i <<
", worldPos); \n";
1484 " // pass cam depth\n"
1485 " oUVMisc.z = oPos.z;\n";
1491 uint* texCoord, uint* sampler,
const SM2Profile* prof,
const Terrain* terrain,
TechniqueType tt, Ogre::StringStream& outStream)
1494 mShadowSamplerStartHi = *sampler;
1495 else if (tt == LOW_LOD)
1496 mShadowSamplerStartLo = *sampler;
1499 uint numTextures = 1;
1504 ", uniform float4 pssmSplitPoints \n";
1506 for (uint i = 0; i < numTextures; ++i)
1509 ", float4 lightSpacePos" << i <<
" : TEXCOORD" << *texCoord <<
" \n" <<
1510 ", uniform sampler2D shadowMap" << i <<
" : register(s" << *sampler <<
") \n";
1511 *sampler = *sampler + 1;
1512 *texCoord = *texCoord + 1;
1516 ", uniform float inverseShadowmapSize" << i <<
" \n";
1529 " float camDepth = uvMisc.z;\n";
1534 " float rtshadow = calcPSSMDepthShadow(";
1539 " float rtshadow = calcPSSMSimpleShadow(";
1541 for (uint i = 0; i < numTextures; ++i)
1542 outStream <<
"shadowMap" << i <<
", ";
1545 for (uint i = 0; i < numTextures; ++i)
1546 outStream <<
"lightSpacePos" << i <<
", ";
1550 for (uint i = 0; i < numTextures; ++i)
1551 outStream <<
"inverseShadowmapSize" << i <<
", ";
1553 outStream <<
"\n" <<
1554 " pssmSplitPoints, camDepth);\n";
1561 " float rtshadow = calcDepthShadow(shadowMap0, lightSpacePos0, inverseShadowmapSize0);";
1566 " float rtshadow = calcSimpleShadow(shadowMap0, lightSpacePos0);";
1571 " shadow = min(shadow, rtshadow);\n";
1576HighLevelGpuProgramPtr
1580 HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1581 String progName = getVertexProgramName(prof, terrain, tt);
1583 HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1586 ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1587 "hlsl", GPT_VERTEX_PROGRAM);
1595 ret->setParameter(
"target",
"vs_4_0");
1597 ret->setParameter(
"target",
"vs_3_0");
1599 ret->setParameter(
"target",
"vs_2_0");
1600 ret->setParameter(
"entry_point",
"main_vp");
1606HighLevelGpuProgramPtr
1610 HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1611 String progName = getFragmentProgramName(prof, terrain, tt);
1613 HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1616 ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1617 "hlsl", GPT_FRAGMENT_PROGRAM);
1625 ret->setParameter(
"target",
"ps_4_0");
1627 ret->setParameter(
"target",
"ps_3_0");
1629 ret->setParameter(
"target",
"ps_2_x");
1630 ret->setParameter(
"entry_point",
"main_fp");
1637HighLevelGpuProgramPtr
1641 HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1642 String progName = getVertexProgramName(prof, terrain, tt);
1647 progName +=
"/hlod";
1650 progName +=
"/llod";
1652 case RENDER_COMPOSITE_MAP:
1653 progName +=
"/comp";
1657 HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1660 ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1661 "glsl", GPT_VERTEX_PROGRAM);
1672HighLevelGpuProgramPtr
1676 HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1677 String progName = getFragmentProgramName(prof, terrain, tt);
1679 HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1682 ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1683 "glsl", GPT_FRAGMENT_PROGRAM);
1695HighLevelGpuProgramPtr
1699 HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1700 String progName = getVertexProgramName(prof, terrain, tt);
1705 progName +=
"/hlod";
1708 progName +=
"/llod";
1710 case RENDER_COMPOSITE_MAP:
1711 progName +=
"/comp";
1715 HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1718 ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1719 "glsles", GPT_VERTEX_PROGRAM);
1730HighLevelGpuProgramPtr
1734 HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
1735 String progName = getFragmentProgramName(prof, terrain, tt);
1737 HighLevelGpuProgramPtr ret = mgr.getByName(progName);
1740 ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
1741 "glsles", GPT_FRAGMENT_PROGRAM);
Utility class to help with generating shaders for Cg / HLSL.
uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
void generateFpLayer(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, uint layer, Ogre::StringStream &outStream)
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
void generateVpDynamicShadows(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
void generateFpHeader(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
void generateFpDynamicShadowsHelpers(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
void generateFpDynamicShadowsParams(uint *texCoord, uint *sampler, const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
void generateVpFooter(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
void generateVpHeader(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
void generateFpFooter(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
void generateFpDynamicShadows(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
void generateVpLayer(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, uint layer, Ogre::StringStream &outStream)
Utility class to help with generating shaders for GLSL ES.
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Utility class to help with generating shaders for GLSL.
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
virtual void updateVpParams(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, const GpuProgramParametersSharedPtr ¶ms)
virtual HighLevelGpuProgramPtr generateFragmentProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
virtual void generateFragmentProgramSource(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
virtual void defaultVpParams(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, const HighLevelGpuProgramPtr &prog)
virtual void generateVertexProgramSource(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, Ogre::StringStream &outStream)
virtual HighLevelGpuProgramPtr generateVertexProgram(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
virtual void updateParams(const SM2Profile *prof, const MaterialPtr &mat, const Terrain *terrain, bool compositeMap)
virtual String getFragmentProgramName(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
virtual void updateFpParams(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, const GpuProgramParametersSharedPtr ¶ms)
static String getChannel(uint idx)
virtual void defaultFpParams(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt, const HighLevelGpuProgramPtr &prog)
virtual String getVertexProgramName(const SM2Profile *prof, const Terrain *terrain, TechniqueType tt)
Shader model 2 profile target.
void requestOptions(Terrain *terrain)
void setCompositeMapEnabled(bool enabled)
Whether to use the composite map to provide a lower LOD technique in the distance (default true).
bool isLayerParallaxMappingEnabled() const
Whether to support parallax mapping per layer in the shader (default true).
bool isGlobalColourMapEnabled() const
Whether to support a global colour map over the terrain in the shader, if it's present (default true)...
SM2Profile(TerrainMaterialGenerator *parent, const String &name, const String &desc)
void setReceiveDynamicShadowsLowLod(bool enabled)
Whether to use shadows on low LOD material rendering (when using composite map) (default false).
bool getReceiveDynamicShadowsDepth() const
Whether to use depth shadows (default false).
void updateParams(const MaterialPtr &mat, const Terrain *terrain)
bool isCompositeMapEnabled() const
Whether to use the composite map to provide a lower LOD technique in the distance (default true).
void setReceiveDynamicShadowsEnabled(bool enabled)
Whether to support dynamic texture shadows received from other objects, on the terrain (default true)...
void setReceiveDynamicShadowsDepth(bool enabled)
Whether to use depth shadows (default false).
void setLayerNormalMappingEnabled(bool enabled)
Whether to support normal mapping per layer in the shader (default true).
PSSMShadowCameraSetup * getReceiveDynamicShadowsPSSM() const
Whether to use PSSM support dynamic texture shadows, and if so the settings to use (default 0).
bool isVertexCompressionSupported() const
uint8 getMaxLayers(const Terrain *terrain) const
void setLightmapEnabled(bool enabled)
Whether to support a light map over the terrain in the shader, if it's present (default true).
bool isLayerNormalMappingEnabled() const
Whether to support normal mapping per layer in the shader (default true).
void setLayerSpecularMappingEnabled(bool enabled)
Whether to support specular mapping per layer in the shader (default true).
MaterialPtr generateForCompositeMap(const Terrain *terrain)
void updateParamsForCompositeMap(const MaterialPtr &mat, const Terrain *terrain)
bool _isSM4Available() const
void setReceiveDynamicShadowsPSSM(PSSMShadowCameraSetup *pssmSettings)
Whether to use PSSM support dynamic texture shadows, and if so the settings to use (default 0).
MaterialPtr generate(const Terrain *terrain)
bool isShadowingEnabled(TechniqueType tt, const Terrain *terrain) const
void setGlobalColourMapEnabled(bool enabled)
Whether to support a global colour map over the terrain in the shader, if it's present (default true)...
bool isLightmapEnabled() const
Whether to support a light map over the terrain in the shader, if it's present (default true).
bool _isSM3Available() const
Internal.
void addTechnique(const MaterialPtr &mat, const Terrain *terrain, TechniqueType tt)
void setLayerParallaxMappingEnabled(bool enabled)
Whether to support parallax mapping per layer in the shader (default true).
bool isLayerSpecularMappingEnabled() const
Whether to support specular mapping per layer in the shader (default true).
~TerrainPSSMMaterialGenerator()
TerrainPSSMMaterialGenerator()