diff --git a/Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp b/Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp index 7255ea5645..932b705701 100644 --- a/Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp +++ b/Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp @@ -30,6 +30,7 @@ #include "renderInstance/renderDeferredMgr.h" #include "materials/processedMaterial.h" #include "materials/materialFeatureTypes.h" +#include "terrain/terrFeatureTypes.h" void DeferredRTLightingFeatHLSL::processPixMacros( Vector ¯os, @@ -132,6 +133,8 @@ void DeferredRTLightingFeatHLSL::processPix( Vector &component lightBufferTex->uniform = true; lightBufferTex->texture = true; lightBufferTex->constNum = lightInfoBuffer->constNum; + if (fd.features.hasFeature(MFT_TerrainDetailMap)) + lightInfoBuffer->constNum = 6; // Declare the RTLighting variables in this feature, they will either be assigned // in this feature, or in the tonemap/lightmap feature diff --git a/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp b/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp index 0946137859..98368374fd 100644 --- a/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp +++ b/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp @@ -89,27 +89,51 @@ Var* TerrainFeatHLSL::_getUniformVar( const char *name, const char *type, Consta return theVar; } -Var* TerrainFeatHLSL::_getInDetailCoord( Vector &componentList ) +Var* TerrainFeatHLSL::_computeAndGetInDetailCoord( MultiLine* meta, Vector &componentList ) { - String name( String::ToString( "detCoord%d", getProcessIndex() ) ); + String name("detCoord"); Var *inDet = (Var*)LangElement::find( name ); - if ( !inDet ) + if (!inDet) { - ShaderConnector *connectComp = dynamic_cast( componentList[C_CONNECTOR] ); + ShaderConnector *connectComp = dynamic_cast(componentList[C_CONNECTOR]); - inDet = connectComp->getElement( RT_TEXCOORD ); - inDet->setName( name ); - inDet->setStructName( "IN" ); - inDet->setType( "float4" ); + inDet = connectComp->getElement(RT_TEXCOORD); + inDet->setName(name); + inDet->setStructName("IN"); + inDet->setType("float4"); } - return inDet; + S32 index = getProcessIndex(); + + // Get the detail scale and fade info. + Var *detScaleAndFade = (Var*)LangElement::find(String::ToString("detailScaleAndFade%d", index)); + if (!detScaleAndFade) + { + detScaleAndFade = new Var; + detScaleAndFade->setType("float4"); + detScaleAndFade->setName(String::ToString("detailScaleAndFade%d", index)); + detScaleAndFade->uniform = true; + detScaleAndFade->constSortPos = cspPotentialPrimitive; + } + + Var *detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", index)); + if (!detCoord) + { + detCoord = new Var; + detCoord->setType("float4"); + detCoord->setName(String::ToString("detCoord%d", index)); + meta->addStatement(new GenOp(" @;\r\n", new DecOp(detCoord))); + meta->addStatement(new GenOp(" @.xyz = @.xyz * @.xyx;\r\n", detCoord, inDet, detScaleAndFade)); + meta->addStatement(new GenOp(" @.w = clamp((@.z - @.w) * @.w, 0.0, 1.0);\r\n", detCoord, detScaleAndFade, inDet, detScaleAndFade)); + } + + return detCoord; } -Var* TerrainFeatHLSL::_getInMacroCoord( Vector &componentList ) +Var* TerrainFeatHLSL::_computeAndGetInMacroCoord(MultiLine* meta, Vector &componentList ) { - String name( String::ToString( "macroCoord%d", getProcessIndex() ) ); + String name( "macroCoord" ); Var *inDet = (Var*)LangElement::find( name ); if ( !inDet ) @@ -122,12 +146,36 @@ Var* TerrainFeatHLSL::_getInMacroCoord( Vector &componentList inDet->setType( "float4" ); } - return inDet; + S32 index = getProcessIndex(); + + // Get the macro scale and fade info. + Var *macroScaleAndFade = (Var*)LangElement::find(String::ToString("macroScaleAndFade%d", index)); + if (!macroScaleAndFade) + { + macroScaleAndFade = new Var; + macroScaleAndFade->setType("float4"); + macroScaleAndFade->setName(String::ToString("macroScaleAndFade%d", index)); + macroScaleAndFade->uniform = true; + macroScaleAndFade->constSortPos = cspPotentialPrimitive; + } + + Var *macroCoord = (Var*)LangElement::find(String::ToString("macroCoord%d", index)); + if (!macroCoord) + { + macroCoord = new Var; + macroCoord->setType("float4"); + macroCoord->setName(String::ToString("macroCoord%d", index)); + meta->addStatement(new GenOp(" @;\r\n", new DecOp(macroCoord))); + meta->addStatement(new GenOp(" @.xyz = @.xyz * @.xyx;\r\n", macroCoord, inDet, macroScaleAndFade)); + meta->addStatement(new GenOp(" @.w = clamp((@.z - @.w) * @.w, 0.0, 1.0);\r\n", macroCoord, macroScaleAndFade, inDet, macroScaleAndFade)); + } + + return macroCoord; } Var* TerrainFeatHLSL::_getNormalMapTex() { - String name(String::ToString("normalMap%d", getProcessIndex())); + String name("normalMap"); Var *normalMap = (Var*)LangElement::find(name); if (!normalMap) @@ -359,13 +407,6 @@ void TerrainDetailMapFeatHLSL::processVert( Vector &component new DecOp( dist ), inPos, eyePos ) ); } - // grab connector texcoord register - ShaderConnector *connectComp = dynamic_cast( componentList[C_CONNECTOR] ); - Var *outTex = connectComp->getElement( RT_TEXCOORD ); - outTex->setName( String::ToString( "detCoord%d", detailIndex ) ); - outTex->setStructName( "OUT" ); - outTex->setType( "float4" ); - // Get the detail scale and fade info. Var *detScaleAndFade = new Var; detScaleAndFade->setType( "float4" ); @@ -382,11 +423,19 @@ void TerrainDetailMapFeatHLSL::processVert( Vector &component // // See TerrainBaseMapFeatHLSL::processVert(). // - meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) ); - // And sneak the detail fade thru the w detailCoord. - meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", - outTex, detScaleAndFade, dist, detScaleAndFade ) ); + // grab connector texcoord register + Var *outTex = (Var*)LangElement::find("detCoord"); + if (!outTex) + { + ShaderConnector *connectComp = dynamic_cast(componentList[C_CONNECTOR]); + outTex = connectComp->getElement(RT_TEXCOORD); + outTex->setName("detCoord"); + outTex->setStructName("OUT"); + outTex->setType("float4"); + } + meta->addStatement(new GenOp(" @.xyz = @.xyx;\r\n", outTex, inTex)); + meta->addStatement(new GenOp(" @.w = @;\r\n", outTex, dist)); output = meta; } @@ -457,7 +506,7 @@ void TerrainDetailMapFeatHLSL::processPix( Vector &component } // Grab the incoming detail coord. - Var *inDet = _getInDetailCoord( componentList ); + Var *inDet = _computeAndGetInDetailCoord( meta, componentList ); // Get the detail id. Var *detailInfo = _getDetailIdStrengthParallax(); @@ -483,7 +532,30 @@ void TerrainDetailMapFeatHLSL::processPix( Vector &component // Add to the blend total. - meta->addStatement(new GenOp(" @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend)); + meta->addStatement(new GenOp(" @ += @;\r\n", blendTotal, detailBlend)); + + Var *detailColor = (Var*)LangElement::find("detailColor"); + if (!detailColor) + { + detailColor = new Var; + detailColor->setType("float4"); + detailColor->setName("detailColor"); + meta->addStatement(new GenOp(" @;\r\n", new DecOp(detailColor))); + } + + // Get the detail texture. + Var *detailMap = (Var*)LangElement::find("detailMap"); + if (!detailMap) + { + detailMap = new Var; + detailMap->setType("SamplerState"); + detailMap->setName("detailMap"); + detailMap->uniform = true; + detailMap->sampler = true; + detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here + } + + S32 detailTexIndex = Var::getTexUnitNum(); // If we had a parallax feature... then factor in the parallax // amount so that it fades out with the layer blending. @@ -491,6 +563,8 @@ void TerrainDetailMapFeatHLSL::processPix( Vector &component { // Get the rest of our inputs. Var *normalMap = _getNormalMapTex(); + normalMap->constNum--; + detailTexIndex++; String name(String::ToString("normalMapTex%d", getProcessIndex())); Var *normalMapTex = (Var*)LangElement::find(name); @@ -502,7 +576,7 @@ void TerrainDetailMapFeatHLSL::processPix( Vector &component normalMapTex->setType("Texture2D"); normalMapTex->uniform = true; normalMapTex->texture = true; - normalMapTex->constNum = normalMap->constNum; + normalMapTex->constNum = Var::getTexUnitNum(); } // Call the library function to do the rest. @@ -518,32 +592,6 @@ void TerrainDetailMapFeatHLSL::processPix( Vector &component } } - Var *detailColor = (Var*)LangElement::find( "detailColor" ); - if ( !detailColor ) - { - detailColor = new Var; - detailColor->setType( "float4" ); - detailColor->setName( "detailColor" ); - meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) ); - } - - // Get the detail texture. - Var *detailMap = new Var; - detailMap->setType( "SamplerState" ); - detailMap->setName( String::ToString( "detailMap%d", detailIndex ) ); - detailMap->uniform = true; - detailMap->sampler = true; - detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here - - // If we're using SM 3.0 then take advantage of - // dynamic branching to skip layers per-pixel. - - - if ( GFX->getPixelShaderVersion() >= 3.0f ) - meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) ); - - meta->addStatement( new GenOp( " {\r\n" ) ); - // Note that we're doing the standard greyscale detail // map technique here which can darken and lighten the // diffuse texture. @@ -558,7 +606,17 @@ void TerrainDetailMapFeatHLSL::processPix( Vector &component detailTex->setType("Texture2D"); detailTex->uniform = true; detailTex->texture = true; - detailTex->constNum = detailMap->constNum; + detailTex->constNum = detailTexIndex; + + + // If we're using SM 3.0 then take advantage of + // dynamic branching to skip layers per-pixel. + + + if ( GFX->getPixelShaderVersion() >= 3.0f ) + meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) ); + + meta->addStatement( new GenOp( " {\r\n" ) ); if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex)) { @@ -605,6 +663,10 @@ ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialF // worldToTanget transform. if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) ) res.numTexReg += 4; + + // We always send the detail texture + // coord information to the pixel shader. + res.numTexReg += 1; } // sample from the detail texture for diffuse coloring. @@ -617,7 +679,7 @@ ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialF // Finally we always send the detail texture // coord to the pixel shader. - res.numTexReg += 1; + //res.numTexReg += 1; return res; } @@ -671,11 +733,16 @@ void TerrainMacroMapFeatHLSL::processVert( Vector &componentL } // grab connector texcoord register - ShaderConnector *connectComp = dynamic_cast( componentList[C_CONNECTOR] ); - Var *outTex = connectComp->getElement( RT_TEXCOORD ); - outTex->setName( String::ToString( "macroCoord%d", detailIndex ) ); - outTex->setStructName( "OUT" ); - outTex->setType( "float4" ); + Var *outTex = (Var*)LangElement::find("macroCoord"); + if (!outTex) + { + // grab connector texcoord register + ShaderConnector *connectComp = dynamic_cast(componentList[C_CONNECTOR]); + outTex = connectComp->getElement(RT_TEXCOORD); + outTex->setName("macroCoord"); + outTex->setStructName("OUT"); + outTex->setType("float4"); + } // Get the detail scale and fade info. Var *detScaleAndFade = new Var; @@ -685,11 +752,10 @@ void TerrainMacroMapFeatHLSL::processVert( Vector &componentL detScaleAndFade->constSortPos = cspPotentialPrimitive; // Setup the detail coord. - meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) ); + meta->addStatement(new GenOp(" @.xyz = @.xyx;\r\n", outTex, inTex)); // And sneak the detail fade thru the w detailCoord. - meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", - outTex, detScaleAndFade, dist, detScaleAndFade ) ); + meta->addStatement(new GenOp(" @.w = @;\r\n", outTex, dist)); output = meta; } @@ -761,7 +827,7 @@ void TerrainMacroMapFeatHLSL::processPix( Vector &componentL } // Grab the incoming detail coord. - Var *inDet = _getInMacroCoord( componentList ); + Var *inDet = _computeAndGetInMacroCoord( meta, componentList ); // Get the detail id. Var *detailInfo = _getMacroIdStrengthParallax(); @@ -786,7 +852,7 @@ void TerrainMacroMapFeatHLSL::processPix( Vector &componentL } // Add to the blend total. - meta->addStatement(new GenOp(" @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend)); + meta->addStatement(new GenOp(" @ += @;\r\n", blendTotal, detailBlend)); Var *detailColor = (Var*)LangElement::find( "macroColor" ); if ( !detailColor ) @@ -798,20 +864,24 @@ void TerrainMacroMapFeatHLSL::processPix( Vector &componentL } // Get the detail texture. - Var *detailMap = new Var; - detailMap->setType( "SamplerState" ); - detailMap->setName( String::ToString( "macroMap%d", detailIndex ) ); - detailMap->uniform = true; - detailMap->sampler = true; - detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here - + Var *detailMap = (Var*)LangElement::find("macroMap"); + if (!detailMap) + { + detailMap = new Var; + detailMap->setType("SamplerState"); + detailMap->setName("macroMap"); + detailMap->uniform = true; + detailMap->sampler = true; + detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here + } + //Create texture object for directx 11 Var *detailTex = new Var; detailTex->setName(String::ToString("macroMapTex%d", detailIndex)); detailTex->setType("Texture2D"); detailTex->uniform = true; detailTex->texture = true; - detailTex->constNum = detailMap->constNum; + detailTex->constNum = Var::getTexUnitNum(); // If we're using SM 3.0 then take advantage of // dynamic branching to skip layers per-pixel. @@ -932,7 +1002,7 @@ void TerrainNormalMapFeatHLSL::processPix( Vector &component Var *normalMap = _getNormalMapTex(); /// Get the texture coord. - Var *inDet = _getInDetailCoord( componentList ); + Var *inDet = _computeAndGetInDetailCoord( meta, componentList ); Var *inTex = getVertTexCoord( "texCoord" ); // Sample the normal map. @@ -950,7 +1020,7 @@ void TerrainNormalMapFeatHLSL::processPix( Vector &component normalMapTex->setType("Texture2D"); normalMapTex->uniform = true; normalMapTex->texture = true; - normalMapTex->constNum = normalMap->constNum; + normalMapTex->constNum = Var::getTexUnitNum(); } if (fd.features.hasFeature(MFT_TerrainSideProject, normalIndex)) diff --git a/Engine/source/terrain/hlsl/terrFeatureHLSL.h b/Engine/source/terrain/hlsl/terrFeatureHLSL.h index 2effbdc367..0c312b8576 100644 --- a/Engine/source/terrain/hlsl/terrFeatureHLSL.h +++ b/Engine/source/terrain/hlsl/terrFeatureHLSL.h @@ -41,9 +41,9 @@ class TerrainFeatHLSL : public ShaderFeatureHLSL public: TerrainFeatHLSL(); - Var* _getInDetailCoord(Vector &componentList ); + Var* _computeAndGetInDetailCoord(MultiLine* meta, Vector &componentList ); - Var* _getInMacroCoord(Vector &componentList ); + Var* _computeAndGetInMacroCoord(MultiLine* meta, Vector &componentList ); Var* _getNormalMapTex(); diff --git a/Engine/source/terrain/terrCellMaterial.cpp b/Engine/source/terrain/terrCellMaterial.cpp index cd1f123d07..9bdbf03404 100644 --- a/Engine/source/terrain/terrCellMaterial.cpp +++ b/Engine/source/terrain/terrCellMaterial.cpp @@ -37,7 +37,7 @@ #include "gfx/util/screenspace.h" #include "lighting/advanced/advancedLightBinManager.h" -S32 sgMaxTerrainMaterialsPerPass = 3; +S32 sgMaxTerrainMaterialsPerPass = 32; AFTER_MODULE_INIT( MaterialManager ) { @@ -55,12 +55,12 @@ Vector _initSamplerNames() samplerNames.push_back("$macrolayerTex"); samplerNames.push_back("$lightMapTex"); samplerNames.push_back("$lightInfoBuffer"); - for(int i = 0; i < 3; ++i) - { - samplerNames.push_back(avar("$normalMap%d",i)); - samplerNames.push_back(avar("$detailMap%d",i)); - samplerNames.push_back(avar("$macroMap%d",i)); - } + //for(int i = 0; i < 3; ++i) + //{ + samplerNames.push_back("$normalMap"); + samplerNames.push_back("$detailMap"); + samplerNames.push_back("$macroMap"); + //} return samplerNames; } @@ -595,10 +595,10 @@ bool TerrainCellMaterial::_createPass( Vector *materials, matInfo->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) ); matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%d", i ) ); - matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) ); - if ( matInfo->detailTexConst->isValid() ) + matInfo->detailTexConst = pass->shader->getShaderConstHandle(avar("$detailTex%d", i)); + if (matInfo->mat->getDetailMap().isNotEmpty() || matInfo->detailTexConst->isValid()) { - const S32 sampler = matInfo->detailTexConst->getSamplerRegister(); + const S32 sampler = pass->shader->getShaderConstHandle("$detailMap")->getSamplerRegister(); desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear(); desc.samplers[sampler].magFilter = GFXTextureFilterLinear; @@ -619,10 +619,10 @@ bool TerrainCellMaterial::_createPass( Vector *materials, matInfo->macroInfoVConst = pass->shader->getShaderConstHandle( avar( "$macroScaleAndFade%d", i ) ); matInfo->macroInfoPConst = pass->shader->getShaderConstHandle( avar( "$macroIdStrengthParallax%d", i ) ); - matInfo->macroTexConst = pass->shader->getShaderConstHandle( avar( "$macroMap%d", i ) ); - if ( matInfo->macroTexConst->isValid() ) + matInfo->macroTexConst = pass->shader->getShaderConstHandle(avar("$macroMapTex%d", i)); + if (matInfo->mat->getMacroMap().isNotEmpty() || matInfo->macroTexConst->isValid()) { - const S32 sampler = matInfo->macroTexConst->getSamplerRegister(); + const S32 sampler = pass->shader->getShaderConstHandle("$macroMap")->getSamplerRegister(); desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear(); desc.samplers[sampler].magFilter = GFXTextureFilterLinear; @@ -641,10 +641,10 @@ bool TerrainCellMaterial::_createPass( Vector *materials, } //end macro texture - matInfo->normalTexConst = pass->shader->getShaderConstHandle( avar( "$normalMap%d", i ) ); - if ( matInfo->normalTexConst->isValid() ) + matInfo->normalTexConst = pass->shader->getShaderConstHandle(avar("$normalMapTex%d", i)); + if (matInfo->mat->getNormalMap().isNotEmpty() || matInfo->normalTexConst->isValid()) { - const S32 sampler = matInfo->normalTexConst->getSamplerRegister(); + const S32 sampler = pass->shader->getShaderConstHandle("$normalMap")->getSamplerRegister(); desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear(); desc.samplers[sampler].magFilter = GFXTextureFilterLinear; @@ -803,16 +803,17 @@ bool TerrainCellMaterial::setupPass( const SceneRenderState *state, mCurrPass, pass.consts ); + U32 samplerIndex = 4; for ( U32 i=0; i < pass.materials.size(); i++ ) { MaterialInfo *matInfo = pass.materials[i]; - if ( matInfo->detailTexConst->isValid() ) - GFX->setTexture( matInfo->detailTexConst->getSamplerRegister(), matInfo->detailTex ); - if ( matInfo->macroTexConst->isValid() ) - GFX->setTexture( matInfo->macroTexConst->getSamplerRegister(), matInfo->macroTex ); - if ( matInfo->normalTexConst->isValid() ) - GFX->setTexture( matInfo->normalTexConst->getSamplerRegister(), matInfo->normalTex ); + if (matInfo->mat->getDetailMap().isNotEmpty() || matInfo->detailTexConst->isValid()) + GFX->setTexture(samplerIndex++, matInfo->detailTex); + if (matInfo->mat->getNormalMap().isNotEmpty() || matInfo->normalTexConst->isValid()) + GFX->setTexture(samplerIndex++, matInfo->normalTex); + if (matInfo->mat->getMacroMap().isNotEmpty() || matInfo->macroTexConst->isValid()) + GFX->setTexture(samplerIndex++, matInfo->macroTex); } pass.consts->setSafe( pass.layerSizeConst, (F32)mTerrain->mLayerTex.getWidth() );