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);
444 HighLevelGpuProgramPtr
448 HighLevelGpuProgramPtr ret = createVertexProgram(prof, terrain, tt);
450 StringUtil::StrStreamType 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*** ***";
464 HighLevelGpuProgramPtr
468 HighLevelGpuProgramPtr ret = createFragmentProgram(prof, terrain, tt);
470 StringUtil::StrStreamType 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:
730 HighLevelGpuProgramPtr
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");
754 HighLevelGpuProgramPtr
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";
1139 const SM2Profile* prof,
const Terrain* terrain,
TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream)
1146 const SM2Profile* prof,
const Terrain* terrain,
TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream)
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, StringUtil::StrStreamType& 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, StringUtil::StrStreamType& 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";
1576 HighLevelGpuProgramPtr
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");
1606 HighLevelGpuProgramPtr
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");
1637 HighLevelGpuProgramPtr
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);
1672 HighLevelGpuProgramPtr
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);
1695 HighLevelGpuProgramPtr
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);
1730 HighLevelGpuProgramPtr
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);