//----------------------------------------------------------------------------------- void PbsMaterial::createTexturUnits(Pass* pass) { GpuProgramParametersSharedPtr fragmentParams = pass->getFragmentProgramParameters(); fragmentParams->setIgnoreMissingParams(true); // Create the texture unit states for (int i = 0; i < ST_COUNT; i++) { SamplerContainer& s = _samplers[i]; if (s.status == SS_ACTIVE || s.status == SS_ADDED || s.status == SS_UPDATED) { s.textureUnitState = pass->createTextureUnitState(); s.textureUnitState->setName("in_map_" + s.name); s.status = SS_UPDATED; } else { s.status = SS_NOT_ACTIVE; } } // set the sampler name for the texture unit state int size = pass->getNumTextureUnitStates(); for (int i = 0; i < size; i++) { TextureUnitState* tus = pass->getTextureUnitState(i); fragmentParams->setNamedConstant(tus->getName(), i); } _hasSamplerChanged = true; }
//--------------------------------------------------------------------- void TerrainMaterialGeneratorC::SM2Profile::ShaderHelper::updateVpParams( const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params) { params->setIgnoreMissingParams(true); uint maxLayers = prof->getMaxLayers(terrain); uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount())); uint numUVMul = numLayers / 4; if (numLayers % 4) ++numUVMul; for (uint i = 0; i < numUVMul; ++i) { Vector4 uvMul( terrain->getLayerUVMultiplier(i * 4), terrain->getLayerUVMultiplier(i * 4 + 1), terrain->getLayerUVMultiplier(i * 4 + 2), terrain->getLayerUVMultiplier(i * 4 + 3) ); params->setNamedConstant("uvMul_" + StringConverter::toString(i), uvMul); } if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP) { Real baseUVScale = 1.0f / (terrain->getSize() - 1); params->setNamedConstant("baseUVScale", baseUVScale); } }
void MaterialGenerator::vertexProgramParams(HighLevelGpuProgramPtr program) { GpuProgramParametersSharedPtr params = program->getDefaultParameters(); //#ifndef _DEBUG params->setIgnoreMissingParams(true); //#endif if (vpNeedWMat()) params->setNamedAutoConstant("wMat", GpuProgramParameters::ACT_WORLD_MATRIX); params->setNamedAutoConstant("wvpMat", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); if (vpNeedWvMat()) params->setNamedAutoConstant("wvMat", GpuProgramParameters::ACT_WORLDVIEW_MATRIX); if (fpNeedEyeVector() || mShader->wind == 1) params->setNamedAutoConstant("eyePosition", GpuProgramParameters::ACT_CAMERA_POSITION); params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); if (mShader->wind == 2) params->setNamedConstant("enableWind", Real(1.0)); if(MRTSupported()) { params->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE); } individualVertexProgramParams(params); }
/// Populate the passed parameters with name->index map, must be overridden void populateParameterNames(GpuProgramParametersSharedPtr params) { // Skip the normal implementation // Ensure we don't complain about missing parameter names params->setIgnoreMissingParams(true); }
//--------------------------------------------------------------------- void TerrainMaterialGeneratorC::SM2Profile::ShaderHelper::defaultFpParams( const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog) { GpuProgramParametersSharedPtr params = prog->getDefaultParameters(); params->setIgnoreMissingParams(true); params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); params->setNamedAutoConstant("cFarDistance", Ogre::GpuProgramParameters::ACT_FAR_CLIP_DISTANCE); params->setNamedAutoConstant("viewMatrix", GpuProgramParameters::ACT_WORLDVIEW_MATRIX); // tout sauf Z : VIEW_MATRIX }
//--------------------------------------------------------------------- void TerrainMaterialGeneratorC::SM2Profile::ShaderHelper::updateFpParams( const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params) { params->setIgnoreMissingParams(true); // TODO - parameterise this? /*Vector4 scaleBiasSpecular(0.03, -0.04, 32, 1); params->setNamedConstant("scaleBiasSpecular", scaleBiasSpecular);*/ }
HighLevelGpuProgramPtr ParticleMaterialGenerator::createSoftParticleVertexProgram() { HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); std::string progName = mDef->getName() + "_ambient_VP"; HighLevelGpuProgramPtr ret = mgr.getByName(progName); if (!ret.isNull()) mgr.remove(progName); ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM); ret->setParameter("profiles", "vs_4_0 vs_1_1 arbvp1"); ret->setParameter("entry_point", "main_vp"); StringUtil::StrStreamType sourceStr; sourceStr << "void main_vp( float4 position : POSITION, \n" " float4 color : COLOR, \n" " float2 texCoord : TEXCOORD0, \n" " out float4 oPosition : POSITION, \n" " out float4 objectPos : COLOR, \n" " out float4 oTexCoord : TEXCOORD0, \n" " out float4 oVertexColour : TEXCOORD1, \n" " out float4 oScreenPosition : TEXCOORD2, \n" " out float4 oWorldPosition : TEXCOORD3, \n" " uniform float enableFog, \n" " uniform float4 fogParams, \n" " uniform float4x4 wvpMat, \n" " uniform float4x4 wMat \n" ") \n" "{ \n" " oVertexColour = color; \n" " oPosition = mul(wvpMat, position); \n" " oWorldPosition = mul(wMat, position); \n" " oScreenPosition = oPosition; \n" " oTexCoord = float4(texCoord.x, texCoord.y, 1, 1); \n" " objectPos = position; \n" " objectPos.w = enableFog * saturate(fogParams.x * (oPosition.z - fogParams.y) * fogParams.w); \n" "} \n"; ret->setSource(sourceStr.str()); ret->load(); // params GpuProgramParametersSharedPtr params = ret->getDefaultParameters(); params->setIgnoreMissingParams(true); params->setNamedAutoConstant("wvpMat", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); params->setNamedAutoConstant("wMat", GpuProgramParameters::ACT_WORLD_MATRIX); params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); params->setNamedConstant("enableFog", mDef->mProps->fog ? Real(1.0) : Real(0.0)); return ret; }
void WaterMaterialGenerator::vertexProgramParams(Ogre::HighLevelGpuProgramPtr program) { GpuProgramParametersSharedPtr params = program->getDefaultParameters(); params->setIgnoreMissingParams(true); params->setNamedAutoConstant("wMat", GpuProgramParameters::ACT_WORLD_MATRIX); params->setNamedAutoConstant("wvpMat", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); individualVertexProgramParams(params); }
void MaterialFactory::setWind(bool wind) { for (std::vector<std::string>::iterator it=windMtrs.begin(); it != windMtrs.end(); ++it) { MaterialPtr mat = MaterialManager::getSingleton().getByName( (*it) ); if (mat->getTechnique(0)->getPass(0)->hasVertexProgram()) { GpuProgramParametersSharedPtr vparams = mat->getTechnique(0)->getPass(0)->getVertexProgramParameters(); vparams->setIgnoreMissingParams(true); vparams->setNamedConstant("enableWind", wind ? Real(1.0) : Real(0.0)); } } }
void MaterialGenerator::individualVertexProgramParams(GpuProgramParametersSharedPtr params) { //#ifndef _DEBUG params->setIgnoreMissingParams(true); //#endif if (needShadows()) for (int i=0; i<mParent->getNumShadowTex(); ++i) { params->setNamedAutoConstant("texWorldViewProjMatrix"+toStr(i), GpuProgramParameters::ACT_TEXTURE_WORLDVIEWPROJ_MATRIX, i); } params->setNamedConstant("enableFog", mDef->mProps->fog ? Real(1.0) : Real(0.0)); }
//----------------------------------------------------------------------- GpuProgramParametersSharedPtr UnifiedHighLevelGpuProgram::createParameters(void) { if (isSupported()) { return _getDelegate()->createParameters(); } else { // return a default set GpuProgramParametersSharedPtr params = GpuProgramManager::getSingleton().createParameters(); // avoid any errors on parameter names that don't exist params->setIgnoreMissingParams(true); return params; } }
void WaterMaterialGenerator::fragmentProgramParams(Ogre::HighLevelGpuProgramPtr program) { GpuProgramParametersSharedPtr params = program->getDefaultParameters(); params->setIgnoreMissingParams(true); params->setNamedAutoConstant("iTWMat", GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX); params->setNamedAutoConstant("fogColor", GpuProgramParameters::ACT_FOG_COLOUR); params->setNamedAutoConstant("lightSpec0", GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, 0); params->setNamedAutoConstant("lightPos0", GpuProgramParameters::ACT_LIGHT_POSITION, 0); params->setNamedAutoConstant("camPos", GpuProgramParameters::ACT_CAMERA_POSITION); params->setNamedAutoConstant("time", GpuProgramParameters::ACT_TIME); params->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); params->setNamedAutoConstant("lightDiff", GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, 0); params->setNamedAutoConstant("inverseProjection", GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING); params->setNamedConstantFromTime("time", 1); individualFragmentProgramParams(params); }
//----------------------------------------------------------------------------- void GLSLESProgramProcessor::bindTextureSamplers(Program* pCpuProgram, GpuProgramPtr pGpuProgram) { GpuProgramParametersSharedPtr pGpuParams = pGpuProgram->getDefaultParameters(); const UniformParameterList& progParams = pCpuProgram->getParameters(); UniformParameterConstIterator itParams; // Bind the samplers. for (itParams = progParams.begin(); itParams != progParams.end(); ++itParams) { const UniformParameterPtr pCurParam = *itParams; if (pCurParam->isSampler()) { // The optimizer may remove some unnecessary parameters, so we should ignore them pGpuParams->setIgnoreMissingParams(true); pGpuParams->setNamedConstant(pCurParam->getName(), pCurParam->getIndex()); } } }
//------------------------------------------------------------------------------------------------------- // utility //------------------------------------------------------------------------------------------------------- void CarModel::UpdateLightMap() { MaterialPtr mtr; for (int i=0; i < NumMaterials; ++i) { mtr = MaterialManager::getSingleton().getByName(sMtr[i]); if (!mtr.isNull()) { Material::TechniqueIterator techIt = mtr->getTechniqueIterator(); while (techIt.hasMoreElements()) { Technique* tech = techIt.getNext(); Technique::PassIterator passIt = tech->getPassIterator(); while (passIt.hasMoreElements()) { Pass* pass = passIt.getNext(); if (pass->hasFragmentProgram()) { GpuProgramParametersSharedPtr params = pass->getFragmentProgramParameters(); params->setIgnoreMissingParams(true); // don't throw exception if material doesnt use lightmap params->setNamedConstant("enableTerrainLightMap", bLightMapEnabled ? 1.f : 0.f); } } } } } }
//--------------------------------------------------------------------- void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::defaultVpParams( const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog) { GpuProgramParametersSharedPtr params = prog->getDefaultParameters(); params->setIgnoreMissingParams(true); params->setNamedAutoConstant("worldMatrix", GpuProgramParameters::ACT_WORLD_MATRIX); params->setNamedAutoConstant("viewProjMatrix", GpuProgramParameters::ACT_VIEWPROJ_MATRIX); params->setNamedAutoConstant("lodMorph", GpuProgramParameters::ACT_CUSTOM, Terrain::LOD_MORPH_CUSTOM_PARAM); params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); if (prof->isShadowingEnabled(tt, terrain)) { uint numTextures = 1; if (prof->getReceiveDynamicShadowsPSSM()) { numTextures = (uint)prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); } for (uint i = 0; i < numTextures; ++i) { params->setNamedAutoConstant("texViewProjMatrix" + StringConverter::toString(i), GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i); if (prof->getReceiveDynamicShadowsDepth()) { params->setNamedAutoConstant("depthRange" + StringConverter::toString(i), GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE, i); } } } if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP) { Matrix4 posIndexToObjectSpace; terrain->getPointTransform(&posIndexToObjectSpace); params->setNamedConstant("posIndexToObjectSpace", posIndexToObjectSpace); } }
//--------------------------------------------------------------------- void TerrainMaterialGeneratorC::SM2Profile::ShaderHelper::defaultVpParams( const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog) { GpuProgramParametersSharedPtr params = prog->getDefaultParameters(); params->setIgnoreMissingParams(true); params->setNamedAutoConstant("worldMatrix", GpuProgramParameters::ACT_WORLD_MATRIX); params->setNamedAutoConstant("viewMatrix", GpuProgramParameters::ACT_WORLDVIEW_MATRIX); params->setNamedAutoConstant("viewProjMatrix", GpuProgramParameters::ACT_VIEWPROJ_MATRIX); params->setNamedAutoConstant("lodMorph", GpuProgramParameters::ACT_CUSTOM, Terrain::LOD_MORPH_CUSTOM_PARAM); params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP) { Matrix4 posIndexToObjectSpace; terrain->getPointTransform(&posIndexToObjectSpace); params->setNamedConstant("posIndexToObjectSpace", posIndexToObjectSpace); } }
void BatchPage::_updateShaders() { if (!shadersSupported) return; uint32 i = 0; BatchedGeometry::SubBatchIterator it = batch->getSubBatchIterator(); while (it.hasMoreElements()){ BatchedGeometry::SubBatch *subBatch = it.getNext(); MaterialPtr mat = unfadedMaterials[i++]; //Check if lighting should be enabled bool lightingEnabled = false; for (unsigned short t = 0; t < mat->getNumTechniques(); ++t){ Technique *tech = mat->getTechnique(t); for (unsigned short p = 0; p < tech->getNumPasses(); ++p){ Pass *pass = tech->getPass(p); if (pass->getLightingEnabled()) { lightingEnabled = true; break; } } if (lightingEnabled) break; } //Compile the CG shader script based on various material / fade options StringUtil::StrStreamType tmpName; tmpName << "BatchPage_"; if (fadeEnabled) tmpName << "fade_"; if (lightingEnabled) tmpName << "lit_"; if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL) tmpName << "clr_"; for (unsigned short i = 0; i < subBatch->vertexData->vertexDeclaration->getElementCount(); ++i) { const VertexElement *el = subBatch->vertexData->vertexDeclaration->getElement(i); if (el->getSemantic() == VES_TEXTURE_COORDINATES) { String uvType = ""; switch (el->getType()) { case VET_FLOAT1: uvType = "1"; break; case VET_FLOAT2: uvType = "2"; break; case VET_FLOAT3: uvType = "3"; break; case VET_FLOAT4: uvType = "4"; break; } tmpName << uvType << '_'; } } tmpName << "vp"; const String vertexProgName = tmpName.str(); String shaderLanguage = ShaderHelper::getShaderLanguage(); //If the shader hasn't been created yet, create it if (HighLevelGpuProgramManager::getSingleton().getByName(vertexProgName).isNull()) { Pass *pass = mat->getTechnique(0)->getPass(0); String vertexProgSource; if(!shaderLanguage.compare("hlsl") || !shaderLanguage.compare("cg")) { vertexProgSource = "void main( \n" " float4 iPosition : POSITION, \n" " float3 normal : NORMAL, \n" " out float4 oPosition : POSITION, \n"; if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL) vertexProgSource += " float4 iColor : COLOR, \n"; unsigned texNum = 0; for (unsigned short i = 0; i < subBatch->vertexData->vertexDeclaration->getElementCount(); ++i) { const VertexElement *el = subBatch->vertexData->vertexDeclaration->getElement(i); if (el->getSemantic() == VES_TEXTURE_COORDINATES) { String uvType = ""; switch (el->getType()) { case VET_FLOAT1: uvType = "float"; break; case VET_FLOAT2: uvType = "float2"; break; case VET_FLOAT3: uvType = "float3"; break; case VET_FLOAT4: uvType = "float4"; break; } vertexProgSource += " " + uvType + " iUV" + StringConverter::toString(texNum) + " : TEXCOORD" + StringConverter::toString(texNum) + ", \n" " out " + uvType + " oUV" + StringConverter::toString(texNum) + " : TEXCOORD" + StringConverter::toString(texNum) + ", \n"; ++texNum; } } vertexProgSource += " out float oFog : FOG, \n" " out float4 oColor : COLOR, \n" " uniform float4 iFogParams, \n"; if (lightingEnabled) vertexProgSource += " uniform float4 objSpaceLight, \n" " uniform float4 lightDiffuse, \n" " uniform float4 lightAmbient, \n"; if (fadeEnabled) vertexProgSource += " uniform float3 camPos, \n"; vertexProgSource += " uniform float4x4 worldViewProj, \n" " uniform float fadeGap, \n" " uniform float invisibleDist )\n" "{ \n"; if (lightingEnabled) { //Perform lighting calculations (no specular) vertexProgSource += " float3 light = normalize(objSpaceLight.xyz - (iPosition.xyz * objSpaceLight.w)); \n" " float diffuseFactor = max(dot(normal, light), 0); \n"; if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL) vertexProgSource += "oColor = (lightAmbient + diffuseFactor * lightDiffuse) * iColor; \n"; else vertexProgSource += "oColor = (lightAmbient + diffuseFactor * lightDiffuse); \n"; } else { if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL) vertexProgSource += "oColor = iColor; \n"; else vertexProgSource += "oColor = float4(1, 1, 1, 1); \n"; } if (fadeEnabled) vertexProgSource += //Fade out in the distance " float dist = distance(camPos.xz, iPosition.xz); \n" " oColor.a *= (invisibleDist - dist) / fadeGap; \n"; texNum = 0; for (unsigned short i = 0; i < subBatch->vertexData->vertexDeclaration->getElementCount(); ++i) { const VertexElement *el = subBatch->vertexData->vertexDeclaration->getElement(i); if (el->getSemantic() == VES_TEXTURE_COORDINATES) { vertexProgSource += " oUV" + StringConverter::toString(texNum) + " = iUV" + StringConverter::toString(texNum) + "; \n"; ++texNum; } } vertexProgSource += " oPosition = mul(worldViewProj, iPosition); \n"; if (sceneMgr->getFogMode() == Ogre::FOG_EXP2) { vertexProgSource += " oFog = 1 - clamp (pow (2.71828, -oPosition.z * iFogParams.x), 0, 1); \n"; } else { vertexProgSource += " oFog = oPosition.z; \n"; } vertexProgSource += "}"; } if(!shaderLanguage.compare("glsl")) { vertexProgSource = "uniform float fadeGap; \n" "uniform float invisibleDist; \n"; if (lightingEnabled) vertexProgSource += "uniform vec4 objSpaceLight; \n" "uniform vec4 lightDiffuse; \n" "uniform vec4 lightAmbient; \n"; if (fadeEnabled) vertexProgSource += "uniform vec3 camPos; \n"; vertexProgSource += "void main() \n" "{ \n"; if (lightingEnabled) { //Perform lighting calculations (no specular) vertexProgSource += " vec3 light = normalize(objSpaceLight.xyz - (gl_Vertex.xyz * objSpaceLight.w)); \n" " float diffuseFactor = max(dot(gl_Normal, light), 0.0); \n"; if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL) { vertexProgSource += " gl_FrontColor = (lightAmbient + diffuseFactor * lightDiffuse) * gl_Color; \n"; } else { vertexProgSource += " gl_FrontColor = (lightAmbient + diffuseFactor * lightDiffuse); \n"; } } else { if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL) { vertexProgSource += " gl_FrontColor = gl_Color; \n"; } else { vertexProgSource += " gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0); \n"; } } if (fadeEnabled) { vertexProgSource += //Fade out in the distance " float dist = distance(camPos.xz, gl_Vertex.xz); \n" " gl_FrontColor.a *= (invisibleDist - dist) / fadeGap; \n"; } unsigned texNum = 0; for (unsigned short i = 0; i < subBatch->vertexData->vertexDeclaration->getElementCount(); ++i) { const VertexElement *el = subBatch->vertexData->vertexDeclaration->getElement(i); if (el->getSemantic() == VES_TEXTURE_COORDINATES) { vertexProgSource += " gl_TexCoord[" + StringConverter::toString(texNum) + "] = gl_MultiTexCoord" + StringConverter::toString(texNum) + "; \n"; ++texNum; } } vertexProgSource += " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"; if (sceneMgr->getFogMode() == Ogre::FOG_EXP2) { vertexProgSource += " gl_FogFragCoord = clamp(exp(- gl_Fog.density * gl_Fog.density * gl_Position.z * gl_Position.z), 0.0, 1.0); \n"; } else { vertexProgSource += " gl_FogFragCoord = gl_Position.z; \n"; } vertexProgSource += "}"; } HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().createProgram( vertexProgName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, shaderLanguage, GPT_VERTEX_PROGRAM); vertexShader->setSource(vertexProgSource); if (shaderLanguage == "hlsl") { vertexShader->setParameter("target", "vs_1_1"); vertexShader->setParameter("entry_point", "main"); } else if(shaderLanguage == "cg") { vertexShader->setParameter("profiles", "vs_1_1 arbvp1"); vertexShader->setParameter("entry_point", "main"); } // GLSL can only have one entry point "main". vertexShader->load(); if (vertexShader->hasCompileError()) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Error loading the batching vertex shader.", "BatchPage::_updateShaders()"); } } std::string fragmentProgramName("BatchFragStandard"); String fragmentProgSource; //We also need a fragment program to go with our vertex program. Especially on ATI cards on Linux where we can't mix shaders and the fixed function pipeline. HighLevelGpuProgramPtr fragShader = static_cast<HighLevelGpuProgramPtr>(HighLevelGpuProgramManager::getSingleton().getByName(fragmentProgramName)); if (fragShader.isNull()){ Pass *pass = mat->getTechnique(0)->getPass(0); if (shaderLanguage == "glsl") { fragmentProgSource = "uniform sampler2D diffuseMap;\n" "void main() {" " gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].st);" " gl_FragColor.rgb = mix(gl_Fog.color, (gl_LightModel.ambient * gl_FragColor + gl_FragColor), gl_FogFragCoord).rgb;" "}"; } else { fragmentProgSource = "void main \n" "( \n" " float2 iTexcoord : TEXCOORD0, \n" " float iFog : FOG, \n" " out float4 oColour : COLOR, \n" " uniform sampler2D diffuseTexture : TEXUNIT0, \n" " uniform float3 iFogColour \n" ") \n" "{ \n" " oColour = tex2D(diffuseTexture, iTexcoord.xy); \n" " oColour.xyz = lerp(oColour.xyz, iFogColour, iFog);\n" "}"; } fragShader = HighLevelGpuProgramManager::getSingleton().createProgram( fragmentProgramName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, shaderLanguage, GPT_FRAGMENT_PROGRAM); fragShader->setSource(fragmentProgSource); if (shaderLanguage == "hlsl") { fragShader->setParameter("entry_point", "main"); fragShader->setParameter("target", "ps_2_0"); } else if (shaderLanguage == "cg") { fragShader->setParameter("profiles", "ps_2_0 arbfp1"); fragShader->setParameter("entry_point", "main"); } fragShader->load(); if (fragShader->hasCompileError()) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Error loading the batching fragment shader.", "BatchPage::_updateShaders()"); } } //Now that the shader is ready to be applied, apply it StringUtil::StrStreamType materialSignature; materialSignature << "BatchMat|"; materialSignature << mat->getName() << "|"; if (fadeEnabled){ materialSignature << visibleDist << "|"; materialSignature << invisibleDist << "|"; } //Search for the desired material MaterialPtr generatedMaterial = MaterialManager::getSingleton().getByName(materialSignature.str()); if (generatedMaterial.isNull()){ //Clone the material generatedMaterial = mat->clone(materialSignature.str()); //And apply the fade shader Ogre::Material::TechniqueIterator I = generatedMaterial->getSupportedTechniqueIterator(); while (I.hasMoreElements()) { Technique *tech = I.getNext(); for (unsigned short p = 0; p < tech->getNumPasses(); ++p){ Pass *pass = tech->getPass(p); //Setup vertex program if (pass->getVertexProgramName() == "") pass->setVertexProgram(vertexProgName); if (pass->getFragmentProgramName() == "" && fragShader->isSupported()) pass->setFragmentProgram(fragmentProgramName); try{ GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); params->setIgnoreMissingParams(true); if (lightingEnabled) { params->setNamedAutoConstant("objSpaceLight", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE); params->setNamedAutoConstant("lightDiffuse", GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR); params->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR); //params->setNamedAutoConstant("matAmbient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR); } if (shaderLanguage.compare("glsl") == 0) { //glsl can use the built in gl_ModelViewProjectionMatrix params->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); } else { params->setNamedAutoConstant("iFogParams", GpuProgramParameters::ACT_FOG_PARAMS); } if (fadeEnabled) { params->setNamedAutoConstant("camPos", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); //Set fade ranges params->setNamedAutoConstant("invisibleDist", GpuProgramParameters::ACT_CUSTOM); params->setNamedConstant("invisibleDist", invisibleDist); params->setNamedAutoConstant("fadeGap", GpuProgramParameters::ACT_CUSTOM); params->setNamedConstant("fadeGap", invisibleDist - visibleDist); if (pass->getAlphaRejectFunction() == CMPF_ALWAYS_PASS) pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); } if (pass->hasFragmentProgram()) { params = pass->getFragmentProgramParameters(); params->setIgnoreMissingParams(true); params->setNamedAutoConstant("iFogColour", GpuProgramParameters::ACT_FOG_COLOUR); } } catch (...) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Error configuring batched geometry transitions. If you're using materials with custom vertex shaders, they will need to implement fade transitions to be compatible with BatchPage.", "BatchPage::_updateShaders()"); } } } } //Apply the material subBatch->setMaterial(generatedMaterial); } }
//----------------------------------------------------------------------------------- void PbsMaterial::updateUniforms(const Pass* pass, const AutoParamDataSource* source, const LightList* pLightList) { // Vertex program GpuProgramParametersSharedPtr vertexParams = pass->getVertexProgramParameters(); vertexParams->setIgnoreMissingParams(true); vertexParams->setNamedAutoConstant("mvpMat", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); vertexParams->setNamedAutoConstant("mvMat", GpuProgramParameters::ACT_WORLDVIEW_MATRIX); // Fragment program GpuProgramParametersSharedPtr fragmentParams = pass->getFragmentProgramParameters(); fragmentParams->setNamedAutoConstant("ivMat", GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX); fragmentParams->setNamedConstant("in_albedo", mAlbedo); fragmentParams->setNamedConstant("in_f0", mF0); fragmentParams->setNamedConstant("in_roughness", mRoughness); fragmentParams->setNamedConstant("in_light_roughness_offset", mLightRoughnessOffset); fragmentParams->setNamedConstant("in_offset_main", mMainOffset); fragmentParams->setNamedConstant("in_scale_main", mMainScale); fragmentParams->setNamedConstant("in_offset_d1", mD1Offset); fragmentParams->setNamedConstant("in_scale_d1", mD1Scale); fragmentParams->setNamedConstant("in_offset_d2", mD2Offset); fragmentParams->setNamedConstant("in_scale_d2", mD2Scale); // Set light uniforms unsigned int count = std::min(mDirectionalLightCount + mPointLightCount + mSpotLightCount, maxLightCount); if (count) { Matrix4 viewMatrix = source->getViewMatrix(); Quaternion viewMatrixQuat = viewMatrix.extractQuaternion(); int directionalLightIndex = 0; int pointLightLightIndex = 0; int spotLightIndex = 0; for (unsigned int i = 0; i < count; i++) { Light* light = (*pLightList)[i]; int index; if (light->getType() == Light::LT_DIRECTIONAL) { index = directionalLightIndex; directionalLightIndex++; } else if (light->getType() == Light::LT_POINT) { index = mDirectionalLightCount + pointLightLightIndex; pointLightLightIndex++; } else { index = mDirectionalLightCount + mPointLightCount + spotLightIndex; spotLightIndex++; } Vector3 pos = viewMatrix * light->getDerivedPosition(); mLightPositions_es[index * 4 + 0] = pos.x; mLightPositions_es[index * 4 + 1] = pos.y; mLightPositions_es[index * 4 + 2] = pos.z; Vector3 dir = -(viewMatrixQuat * light->getDerivedDirection()).normalisedCopy(); mLightDirections_es[index * 4 + 0] = dir.x; mLightDirections_es[index * 4 + 1] = dir.y; mLightDirections_es[index * 4 + 2] = dir.z; ColourValue color = light->getDiffuseColour(); mLightColors[index * 4 + 0] = color.r; mLightColors[index* 4 + 1] = color.g; mLightColors[index* 4 + 2] = color.b; mLightParameters[index * 4 + 0] = light->getAttenuationRange(); mLightParameters[index * 4 + 1] = Math::Cos(light->getSpotlightOuterAngle() / 2.0); mLightParameters[index * 4 + 2] = light->getSpotlightFalloff(); } fragmentParams->setNamedConstant("lightPositions_es", &(mLightPositions_es[0]), count); fragmentParams->setNamedConstant("lightDirections_es", &(mLightDirections_es[0]), count); fragmentParams->setNamedConstant("lightColors", &(mLightColors[0]), count); fragmentParams->setNamedConstant("lightParameters", &(mLightParameters[0]), count); } // update the textures if (_hasSamplerChanged) { for (int i = 0; i < ST_COUNT; i++) { SamplerContainer& s = _samplers[i]; if (s.status == SS_UPDATED) { updateTexturUnits(s.textureUnitState, fragmentParams, s, i); s.status = SS_ACTIVE; } } _hasSamplerChanged = false; } }
//--------------------------------------------------------------------- void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::defaultFpParams( const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog) { GpuProgramParametersSharedPtr params = prog->getDefaultParameters(); params->setIgnoreMissingParams(true); params->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); params->setNamedAutoConstant("lightPosObjSpace", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, 0); params->setNamedAutoConstant("lightDiffuseColour", GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, 0); params->setNamedAutoConstant("lightSpecularColour", GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, 0); params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); if (prof->isShadowingEnabled(tt, terrain)) { uint numTextures = 1; if (prof->getReceiveDynamicShadowsPSSM()) { PSSMShadowCameraSetup* pssm = prof->getReceiveDynamicShadowsPSSM(); numTextures = (uint)pssm->getSplitCount(); Vector4 splitPoints; const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssm->getSplitPoints(); // Populate from split point 1, not 0, since split 0 isn't useful (usually 0) for (uint i = 1; i < numTextures; ++i) { splitPoints[i-1] = splitPointList[i]; } params->setNamedConstant("pssmSplitPoints", splitPoints); } if (prof->getReceiveDynamicShadowsDepth()) { size_t samplerOffset = (tt == HIGH_LOD) ? mShadowSamplerStartHi : mShadowSamplerStartLo; for (uint i = 0; i < numTextures; ++i) { params->setNamedAutoConstant("inverseShadowmapSize" + StringConverter::toString(i), GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i + samplerOffset); } } } // Explicitly bind samplers for GLSL if ((prof->_getShaderLanguage() == "glsl") || (prof->_getShaderLanguage() == "glsles")) { int numSamplers = 0; if (tt == LOW_LOD) { params->setNamedConstant("compositeMap", (int)numSamplers++); } else { params->setNamedConstant("globalNormal", (int)numSamplers++); if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) { params->setNamedConstant("globalColourMap", (int)numSamplers++); } if (prof->isLightmapEnabled()) { params->setNamedConstant("lightMap", (int)numSamplers++); } uint maxLayers = prof->getMaxLayers(terrain); uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()); uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount())); // Blend textures - sampler definitions for (uint i = 0; i < numBlendTextures; ++i) { params->setNamedConstant("blendTex" + StringConverter::toString(i), (int)numSamplers++); } // Layer textures - sampler definitions & UV multipliers for (uint i = 0; i < numLayers; ++i) { params->setNamedConstant("difftex" + StringConverter::toString(i), (int)numSamplers++); params->setNamedConstant("normtex" + StringConverter::toString(i), (int)numSamplers++); } uint numShadowTextures = 1; if (prof->getReceiveDynamicShadowsPSSM()) numShadowTextures = (uint)prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); for (uint i = 0; i < numShadowTextures; ++i) { if (prof->isShadowingEnabled(tt, terrain)) params->setNamedConstant("shadowMap" + StringConverter::toString(i), (int)numSamplers++); } } } }