Merge pull request #1519 from Azaezel/deferredShading

Deferred shading
This commit is contained in:
Areloch 2016-02-27 15:08:20 -06:00
commit 908be4818f
112 changed files with 2645 additions and 680 deletions

View file

@ -26,6 +26,7 @@
#include "terrain/terrFeatureTypes.h"
#include "materials/materialFeatureTypes.h"
#include "materials/materialFeatureData.h"
#include "materials/processedMaterial.h"
#include "gfx/gfxDevice.h"
#include "shaderGen/langElement.h"
#include "shaderGen/shaderOp.h"
@ -48,6 +49,10 @@ namespace
FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureGLSL( "Terrain Side Projection" ) );
FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatGLSL );
FEATUREMGR->registerFeature( MFT_DeferredTerrainBaseMap, new TerrainBaseMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_DeferredTerrainMacroMap, new TerrainMacroMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_DeferredTerrainDetailMap, new TerrainDetailMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatGLSL );
}
};
@ -250,10 +255,6 @@ void TerrainBaseMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
// grab connector texcoord register
Var *texCoord = getInTexCoord( "texCoord", "vec3", true, componentList );
// We do nothing more if this is a prepass.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
return;
// create texture var
Var *diffuseMap = new Var;
diffuseMap->setType( "sampler2D" );
@ -269,7 +270,14 @@ void TerrainBaseMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
baseColor->setName( "baseColor" );
meta->addStatement( new GenOp( " @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", baseColor, baseColor));
meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul ) ) );
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
if(fd.features.hasFeature(MFT_isDeferred))
{
target= ShaderFeature::RenderTarget1;
}
meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul,NULL,target ) ) );
output = meta;
}
@ -278,14 +286,16 @@ ShaderFeature::Resources TerrainBaseMapFeatGLSL::getResources( const MaterialFea
{
Resources res;
res.numTexReg = 1;
// We only sample from the base map during a diffuse pass.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
res.numTex = 1;
return res;
}
U32 TerrainBaseMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
{
return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
}
TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL()
: mTorqueDep( "shaders/common/gl/torque.glsl" ),
mTerrainDep( "shaders/common/terrain/terrain.glsl" )
@ -386,6 +396,9 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
const S32 detailIndex = getProcessIndex();
Var *inTex = getVertTexCoord( "texCoord" );
// new terrain
bool hasNormal = fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex);
MultiLine *meta = new MultiLine;
// We need the negative tangent space view vector
@ -454,6 +467,100 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
// New terrain
Var *lerpBlend = (Var*)LangElement::find("lerpBlend");
if (!lerpBlend)
{
lerpBlend = new Var;
lerpBlend->setType("float");
lerpBlend->setName("lerpBlend");
lerpBlend->uniform = true;
lerpBlend->constSortPos = cspPrimitive;
}
Var *blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", detailIndex));
if (!blendDepth)
{
blendDepth = new Var;
blendDepth->setType("float");
blendDepth->setName(String::ToString("blendDepth%d", detailIndex));
blendDepth->uniform = true;
blendDepth->constSortPos = cspPrimitive;
}
Var *baseColor = (Var*)LangElement::find("baseColor");
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
if(fd.features.hasFeature( MFT_DeferredTerrainDetailMap ))
target= ShaderFeature::RenderTarget1;
Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
if (!outColor)
{
// create color var
outColor = new Var;
outColor->setType("float4");
outColor->setName("col");
outColor->setStructName("OUT");
meta->addStatement(new GenOp(" @;\r\n", outColor));
}
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("sampler2D");
detailMap->setName(String::ToString("detailMap%d", detailIndex));
detailMap->uniform = true;
detailMap->sampler = true;
detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here
// Get the normal map texture.
Var *normalMap = _getNormalMapTex();
// Issue happens somewhere here -----
// Sample the normal map.
//
// We take two normal samples and lerp between them for
// side projection layers... else a single sample.
LangElement *texOp;
// Note that we're doing the standard greyscale detail
// map technique here which can darken and lighten the
// diffuse texture.
//
// We take two color samples and lerp between them for
// side projection layers... else a single sample.
//
if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
{
meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, detailMap, inDet, inTex));
texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
normalMap, inDet, normalMap, inDet, inTex);
}
else
{
meta->addStatement(new GenOp(" @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet));
texOp = new GenOp("tex2D(@, @.xy)", normalMap, inDet);
}
// New terrain
// Get a var and accumulate the blend amount.
Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
if ( !blendTotal )
@ -487,46 +594,6 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
}
}
// If this is a prepass then we skip color.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
{
// Check to see if we have a gbuffer normal.
Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
// If we have a gbuffer normal and we don't have a
// normal map feature then we need to lerp in a
// default normal else the normals below this layer
// will show thru.
if ( gbNormal &&
!fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
{
Var *viewToTangent = getInViewToTangent( componentList );
meta->addStatement( new GenOp( " @ = lerp( @, tGetMatrix3Row(@, 2), min( @, @.w ) );\r\n",
gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
}
output = meta;
return;
}
Var *detailColor = (Var*)LangElement::find( "detailColor" );
if ( !detailColor )
{
detailColor = new Var;
detailColor->setType( "vec4" );
detailColor->setName( "detailColor" );
meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
}
// Get the detail texture.
Var *detailMap = new Var;
detailMap->setType( "sampler2D" );
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.
@ -557,9 +624,6 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) );
Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" );
meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n",
outColor, outColor, baseColor, detailColor, detailBlend ) );
@ -585,9 +649,7 @@ ShaderFeature::Resources TerrainDetailMapFeatGLSL::getResources( const MaterialF
res.numTexReg += 4;
}
// If this isn't the prepass then we sample
// from the detail texture for diffuse coloring.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
// sample from the detail texture for diffuse coloring.
res.numTex += 1;
// If we have parallax for this layer then we'll also
@ -602,6 +664,11 @@ ShaderFeature::Resources TerrainDetailMapFeatGLSL::getResources( const MaterialF
return res;
}
U32 TerrainDetailMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
{
return fd.features[MFT_DeferredTerrainDetailMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
}
TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL()
: mTorqueDep( "shaders/common/gl/torque.glsl" ),
@ -759,29 +826,6 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
// Add to the blend total.
meta->addStatement( new GenOp( " @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) );
// If this is a prepass then we skip color.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
{
// Check to see if we have a gbuffer normal.
Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
// If we have a gbuffer normal and we don't have a
// normal map feature then we need to lerp in a
// default normal else the normals below this layer
// will show thru.
if ( gbNormal &&
!fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
{
Var *viewToTangent = getInViewToTangent( componentList );
meta->addStatement( new GenOp( " @ = lerp( @, tGetMatrix3Row(@, 2), min( @, @.w ) );\r\n",
gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
}
output = meta;
return;
}
Var *detailColor = (Var*)LangElement::find( "macroColor" );
if ( !detailColor )
{
@ -826,8 +870,12 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) );
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
Var *outColor = (Var*)LangElement::find( "col" );
if(fd.features.hasFeature(MFT_DeferredTerrainMacroMap))
target= ShaderFeature::RenderTarget1;
Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n",
outColor, outColor, outColor, detailColor, detailBlend ) );
@ -850,9 +898,6 @@ ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFe
res.numTex += 1;
}
// If this isn't the prepass then we sample
// from the detail texture for diffuse coloring.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
res.numTex += 1;
// Finally we always send the detail texture
@ -862,6 +907,11 @@ ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFe
return res;
}
U32 TerrainMacroMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
{
return fd.features[MFT_DeferredTerrainMacroMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
}
void TerrainNormalMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
@ -881,9 +931,6 @@ void TerrainNormalMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
// We only need to process normals during the prepass.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
return;
MultiLine *meta = new MultiLine;
@ -1023,7 +1070,12 @@ ShaderFeature::Resources TerrainLightMapFeatGLSL::getResources( const MaterialFe
void TerrainAdditiveFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
Var *color = (Var*) LangElement::find( "col" );
Var *color = NULL;
if (fd.features[MFT_DeferredTerrainDetailMap])
color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
else
color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
if ( !color || !blendTotal )
return;
@ -1035,3 +1087,40 @@ void TerrainAdditiveFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
output = meta;
}
//standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO),
//.b = specular strength, a= spec power.
//here, it's merely a cutout for now, so that lightmapping (target3) doesn't get mangled.
//we'll most likely revisit that later. possibly several ways...
U32 TerrainBlankInfoMapFeatGLSL::getOutputTargets(const MaterialFeatureData &fd) const
{
return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
}
void TerrainBlankInfoMapFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd)
{
// search for material var
Var *material;
OutputTarget targ = RenderTarget1;
if (fd.features[MFT_isDeferred])
{
targ = RenderTarget2;
}
material = (Var*)LangElement::find(getOutputTargetVarName(targ));
MultiLine * meta = new MultiLine;
if (!material)
{
// create color var
material = new Var;
material->setType("vec4");
material->setName(getOutputTargetVarName(targ));
material->setStructName("OUT");
}
meta->addStatement(new GenOp(" @ = float4(0.0,0.0,0.0,0.0001);\r\n", material));
output = meta;
}

View file

@ -67,6 +67,8 @@ public:
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Terrain Base Texture"; }
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
@ -90,6 +92,8 @@ public:
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Terrain Detail Texture"; }
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
@ -113,6 +117,8 @@ public:
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Terrain Macro Texture"; }
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
@ -154,4 +160,15 @@ public:
virtual String getName() { return "Terrain Additive"; }
};
class TerrainBlankInfoMapFeatGLSL : public ShaderFeatureGLSL
{
public:
virtual void processPix(Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd);
virtual U32 getOutputTargets(const MaterialFeatureData &fd) const;
virtual String getName() { return "Blank Matinfo map"; }
};
#endif // _TERRFEATUREGLSL_H_

View file

@ -26,6 +26,7 @@
#include "terrain/terrFeatureTypes.h"
#include "materials/materialFeatureTypes.h"
#include "materials/materialFeatureData.h"
#include "materials/processedMaterial.h"
#include "gfx/gfxDevice.h"
#include "shaderGen/langElement.h"
#include "shaderGen/shaderOp.h"
@ -47,9 +48,12 @@ namespace
FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatHLSL );
FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatHLSL );
FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureHLSL( "Terrain Side Projection" ) );
FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatHLSL );
FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatHLSL );
FEATUREMGR->registerFeature( MFT_DeferredTerrainBaseMap, new TerrainBaseMapFeatHLSL );
FEATUREMGR->registerFeature( MFT_DeferredTerrainMacroMap, new TerrainMacroMapFeatHLSL );
FEATUREMGR->registerFeature( MFT_DeferredTerrainDetailMap, new TerrainDetailMapFeatHLSL );
FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatHLSL );
}
};
MODULE_BEGIN( TerrainFeatHLSL )
@ -250,10 +254,6 @@ void TerrainBaseMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentLis
// grab connector texcoord register
Var *texCoord = getInTexCoord( "texCoord", "float3", true, componentList );
// We do nothing more if this is a prepass.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
return;
// create texture var
Var *diffuseMap = new Var;
diffuseMap->setType( "sampler2D" );
@ -269,8 +269,15 @@ void TerrainBaseMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentLis
baseColor->setName( "baseColor" );
meta->addStatement( new GenOp( " @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", baseColor, baseColor));
meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul ) ) );
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
if (fd.features.hasFeature(MFT_isDeferred))
{
target= ShaderFeature::RenderTarget1;
}
meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul,NULL,target ) ) );
output = meta;
}
@ -278,14 +285,16 @@ ShaderFeature::Resources TerrainBaseMapFeatHLSL::getResources( const MaterialFea
{
Resources res;
res.numTexReg = 1;
// We only sample from the base map during a diffuse pass.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
res.numTex = 1;
return res;
}
U32 TerrainBaseMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
{
return fd.features[MFT_DeferredTerrainBaseMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
}
TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL()
: mTorqueDep( "shaders/common/torque.hlsl" ),
mTerrainDep( "shaders/common/terrain/terrain.hlsl" )
@ -477,7 +486,7 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
// Call the library function to do the rest.
if(fd.features.hasFeature( MFT_IsDXTnm, detailIndex ) )
{
meta->addStatement( new GenOp( " @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n",
meta->addStatement( new GenOp( " @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n",
inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) );
}
else
@ -487,29 +496,6 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
}
}
// If this is a prepass then we skip color.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
{
// Check to see if we have a gbuffer normal.
Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
// If we have a gbuffer normal and we don't have a
// normal map feature then we need to lerp in a
// default normal else the normals below this layer
// will show thru.
if ( gbNormal &&
!fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
{
Var *viewToTangent = getInViewToTangent( componentList );
meta->addStatement( new GenOp( " @ = lerp( @, @[2], min( @, @.w ) );\r\n",
gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
}
output = meta;
return;
}
Var *detailColor = (Var*)LangElement::find( "detailColor" );
if ( !detailColor )
{
@ -543,21 +529,35 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
// We take two color samples and lerp between them for
// side projection layers... else a single sample.
//
//Sampled detail texture that is not expanded
Var *detailTex = new Var;
detailTex->setType("float4");
detailTex->setName("detailTex");
meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailTex ) ) );
if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
{
meta->addStatement( new GenOp( " @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
meta->addStatement( new GenOp(" @ = lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z);\r\n",detailTex,detailMap,inDet,detailMap,inDet,inTex));
meta->addStatement( new GenOp( " @ = ( @ * 2.0 ) - 1.0;\r\n", detailColor, detailTex) );
}
else
{
meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet ) );
meta->addStatement( new GenOp(" @ = tex2D(@,@.xy);\r\n",detailTex,detailMap,inDet));
meta->addStatement( new GenOp( " @ = ( @ * 2.0 ) - 1.0;\r\n",
detailColor, detailTex) );
}
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) );
Var *outColor = (Var*)LangElement::find( "col" );
Var *baseColor = (Var*)LangElement::find( "baseColor" );
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
if(fd.features.hasFeature( MFT_DeferredTerrainDetailMap ))
target= ShaderFeature::RenderTarget1;
Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
meta->addStatement( new GenOp( " @ += @ * @;\r\n",
outColor, detailColor, detailBlend));
@ -584,9 +584,7 @@ ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialF
res.numTexReg += 4;
}
// If this isn't the prepass then we sample
// from the detail texture for diffuse coloring.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
// sample from the detail texture for diffuse coloring.
res.numTex += 1;
// If we have parallax for this layer then we'll also
@ -601,6 +599,11 @@ ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialF
return res;
}
U32 TerrainDetailMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
{
return fd.features[MFT_DeferredTerrainDetailMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
}
TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL()
: mTorqueDep( "shaders/common/torque.hlsl" ),
@ -758,29 +761,6 @@ void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentL
// Add to the blend total.
meta->addStatement( new GenOp( " @ += @;\r\n", blendTotal, detailBlend ) );
// If this is a prepass then we skip color.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
{
// Check to see if we have a gbuffer normal.
Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
// If we have a gbuffer normal and we don't have a
// normal map feature then we need to lerp in a
// default normal else the normals below this layer
// will show thru.
if ( gbNormal &&
!fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
{
Var *viewToTangent = getInViewToTangent( componentList );
meta->addStatement( new GenOp( " @ = lerp( @, @[2], min( @, @.w ) );\r\n",
gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
}
output = meta;
return;
}
Var *detailColor = (Var*)LangElement::find( "macroColor" );
if ( !detailColor )
{
@ -826,8 +806,14 @@ void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentL
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) );
//Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" );
Var *baseColor = (Var*)LangElement::find( "baseColor" );
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
if(fd.features.hasFeature(MFT_DeferredTerrainMacroMap))
target= ShaderFeature::RenderTarget1;
Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
meta->addStatement(new GenOp(" @ += @ * @;\r\n",
outColor, detailColor, detailBlend));
@ -837,8 +823,6 @@ void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentL
output = meta;
}
ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
@ -850,9 +834,6 @@ ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFe
res.numTex += 1;
}
// If this isn't the prepass then we sample
// from the detail texture for diffuse coloring.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
res.numTex += 1;
// Finally we always send the detail texture
@ -862,6 +843,11 @@ ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFe
return res;
}
U32 TerrainMacroMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
{
return fd.features[MFT_DeferredTerrainMacroMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
}
void TerrainNormalMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
@ -881,9 +867,6 @@ void TerrainNormalMapFeatHLSL::processVert( Vector<ShaderComponent*> &component
void TerrainNormalMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
// We only need to process normals during the prepass.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
return;
MultiLine *meta = new MultiLine;
@ -1019,11 +1002,15 @@ ShaderFeature::Resources TerrainLightMapFeatHLSL::getResources( const MaterialFe
return res;
}
void TerrainAdditiveFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
Var *color = (Var*) LangElement::find( "col" );
Var *color = NULL;
if (fd.features[MFT_DeferredTerrainDetailMap])
color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
else
color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
if ( !color || !blendTotal )
return;
@ -1033,5 +1020,43 @@ void TerrainAdditiveFeatHLSL::processPix( Vector<ShaderComponent*> &componentLis
meta->addStatement( new GenOp( " clip( @ - 0.0001 );\r\n", blendTotal ) );
meta->addStatement( new GenOp( " @.a = @;\r\n", color, blendTotal ) );
output = meta;
}
//standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO),
//.b = specular strength, a= spec power.
//here, it's merely a cutout for now, so that lightmapping (target3) doesn't get mangled.
//we'll most likely revisit that later. possibly several ways...
U32 TerrainBlankInfoMapFeatHLSL::getOutputTargets(const MaterialFeatureData &fd) const
{
return fd.features[MFT_DeferredTerrainBaseMap] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
}
void TerrainBlankInfoMapFeatHLSL::processPix(Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd)
{
// search for material var
Var *material;
OutputTarget targ = RenderTarget1;
if (fd.features[MFT_isDeferred])
{
targ = RenderTarget2;
}
material = (Var*)LangElement::find(getOutputTargetVarName(targ));
MultiLine * meta = new MultiLine;
if (!material)
{
// create color var
material = new Var;
material->setType("fragout");
material->setName(getOutputTargetVarName(targ));
material->setStructName("OUT");
}
meta->addStatement(new GenOp(" @ = float4(0.0,0.0,0.0,0.0001);\r\n", material));
output = meta;
}

View file

@ -68,6 +68,8 @@ public:
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Terrain Base Texture"; }
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
@ -91,6 +93,8 @@ public:
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Terrain Detail Texture"; }
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
@ -114,6 +118,8 @@ public:
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Terrain Macro Texture"; }
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
@ -155,4 +161,15 @@ public:
virtual String getName() { return "Terrain Additive"; }
};
class TerrainBlankInfoMapFeatHLSL : public TerrainFeatHLSL
{
public:
virtual void processPix(Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd);
virtual U32 getOutputTargets(const MaterialFeatureData &fd) const;
virtual String getName() { return "Blank Matinfo map"; }
};
#endif // _TERRFEATUREHLSL_H_

View file

@ -37,6 +37,7 @@
#include "gfx/util/screenspace.h"
#include "lighting/advanced/advancedLightBinManager.h"
S32 sgMaxTerrainMaterialsPerPass = 3;
AFTER_MODULE_INIT( MaterialManager )
{
@ -310,12 +311,12 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
if ( GFX->getPixelShaderVersion() < 3.0f )
baseOnly = true;
// NOTE: At maximum we only try to combine 3 materials
// NOTE: At maximum we only try to combine sgMaxTerrainMaterialsPerPass materials
// into a single pass. This is sub-optimal for the simplest
// cases, but the most common case results in much fewer
// shader generation failures and permutations leading to
// faster load time and less hiccups during gameplay.
U32 matCount = getMin( 3, materials->size() );
U32 matCount = getMin( sgMaxTerrainMaterialsPerPass, materials->size() );
Vector<GFXTexHandle> normalMaps;
@ -349,24 +350,27 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
{
FeatureSet features;
features.addFeature( MFT_VertTransform );
features.addFeature( MFT_TerrainBaseMap );
if ( prePassMat )
{
features.addFeature( MFT_EyeSpaceDepthOut );
features.addFeature( MFT_PrePassConditioner );
features.addFeature( MFT_DeferredTerrainBaseMap );
features.addFeature(MFT_isDeferred);
if ( advancedLightmapSupport )
features.addFeature( MFT_RenderTarget1_Zero );
features.addFeature( MFT_RenderTarget3_Zero );
}
else
{
features.addFeature( MFT_TerrainBaseMap );
features.addFeature( MFT_RTLighting );
// The HDR feature is always added... it will compile out
// if HDR is not enabled in the engine.
features.addFeature( MFT_HDROut );
}
features.addFeature(MFT_DeferredTerrainBlankInfoMap);
// Enable lightmaps and fogging if we're in BL.
if ( reflectMat || useBLM )
@ -405,8 +409,16 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
// check for macro detail texture
if ( !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
{
if(prePassMat)
features.addFeature( MFT_DeferredTerrainMacroMap, featureIndex );
else
features.addFeature( MFT_TerrainMacroMap, featureIndex );
}
if(prePassMat)
features.addFeature( MFT_DeferredTerrainDetailMap, featureIndex );
else
features.addFeature( MFT_TerrainDetailMap, featureIndex );
pass->materials.push_back( (*materials)[i] );
@ -536,8 +548,8 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
// MFT_TerrainAdditive feature to lerp the
// output normal with the previous pass.
//
if ( prePassMat )
desc.setColorWrites( true, true, false, false );
//if ( prePassMat )
//desc.setColorWrites( true, true, false, false );
}
// We write to the zbuffer if this is a prepass
@ -656,9 +668,9 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
if ( prePassMat )
desc.addDesc( RenderPrePassMgr::getOpaqueStenciWriteDesc( false ) );
// Flip the cull for reflection materials.
if ( reflectMat )
desc.setCullMode( GFXCullCW );
// Shut off culling for prepass materials (reflection support).
if ( prePassMat )
desc.setCullMode( GFXCullNone );
pass->stateBlock = GFX->createStateBlock( desc );

View file

@ -34,4 +34,8 @@ ImplementFeatureType( MFT_TerrainMacroMap, MFG_Texture, 104.0f, false );
ImplementFeatureType( MFT_TerrainLightMap, MFG_Texture, 105.0f, false );
ImplementFeatureType( MFT_TerrainSideProject, MFG_Texture, 106.0f, false );
ImplementFeatureType( MFT_TerrainAdditive, MFG_PostProcess, 999.0f, false );
//Deferred Shading
ImplementFeatureType( MFT_DeferredTerrainBaseMap, MFG_Texture, 100.1f, false );
ImplementFeatureType( MFT_DeferredTerrainDetailMap, MFG_Texture, 102.1f, false );
ImplementFeatureType( MFT_DeferredTerrainMacroMap, MFG_Texture, 104.1f, false );
ImplementFeatureType( MFT_DeferredTerrainBlankInfoMap, MFG_Texture, 104.1f, false);

View file

@ -35,6 +35,12 @@ DeclareFeatureType( MFT_TerrainParallaxMap );
DeclareFeatureType( MFT_TerrainLightMap );
DeclareFeatureType( MFT_TerrainSideProject );
DeclareFeatureType( MFT_TerrainAdditive );
//Deferred Shading
DeclareFeatureType( MFT_DeferredTerrainBaseMap );
DeclareFeatureType( MFT_DeferredTerrainDetailMap );
DeclareFeatureType( MFT_DeferredTerrainMacroMap );
DeclareFeatureType( MFT_DeferredTerrainBlankInfoMap );
#endif // _TERRFEATURETYPES_H_