Merge branch 'master' into console-func-refactor

Conflicts:
	Engine/source/app/net/net.cpp
	Engine/source/console/astNodes.cpp
	Engine/source/console/compiledEval.cpp
	Engine/source/console/console.h
	Engine/source/console/consoleInternal.h
	Engine/source/console/engineAPI.h
This commit is contained in:
Daniel Buckmaster 2014-10-14 14:40:17 +11:00
commit b507dc9555
6487 changed files with 315149 additions and 609761 deletions

View file

@ -30,22 +30,35 @@
#include "shaderGen/langElement.h"
#include "shaderGen/shaderOp.h"
#include "shaderGen/featureMgr.h"
#include "shaderGen/shaderGen.h"
#include "core/module.h"
namespace
{
void register_glsl_shader_features_for_terrain(GFXAdapterType type)
{
if(type != OpenGL)
return;
FEATUREMGR->registerFeature( MFT_TerrainBaseMap, new TerrainBaseMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainParallaxMap, new NamedFeatureGLSL( "Terrain Parallax Texture" ) );
FEATUREMGR->registerFeature( MFT_TerrainDetailMap, new TerrainDetailMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainNormalMap, new TerrainNormalMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureGLSL( "Terrain Side Projection" ) );
FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatGLSL );
}
};
MODULE_BEGIN( TerrainFeatGLSL )
MODULE_INIT_AFTER( ShaderGenFeatureMgr )
MODULE_INIT_AFTER( ShaderGen )
MODULE_INIT
{
FEATUREMGR->registerFeature( MFT_TerrainBaseMap, new TerrainBaseMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainParallaxMap, new TerrainParallaxMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainDetailMap, new TerrainDetailMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainNormalMap, new TerrainNormalMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureGLSL( "Terrain Side Projection" ) );
FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatGLSL );
{
SHADERGEN->getFeatureInitSignal().notify(&register_glsl_shader_features_for_terrain);
}
MODULE_END;
@ -68,7 +81,7 @@ Var* TerrainFeatGLSL::_getUniformVar( const char *name, const char *type, Consta
Var* TerrainFeatGLSL::_getInDetailCoord( Vector<ShaderComponent*> &componentList )
{
String name( String::ToString( "outDetCoord%d", getProcessIndex() ) );
String name( String::ToString( "detCoord%d", getProcessIndex() ) );
Var *inDet = (Var*)LangElement::find( name );
if ( !inDet )
@ -77,6 +90,7 @@ Var* TerrainFeatGLSL::_getInDetailCoord( Vector<ShaderComponent*> &componentList
inDet = connectComp->getElement( RT_TEXCOORD );
inDet->setName( name );
inDet->setStructName( "IN" );
inDet->setType( "vec4" );
inDet->mapsToSampler = true;
}
@ -84,6 +98,25 @@ Var* TerrainFeatGLSL::_getInDetailCoord( Vector<ShaderComponent*> &componentList
return inDet;
}
Var* TerrainFeatGLSL::_getInMacroCoord( Vector<ShaderComponent*> &componentList )
{
String name( String::ToString( "macroCoord%d", getProcessIndex() ) );
Var *inDet = (Var*)LangElement::find( name );
if ( !inDet )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
inDet = connectComp->getElement( RT_TEXCOORD );
inDet->setName( name );
inDet->setStructName( "IN" );
inDet->setType( "vec4" );
inDet->mapsToSampler = true;
}
return inDet;
}
Var* TerrainFeatGLSL::_getNormalMapTex()
{
String name( String::ToString( "normalMap%d", getProcessIndex() ) );
@ -119,6 +152,24 @@ Var* TerrainFeatGLSL::_getDetailIdStrengthParallax()
return detailInfo;
}
Var* TerrainFeatGLSL::_getMacroIdStrengthParallax()
{
String name( String::ToString( "macroIdStrengthParallax%d", getProcessIndex() ) );
Var *detailInfo = (Var*)LangElement::find( name );
if ( !detailInfo )
{
detailInfo = new Var;
detailInfo->setType( "vec3" );
detailInfo->setName( name );
detailInfo->uniform = true;
detailInfo->constSortPos = cspPotentialPrimitive;
}
return detailInfo;
}
void TerrainBaseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
@ -146,7 +197,7 @@ void TerrainBaseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentLis
// So instead i fixed this by flipping the base and detail
// coord y scale to compensate when rendering.
//
meta->addStatement( new GenOp( " @ = @.xyz * vec3( @, @, -@ );\r\n",
meta->addStatement( new GenOp( " @ = @.xyz * float3( @, @, -@ );\r\n",
new DecOp( inTex ), inPos, oneOverTerrainSize, oneOverTerrainSize, oneOverTerrainSize ) );
}
@ -155,6 +206,7 @@ void TerrainBaseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentLis
// Pass the texture coord to the pixel shader.
Var *outTex = connectComp->getElement( RT_TEXCOORD );
outTex->setName( "outTexCoord" );
outTex->setStructName( "OUT" );
outTex->setType( "vec3" );
outTex->mapsToSampler = true;
meta->addStatement( new GenOp( " @.xy = @.xy;\r\n", outTex, inTex ) );
@ -166,7 +218,7 @@ void TerrainBaseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentLis
{
Var *inNormal = (Var*)LangElement::find( "normal" );
meta->addStatement(
new GenOp( " @.z = pow( abs( dot( normalize( vec3( @.x, @.y, 0.0 ) ), vec3( 0, 1, 0 ) ) ), 10.0 );\r\n",
new GenOp( " @.z = pow( abs( dot( normalize( float3( @.x, @.y, 0 ) ), float3( 0, 1, 0 ) ) ), 10.0 );\r\n",
outTex, inNormal, inNormal ) );
}
else
@ -182,7 +234,7 @@ void TerrainBaseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentLis
Var *inTangentZ = getVertTexCoord( "tcTangentZ" );
Var *inTanget = new Var( "T", "vec3" );
Var *squareSize = _getUniformVar( "squareSize", "float", cspPass );
meta->addStatement( new GenOp( " @ = normalize( vec3( @, 0.0, @ ) );\r\n",
meta->addStatement( new GenOp( " @ = normalize( float3( @, 0, @ ) );\r\n",
new DecOp( inTanget ), squareSize, inTangentZ ) );
}
@ -190,7 +242,7 @@ void TerrainBaseMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
const MaterialFeatureData &fd )
{
// grab connector texcoord register
Var *texCoord = getInTexCoord( "outTexCoord", "vec3", true, componentList );
Var *texCoord = getInTexCoord( "texCoord", "vec3", true, componentList );
// We do nothing more if this is a prepass.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
@ -209,7 +261,7 @@ void TerrainBaseMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
Var *baseColor = new Var;
baseColor->setType( "vec4" );
baseColor->setName( "baseColor" );
meta->addStatement( new GenOp( " @ = texture2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
meta->addStatement( new GenOp( " @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul ) ) );
output = meta;
@ -228,8 +280,11 @@ ShaderFeature::Resources TerrainBaseMapFeatGLSL::getResources( const MaterialFea
}
TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL()
: mTerrainDep( "shaders/common/terrain/terrain.glsl" )
: mTorqueDep( "shaders/common/gl/torque.glsl" ),
mTerrainDep( "shaders/common/terrain/terrain.glsl" )
{
addDependency( &mTorqueDep );
addDependency( &mTerrainDep );
}
@ -238,13 +293,6 @@ void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
{
const U32 detailIndex = getProcessIndex();
// If this is a prepass and we don't have a
// matching normal map... we have nothing to do.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) &&
!fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
return;
// Grab incoming texture coords... the base map feature
// made sure this was created.
Var *inTex = (Var*)LangElement::find( "texCoord" );
@ -260,6 +308,26 @@ void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
MultiLine *meta = new MultiLine;
// If we have parallax mapping then make sure we've sent
// the negative view vector to the pixel shader.
if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
!LangElement::find( "outNegViewTS" ) )
{
// Get the object to tangent transform which
// will consume 3 output registers.
Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta, fd );
// Now use a single output register to send the negative
// view vector in tangent space to the pixel shader.
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD );
outNegViewTS->setName( "outNegViewTS" );
outNegViewTS->setStructName( "OUT" );
outNegViewTS->setType( "vec3" );
meta->addStatement( new GenOp( " @ = tMul( @, float3( @ - @.xyz ) );\r\n",
outNegViewTS, objToTangentSpace, eyePos, inPos ) );
}
// Get the distance from the eye to this vertex.
Var *dist = (Var*)LangElement::find( "dist" );
if ( !dist )
@ -275,7 +343,8 @@ void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
// grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outTex = connectComp->getElement( RT_TEXCOORD );
outTex->setName( String::ToString( "outDetCoord%d", detailIndex ) );
outTex->setName( String::ToString( "detCoord%d", detailIndex ) );
outTex->setStructName( "OUT" );
outTex->setType( "vec4" );
outTex->mapsToSampler = true;
@ -293,7 +362,7 @@ void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
// its scale is flipped to correct for the non negative y
// in texCoord.
//
// See TerrainBaseMapFeatHLSL::processVert().
// See TerrainBaseMapFeatGLSL::processVert().
//
meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) );
@ -308,17 +377,30 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
const MaterialFeatureData &fd )
{
const U32 detailIndex = getProcessIndex();
Var *inTex = getVertTexCoord( "texCoord" );
// If this is a prepass and we don't have a
// matching normal map... we have nothing to do.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) &&
!fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
return;
Var *inTex = getVertTexCoord( "outTexCoord" );
MultiLine *meta = new MultiLine;
// We need the negative tangent space view vector
// as in parallax mapping we step towards the camera.
Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
if ( !negViewTS &&
fd.features.hasFeature( MFT_TerrainParallaxMap ) )
{
Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
if ( !inNegViewTS )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
inNegViewTS = connectComp->getElement( RT_TEXCOORD );
inNegViewTS->setName( "outNegViewTS" );
inNegViewTS->setStructName( "IN" );
inNegViewTS->setType( "vec3" );
}
negViewTS = new Var( "negViewTS", "vec3" );
meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
}
// Get the layer samples.
Var *layerSample = (Var*)LangElement::find( "layerSample" );
if ( !layerSample )
@ -336,7 +418,7 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
layerTex->constNum = Var::getTexUnitNum();
// Read the layer texture to get the samples.
meta->addStatement( new GenOp( " @ = round( texture2D( @, @.xy ) * 255.0f );\r\n",
meta->addStatement( new GenOp( " @ = round( tex2D( @, @.xy ) * 255.0f );\r\n",
new DecOp( layerSample ), layerTex, inTex ) );
}
@ -372,17 +454,43 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
blendTotal = new Var;
blendTotal->setName( "blendTotal" );
blendTotal->setType( "float" );
meta->addStatement( new GenOp( " @ = 0.0;\r\n", new DecOp( blendTotal ) ) );
meta->addStatement( new GenOp( " @ = 0;\r\n", new DecOp( blendTotal ) ) );
}
// Add to the blend total.
meta->addStatement( new GenOp( " @ += @;\r\n", blendTotal, detailBlend ) );
//meta->addStatement( new GenOp( " @ += @ * @.y * @.w;\r\n",
//blendTotal, detailBlend, detailInfo, inDet ) );
meta->addStatement( new GenOp( " @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) );
// Nothing more to do for a detail texture in prepass.
// If we had a parallax feature... then factor in the parallax
// amount so that it fades out with the layer blending.
if ( fd.features.hasFeature( MFT_TerrainParallaxMap, detailIndex ) )
{
// Get the rest of our inputs.
Var *normalMap = _getNormalMapTex();
// Call the library function to do the rest.
meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n",
inDet, normalMap, inDet, negViewTS, detailInfo, 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;
}
@ -407,6 +515,7 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
// 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 ) );
@ -421,12 +530,12 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
//
if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
{
meta->addStatement( new GenOp( " @ = ( mix( texture2D( @, @.yz ), texture2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
meta->addStatement( new GenOp( " @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
}
else
{
meta->addStatement( new GenOp( " @ = ( texture2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet ) );
}
@ -436,7 +545,7 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" );
meta->addStatement( new GenOp( " @ = mix( @, @ + @, @ );\r\n",
meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n",
outColor, outColor, baseColor, detailColor, detailBlend ) );
meta->addStatement( new GenOp( " }\r\n" ) );
@ -448,28 +557,293 @@ ShaderFeature::Resources TerrainDetailMapFeatGLSL::getResources( const MaterialF
{
Resources res;
if ( getProcessIndex() == 0 )
{
// If this is the first detail pass then we
// samples from the layer tex.
res.numTex += 1;
// If this material also does parallax then it
// will generate the negative view vector and the
// worldToTanget transform.
if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) )
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 ) )
res.numTex += 1;
// If we have parallax for this layer then we'll also
// be sampling the normal map for the parallax heightmap.
if ( fd.features.hasFeature( MFT_TerrainParallaxMap, getProcessIndex() ) )
res.numTex += 1;
// Finally we always send the detail texture
// coord to the pixel shader.
res.numTexReg += 1;
return res;
}
TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL()
: mTorqueDep( "shaders/common/gl/torque.glsl" ),
mTerrainDep( "shaders/common/terrain/terrain.glsl" )
{
addDependency( &mTorqueDep );
addDependency( &mTerrainDep );
}
void TerrainMacroMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
const U32 detailIndex = getProcessIndex();
// Grab incoming texture coords... the base map feature
// made sure this was created.
Var *inTex = (Var*)LangElement::find( "texCoord" );
AssertFatal( inTex, "The texture coord is missing!" );
// Grab the input position.
Var *inPos = (Var*)LangElement::find( "inPosition" );
if ( !inPos )
inPos = (Var*)LangElement::find( "position" );
// Get the object space eye position.
Var *eyePos = _getUniformVar( "eyePos", "vec3", cspPotentialPrimitive );
MultiLine *meta = new MultiLine;
// Get the distance from the eye to this vertex.
Var *dist = (Var*)LangElement::find( "macroDist" );
if ( !dist )
{
dist = new Var;
dist->setType( "float" );
dist->setName( "macroDist" );
meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n",
new DecOp( dist ), inPos, eyePos ) );
}
// grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outTex = connectComp->getElement( RT_TEXCOORD );
outTex->setName( String::ToString( "macroCoord%d", detailIndex ) );
outTex->setStructName( "OUT" );
outTex->setType( "vec4" );
outTex->mapsToSampler = true;
// Get the detail scale and fade info.
Var *detScaleAndFade = new Var;
detScaleAndFade->setType( "vec4" );
detScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) );
detScaleAndFade->uniform = true;
detScaleAndFade->constSortPos = cspPotentialPrimitive;
// Setup the detail coord.
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 ) );
output = meta;
}
void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
const U32 detailIndex = getProcessIndex();
Var *inTex = getVertTexCoord( "texCoord" );
MultiLine *meta = new MultiLine;
// We need the negative tangent space view vector
// as in parallax mapping we step towards the camera.
Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
if ( !negViewTS &&
fd.features.hasFeature( MFT_TerrainParallaxMap ) )
{
Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
if ( !inNegViewTS )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
inNegViewTS = connectComp->getElement( RT_TEXCOORD );
inNegViewTS->setName( "outNegViewTS" );
inNegViewTS->setStructName( "IN" );
inNegViewTS->setType( "vec3" );
}
negViewTS = new Var( "negViewTS", "vec3" );
meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
}
// Get the layer samples.
Var *layerSample = (Var*)LangElement::find( "layerSample" );
if ( !layerSample )
{
layerSample = new Var;
layerSample->setType( "vec4" );
layerSample->setName( "layerSample" );
// Get the layer texture var
Var *layerTex = new Var;
layerTex->setType( "sampler2D" );
layerTex->setName( "macrolayerTex" );
layerTex->uniform = true;
layerTex->sampler = true;
layerTex->constNum = Var::getTexUnitNum();
// Read the layer texture to get the samples.
meta->addStatement( new GenOp( " @ = round( tex2D( @, @.xy ) * 255.0f );\r\n",
new DecOp( layerSample ), layerTex, inTex ) );
}
Var *layerSize = (Var*)LangElement::find( "layerSize" );
if ( !layerSize )
{
layerSize = new Var;
layerSize->setType( "float" );
layerSize->setName( "layerSize" );
layerSize->uniform = true;
layerSize->constSortPos = cspPass;
}
// Grab the incoming detail coord.
Var *inDet = _getInMacroCoord( componentList );
// Get the detail id.
Var *detailInfo = _getMacroIdStrengthParallax();
// Create the detail blend var.
Var *detailBlend = new Var;
detailBlend->setType( "float" );
detailBlend->setName( String::ToString( "macroBlend%d", detailIndex ) );
// Calculate the blend for this detail texture.
meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
// Get a var and accumulate the blend amount.
Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
if ( !blendTotal )
{
blendTotal = new Var;
//blendTotal->setName( "blendTotal" );
blendTotal->setName( "blendTotal" );
blendTotal->setType( "float" );
meta->addStatement( new GenOp( " @ = 0;\r\n", new DecOp( blendTotal ) ) );
}
// 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 ) )
{
// If this is a prepass and we don't have a
// matching normal map... we use no resources.
if ( !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() ) )
return res;
// Check to see if we have a gbuffer normal.
Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
// If this is the first matching normal map then
// it also samples from the layer tex.
if ( !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() - 1 ) )
res.numTex += 1;
// 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 )
{
detailColor = new Var;
detailColor->setType( "vec4" );
detailColor->setName( "macroColor" );
meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
}
// Get the detail texture.
Var *detailMap = new Var;
detailMap->setType( "sampler2D" );
detailMap->setName( String::ToString( "macroMap%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.
//
// 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 ) );
}
else
{
// If this is the first detail pass then it
// also samples from the layer tex.
if ( !fd.features.hasFeature( MFT_TerrainDetailMap, getProcessIndex() - 1 ) )
res.numTex += 1;
res.numTex += 1;
meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet ) );
}
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, outColor, detailColor, detailBlend ) );
//outColor, outColor, baseColor, detailColor, detailBlend ) );
meta->addStatement( new GenOp( " }\r\n" ) );
output = meta;
}
ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
if ( getProcessIndex() == 0 )
{
// If this is the first detail pass then we
// samples from the layer tex.
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
// coord to the pixel shader.
res.numTexReg += 1;
return res;
@ -510,7 +884,7 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
gbNormal = new Var;
gbNormal->setName( "gbNormal" );
gbNormal->setType( "vec3" );
meta->addStatement( new GenOp( " @ = @[2];\r\n", new DecOp( gbNormal ), viewToTangent ) );
meta->addStatement( new GenOp( " @ = tGetMatrix3Row(@, 2);\r\n", new DecOp( gbNormal ), viewToTangent ) );
}
const U32 normalIndex = getProcessIndex();
@ -520,7 +894,6 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
// 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 ) );
@ -531,7 +904,7 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
/// Get the texture coord.
Var *inDet = _getInDetailCoord( componentList );
Var *inTex = getVertTexCoord( "outTexCoord" );
Var *inTex = getVertTexCoord( "texCoord" );
// Sample the normal map.
//
@ -540,11 +913,11 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
LangElement *texOp;
if ( fd.features.hasFeature( MFT_TerrainSideProject, normalIndex ) )
{
texOp = new GenOp( "mix( texture2D( @, @.yz ), texture2D( @, @.xz ), @.z )",
texOp = new GenOp( "lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
normalMap, inDet, normalMap, inDet, inTex );
}
else
texOp = new GenOp( "texture2D(@, @.xy)", normalMap, inDet );
texOp = new GenOp( "tex2D(@, @.xy)", normalMap, inDet );
// create bump normal
Var *bumpNorm = new Var;
@ -556,7 +929,7 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
// Normalize is done later...
// Note: The reverse mul order is intentional. Affine matrix.
meta->addStatement( new GenOp( " @ = mix( @, @.xyz * @, min( @, @.w ) );\r\n",
meta->addStatement( new GenOp( " @ = lerp( @, tMul( @.xyz, @ ), min( @, @.w ) );\r\n",
gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet ) );
// End the conditional block.
@ -578,9 +951,11 @@ ShaderFeature::Resources TerrainNormalMapFeatGLSL::getResources( const MaterialF
// We only need to process normals during the prepass.
if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
{
// If this is the first normal map then it
// will generate the worldToTanget transform.
if ( !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() - 1 ) )
// If this is the first normal map and there
// are no parallax features then we will
// generate the worldToTanget transform.
if ( !fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
( getProcessIndex() == 0 || !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() - 1 ) ) )
res.numTexReg = 3;
res.numTex = 1;
@ -589,100 +964,11 @@ ShaderFeature::Resources TerrainNormalMapFeatGLSL::getResources( const MaterialF
return res;
}
TerrainParallaxMapFeatGLSL::TerrainParallaxMapFeatGLSL()
: mIncludeDep( "shaders/common/gl/torque.glsl" )
{
addDependency( &mIncludeDep );
}
void TerrainParallaxMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
if ( LangElement::find( "outNegViewTS" ) )
return;
MultiLine *meta = new MultiLine;
// Grab the input position.
Var *inPos = (Var*)LangElement::find( "inPosition" );
if ( !inPos )
inPos = (Var*)LangElement::find( "position" );
// Get the object space eye position and the
// object to tangent transform.
Var *eyePos = _getUniformVar( "eyePos", "vec3" , cspPotentialPrimitive );
Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta,fd );
// Now send the negative view vector in tangent space to the pixel shader.
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD );
outNegViewTS->setName( "outNegViewTS" );
outNegViewTS->setType( "vec3" );
meta->addStatement( new GenOp( " @ = @ * vec3( @ - @.xyz );\r\n",
outNegViewTS, objToTangentSpace, eyePos, inPos ) );
output = meta;
}
void TerrainParallaxMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
// We need the negative tangent space view vector
// as in parallax mapping we step towards the camera.
Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
if ( !negViewTS )
{
Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
if ( !inNegViewTS )
{
inNegViewTS = connectComp->getElement( RT_TEXCOORD );
inNegViewTS->setName( "outNegViewTS" );
inNegViewTS->setType( "vec3" );
}
negViewTS = new Var( "negViewTS", "vec3" );
meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
}
// Get the rest of our inputs.
Var *detailInfo = _getDetailIdStrengthParallax();
Var *normalMap = _getNormalMapTex();
Var *texCoord = _getInDetailCoord( componentList );
// Call the library function to do the rest.
meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @.z );\r\n",
texCoord, normalMap, texCoord, negViewTS, detailInfo ) );
output = meta;
}
ShaderFeature::Resources TerrainParallaxMapFeatGLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
// If this is the first parallax feature then
// it will generate the tangetEye vector and
// the worldToTanget transform.
if ( getProcessIndex() == 0 || !fd.features.hasFeature( MFT_TerrainParallaxMap, getProcessIndex() - 1 ) )
res.numTexReg = 4;
// If this isn't the prepass then we will
// be adding a normal map.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
res.numTex = 1;
return res;
}
void TerrainLightMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
// grab connector texcoord register
Var *inTex = (Var*)LangElement::find( "outTexCoord" );
Var *inTex = (Var*)LangElement::find( "texCoord" );
if ( !inTex )
return;
@ -694,13 +980,23 @@ void TerrainLightMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
lightMap->sampler = true;
lightMap->constNum = Var::getTexUnitNum();
// Create a 'lightMask' value which is read by
// RTLighting to mask out the directional lighting.
Var *lightMask = new Var;
lightMask->setType( "vec3" );
lightMask->setName( "lightMask" );
MultiLine *meta = new MultiLine;
output = new GenOp( " @ = texture2D( @, @.xy ).rgb;\r\n", new DecOp( lightMask ), lightMap, inTex );
// Find or create the lightMask value which is read by
// RTLighting to mask out the lights.
//
// The first light is always the sunlight so we apply
// the shadow mask to only the first channel.
//
Var *lightMask = (Var*)LangElement::find( "lightMask" );
if ( !lightMask )
{
lightMask = new Var( "lightMask", "vec4" );
meta->addStatement( new GenOp( " @ = vec4(1);\r\n", new DecOp( lightMask ) ) );
}
meta->addStatement( new GenOp( " @[0] = tex2D( @, @.xy ).r;\r\n", lightMask, lightMap, inTex ) );
output = meta;
}
ShaderFeature::Resources TerrainLightMapFeatGLSL::getResources( const MaterialFeatureData &fd )
@ -721,7 +1017,7 @@ void TerrainAdditiveFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
MultiLine *meta = new MultiLine;
meta->addStatement( new GenOp( " if ( @ - 0.0001 < 0.0 ) discard;\r\n", blendTotal ) );
meta->addStatement( new GenOp( " clip( @ - 0.0001 );\r\n", blendTotal ) );
meta->addStatement( new GenOp( " @.a = @;\r\n", color, blendTotal ) );
output = meta;

View file

@ -30,6 +30,7 @@
#include "shaderGen/langElement.h"
#endif
/// A shared base class for terrain features which
/// includes some helper functions.
class TerrainFeatGLSL : public ShaderFeatureGLSL
@ -38,14 +39,18 @@ protected:
Var* _getInDetailCoord(Vector<ShaderComponent*> &componentList );
Var* _getInMacroCoord(Vector<ShaderComponent*> &componentList );
Var* _getNormalMapTex();
static Var* _getUniformVar( const char *name, const char *type, ConstantSortPosition csp );
Var* _getDetailIdStrengthParallax();
Var* _getMacroIdStrengthParallax();
};
class TerrainBaseMapFeatGLSL : public TerrainFeatGLSL
{
public:
@ -61,10 +66,12 @@ public:
virtual String getName() { return "Terrain Base Texture"; }
};
class TerrainDetailMapFeatGLSL : public TerrainFeatGLSL
{
protected:
ShaderIncludeDependency mTorqueDep;
ShaderIncludeDependency mTerrainDep;
public:
@ -83,10 +90,17 @@ public:
};
class TerrainNormalMapFeatGLSL : public TerrainFeatGLSL
class TerrainMacroMapFeatGLSL : public TerrainFeatGLSL
{
protected:
ShaderIncludeDependency mTorqueDep;
ShaderIncludeDependency mTerrainDep;
public:
TerrainMacroMapFeatGLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
@ -95,19 +109,14 @@ public:
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Terrain Normal Texture"; }
virtual String getName() { return "Terrain Macro Texture"; }
};
class TerrainParallaxMapFeatGLSL : public TerrainFeatGLSL
class TerrainNormalMapFeatGLSL : public TerrainFeatGLSL
{
protected:
ShaderIncludeDependency mIncludeDep;
public:
TerrainParallaxMapFeatGLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
@ -116,7 +125,7 @@ public:
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Terrain Parallax Texture"; }
virtual String getName() { return "Terrain Normal Texture"; }
};
class TerrainLightMapFeatGLSL : public TerrainFeatGLSL

View file

@ -43,6 +43,7 @@ MODULE_BEGIN( TerrainFeatHLSL )
FEATUREMGR->registerFeature( MFT_TerrainParallaxMap, new NamedFeatureHLSL( "Terrain Parallax Texture" ) );
FEATUREMGR->registerFeature( MFT_TerrainDetailMap, new TerrainDetailMapFeatHLSL );
FEATUREMGR->registerFeature( MFT_TerrainNormalMap, new TerrainNormalMapFeatHLSL );
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 );
@ -85,6 +86,25 @@ Var* TerrainFeatHLSL::_getInDetailCoord( Vector<ShaderComponent*> &componentList
return inDet;
}
Var* TerrainFeatHLSL::_getInMacroCoord( Vector<ShaderComponent*> &componentList )
{
String name( String::ToString( "macroCoord%d", getProcessIndex() ) );
Var *inDet = (Var*)LangElement::find( name );
if ( !inDet )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
inDet = connectComp->getElement( RT_TEXCOORD );
inDet->setName( name );
inDet->setStructName( "IN" );
inDet->setType( "float4" );
inDet->mapsToSampler = true;
}
return inDet;
}
Var* TerrainFeatHLSL::_getNormalMapTex()
{
String name( String::ToString( "normalMap%d", getProcessIndex() ) );
@ -120,6 +140,24 @@ Var* TerrainFeatHLSL::_getDetailIdStrengthParallax()
return detailInfo;
}
Var* TerrainFeatHLSL::_getMacroIdStrengthParallax()
{
String name( String::ToString( "macroIdStrengthParallax%d", getProcessIndex() ) );
Var *detailInfo = (Var*)LangElement::find( name );
if ( !detailInfo )
{
detailInfo = new Var;
detailInfo->setType( "float3" );
detailInfo->setName( name );
detailInfo->uniform = true;
detailInfo->constSortPos = cspPotentialPrimitive;
}
return detailInfo;
}
void TerrainBaseMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
@ -537,6 +575,268 @@ ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialF
return res;
}
TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL()
: mTorqueDep( "shaders/common/torque.hlsl" ),
mTerrainDep( "shaders/common/terrain/terrain.hlsl" )
{
addDependency( &mTorqueDep );
addDependency( &mTerrainDep );
}
void TerrainMacroMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
const U32 detailIndex = getProcessIndex();
// Grab incoming texture coords... the base map feature
// made sure this was created.
Var *inTex = (Var*)LangElement::find( "texCoord" );
AssertFatal( inTex, "The texture coord is missing!" );
// Grab the input position.
Var *inPos = (Var*)LangElement::find( "inPosition" );
if ( !inPos )
inPos = (Var*)LangElement::find( "position" );
// Get the object space eye position.
Var *eyePos = _getUniformVar( "eyePos", "float3", cspPotentialPrimitive );
MultiLine *meta = new MultiLine;
// Get the distance from the eye to this vertex.
Var *dist = (Var*)LangElement::find( "macroDist" );
if ( !dist )
{
dist = new Var;
dist->setType( "float" );
dist->setName( "macroDist" );
meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n",
new DecOp( dist ), inPos, eyePos ) );
}
// grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outTex = connectComp->getElement( RT_TEXCOORD );
outTex->setName( String::ToString( "macroCoord%d", detailIndex ) );
outTex->setStructName( "OUT" );
outTex->setType( "float4" );
outTex->mapsToSampler = true;
// Get the detail scale and fade info.
Var *detScaleAndFade = new Var;
detScaleAndFade->setType( "float4" );
detScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) );
detScaleAndFade->uniform = true;
detScaleAndFade->constSortPos = cspPotentialPrimitive;
// Setup the detail coord.
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 ) );
output = meta;
}
void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
const U32 detailIndex = getProcessIndex();
Var *inTex = getVertTexCoord( "texCoord" );
MultiLine *meta = new MultiLine;
// We need the negative tangent space view vector
// as in parallax mapping we step towards the camera.
Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
if ( !negViewTS &&
fd.features.hasFeature( MFT_TerrainParallaxMap ) )
{
Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
if ( !inNegViewTS )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
inNegViewTS = connectComp->getElement( RT_TEXCOORD );
inNegViewTS->setName( "outNegViewTS" );
inNegViewTS->setStructName( "IN" );
inNegViewTS->setType( "float3" );
}
negViewTS = new Var( "negViewTS", "float3" );
meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
}
// Get the layer samples.
Var *layerSample = (Var*)LangElement::find( "layerSample" );
if ( !layerSample )
{
layerSample = new Var;
layerSample->setType( "float4" );
layerSample->setName( "layerSample" );
// Get the layer texture var
Var *layerTex = new Var;
layerTex->setType( "sampler2D" );
layerTex->setName( "macrolayerTex" );
layerTex->uniform = true;
layerTex->sampler = true;
layerTex->constNum = Var::getTexUnitNum();
// Read the layer texture to get the samples.
meta->addStatement( new GenOp( " @ = round( tex2D( @, @.xy ) * 255.0f );\r\n",
new DecOp( layerSample ), layerTex, inTex ) );
}
Var *layerSize = (Var*)LangElement::find( "layerSize" );
if ( !layerSize )
{
layerSize = new Var;
layerSize->setType( "float" );
layerSize->setName( "layerSize" );
layerSize->uniform = true;
layerSize->constSortPos = cspPass;
}
// Grab the incoming detail coord.
Var *inDet = _getInMacroCoord( componentList );
// Get the detail id.
Var *detailInfo = _getMacroIdStrengthParallax();
// Create the detail blend var.
Var *detailBlend = new Var;
detailBlend->setType( "float" );
detailBlend->setName( String::ToString( "macroBlend%d", detailIndex ) );
// Calculate the blend for this detail texture.
meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
// Get a var and accumulate the blend amount.
Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
if ( !blendTotal )
{
blendTotal = new Var;
//blendTotal->setName( "blendTotal" );
blendTotal->setName( "blendTotal" );
blendTotal->setType( "float" );
meta->addStatement( new GenOp( " @ = 0;\r\n", new DecOp( blendTotal ) ) );
}
// 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( @, @[2], min( @, @.w ) );\r\n",
gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
}
output = meta;
return;
}
Var *detailColor = (Var*)LangElement::find( "macroColor" );
if ( !detailColor )
{
detailColor = new Var;
detailColor->setType( "float4" );
detailColor->setName( "macroColor" );
meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
}
// Get the detail texture.
Var *detailMap = new Var;
detailMap->setType( "sampler2D" );
detailMap->setName( String::ToString( "macroMap%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.
//
// 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 ) );
}
else
{
meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet ) );
}
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, outColor, detailColor, detailBlend ) );
//outColor, outColor, baseColor, detailColor, detailBlend ) );
meta->addStatement( new GenOp( " }\r\n" ) );
output = meta;
}
ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
if ( getProcessIndex() == 0 )
{
// If this is the first detail pass then we
// samples from the layer tex.
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
// coord to the pixel shader.
res.numTexReg += 1;
return res;
}
void TerrainNormalMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{

View file

@ -39,11 +39,14 @@ protected:
Var* _getInDetailCoord(Vector<ShaderComponent*> &componentList );
Var* _getInMacroCoord(Vector<ShaderComponent*> &componentList );
Var* _getNormalMapTex();
static Var* _getUniformVar( const char *name, const char *type, ConstantSortPosition csp );
Var* _getDetailIdStrengthParallax();
Var* _getMacroIdStrengthParallax();
};
@ -87,6 +90,29 @@ public:
};
class TerrainMacroMapFeatHLSL : public TerrainFeatHLSL
{
protected:
ShaderIncludeDependency mTorqueDep;
ShaderIncludeDependency mTerrainDep;
public:
TerrainMacroMapFeatHLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Terrain Macro Texture"; }
};
class TerrainNormalMapFeatHLSL : public TerrainFeatHLSL
{
public:

View file

@ -849,7 +849,7 @@ void TerrCell::_updateMaterials()
if ( index == U8_MAX || index > 63 )
continue;
mMaterials |= (U64)(1<<index);
mMaterials |= (U64)((U64)1<<index);
}
}

View file

@ -101,6 +101,19 @@ void TerrainCellMaterial::_updateDefaultAnisotropy()
desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
}
if ( matInfo->macroTexConst->isValid() )
{
const S32 sampler = matInfo->macroTexConst->getSamplerRegister();
if ( maxAnisotropy > 1 )
{
desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
}
else
desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
}
if ( matInfo->normalTexConst->isValid() )
{
const S32 sampler = matInfo->normalTexConst->getSamplerRegister();
@ -369,6 +382,10 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
S32 featureIndex = pass->materials.size();
// check for macro detail texture
if ( !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
features.addFeature( MFT_TerrainMacroMap, featureIndex );
features.addFeature( MFT_TerrainDetailMap, featureIndex );
pass->materials.push_back( (*materials)[i] );
@ -567,6 +584,31 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
&GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - DetailMap" );
}
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() )
{
const S32 sampler = matInfo->macroTexConst->getSamplerRegister();
desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;
if ( maxAnisotropy > 1 )
{
desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
}
else
desc.samplers[sampler].minFilter = GFXTextureFilterLinear;
matInfo->macroTex.set( matInfo->mat->getMacroMap(),
&GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - MacroMap" );
}
//end macro texture
matInfo->normalTexConst = pass->shader->getShaderConstHandle( avar( "$normalMap%d", i ) );
if ( matInfo->normalTexConst->isValid() )
{
@ -657,6 +699,31 @@ void TerrainCellMaterial::_updateMaterialConsts( Pass *pass )
pass->consts->setSafe( matInfo->detailInfoVConst, detailScaleAndFade );
pass->consts->setSafe( matInfo->detailInfoPConst, detailIdStrengthParallax );
// macro texture info
F32 macroSize = matInfo->mat->getMacroSize();
F32 macroScale = 1.0f;
if ( !mIsZero( macroSize ) )
macroScale = mTerrain->getWorldBlockSize() / macroSize;
// Scale the distance by the global scalar.
const F32 macroDistance = mTerrain->smDetailScale * matInfo->mat->getMacroDistance();
Point4F macroScaleAndFade( macroScale,
-macroScale,
macroDistance,
0 );
if ( !mIsZero( macroDistance ) )
macroScaleAndFade.w = 1.0f / macroDistance;
Point3F macroIdStrengthParallax( matInfo->layerId,
matInfo->mat->getMacroStrength(),
0 );
pass->consts->setSafe( matInfo->macroInfoVConst, macroScaleAndFade );
pass->consts->setSafe( matInfo->macroInfoPConst, macroIdStrengthParallax );
}
}
@ -706,6 +773,8 @@ bool TerrainCellMaterial::setupPass( const SceneRenderState *state,
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 );
}

View file

@ -71,11 +71,17 @@ protected:
GFXShaderConstHandle *detailTexConst;
GFXTexHandle detailTex;
GFXShaderConstHandle *macroTexConst;
GFXTexHandle macroTex;
GFXShaderConstHandle *normalTexConst;
GFXTexHandle normalTex;
GFXShaderConstHandle *detailInfoVConst;
GFXShaderConstHandle *detailInfoPConst;
GFXShaderConstHandle *macroInfoVConst;
GFXShaderConstHandle *macroInfoPConst;
};
class Pass

View file

@ -422,7 +422,7 @@ void TerrainBlock::buildConvex(const Box3F& box,Convex* convex)
// Build points
Point3F* pos = cp->point;
for (int i = 0; i < 4 ; i++,pos++) {
for (S32 i = 0; i < 4 ; i++,pos++) {
S32 dx = i >> 1;
S32 dy = dx ^ (i & 1);
pos->x = (F32)((x + dx) * mSquareSize);
@ -480,7 +480,7 @@ static void clrbuf(U32* p, U32 s)
*p++ = U32_MAX;
}
bool TerrainBlock::buildPolyList(PolyListContext, AbstractPolyList* polyList, const Box3F &box, const SphereF&)
bool TerrainBlock::buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF&)
{
PROFILE_SCOPE( TerrainBlock_buildPolyList );
@ -530,12 +530,25 @@ bool TerrainBlock::buildPolyList(PolyListContext, AbstractPolyList* polyList, co
swap(vb[0],vb[1]);
clrbuf(vb[1],xExt + 1);
F32 wy1 = y * mSquareSize, wy2 = (y + 1) * mSquareSize;
if(context == PLC_Navigation &&
((wy1 > osBox.maxExtents.y && wy2 > osBox.maxExtents.y) ||
(wy1 < osBox.minExtents.y && wy2 < osBox.minExtents.y)))
continue;
//
for (S32 x = xStart; x < xEnd; x++)
{
S32 xi = x & BlockMask;
const TerrainSquare *sq = mFile->findSquare( 0, xi, yi );
F32 wx1 = x * mSquareSize, wx2 = (x + 1) * mSquareSize;
if(context == PLC_Navigation &&
((wx1 > osBox.maxExtents.x && wx2 > osBox.maxExtents.x) ||
(wx1 < osBox.minExtents.x && wx2 < osBox.minExtents.x)))
continue;
if ( x != xi || y != yi )
continue;
@ -549,7 +562,7 @@ bool TerrainBlock::buildPolyList(PolyListContext, AbstractPolyList* polyList, co
// Add the missing points
U32 vi[5];
for (int i = 0; i < 4 ; i++)
for (S32 i = 0; i < 4 ; i++)
{
S32 dx = i >> 1;
S32 dy = dx ^ (i & 1);
@ -656,10 +669,10 @@ bool TerrainBlock::castRayI(const Point3F &start, const Point3F &end, RayInfo *i
Point3F pStart(start.x * invBlockWorldSize, start.y * invBlockWorldSize, start.z);
Point3F pEnd(end.x * invBlockWorldSize, end.y * invBlockWorldSize, end.z);
int blockX = (S32)mFloor(pStart.x);
int blockY = (S32)mFloor(pStart.y);
S32 blockX = (S32)mFloor(pStart.x);
S32 blockY = (S32)mFloor(pStart.y);
int dx, dy;
S32 dx, dy;
F32 invDeltaX;
if(pEnd.x == pStart.x)
@ -891,7 +904,7 @@ bool TerrainBlock::castRayBlock( const Point3F &pStart,
}
continue;
}
int subSqWidth = 1 << (level - 1);
S32 subSqWidth = 1 << (level - 1);
F32 xIntercept = (blockPos.x + subSqWidth) * invBlockSize;
F32 xInt = calcInterceptX(pStart.x, invDeltaX, xIntercept);
F32 yIntercept = (blockPos.y + subSqWidth) * invBlockSize;

View file

@ -864,8 +864,13 @@ bool TerrainBlock::onAdd()
if ( mTerrFileName.isEmpty() )
{
mTerrFileName = Con::getVariable( "$Client::MissionFile" );
mTerrFileName.replace("tools/levels/", "art/terrains/");
mTerrFileName.replace("levels/", "art/terrains/");
String terrainDirectory( Con::getVariable( "$pref::Directories::Terrain" ) );
if ( terrainDirectory.isEmpty() )
{
terrainDirectory = "art/terrains/";
}
mTerrFileName.replace("tools/levels/", terrainDirectory);
mTerrFileName.replace("levels/", terrainDirectory);
Vector<String> materials;
materials.push_back( "warning_material" );
@ -1065,6 +1070,9 @@ void TerrainBlock::setTransform(const MatrixF & mat)
setRenderTransform( mat );
setMaskBits( TransformMask );
if(isClientObject())
smUpdateSignal.trigger( HeightmapUpdate, this, Point2I::Zero, Point2I::Max );
}
void TerrainBlock::setScale( const VectorF &scale )

View file

@ -233,7 +233,8 @@ public:
F32 heightScale,
F32 metersPerPixel,
const Vector<U8> &layerMap,
const Vector<String> &materials );
const Vector<String> &materials,
bool flipYAxis = true );
#ifdef TORQUE_TOOLS
bool exportHeightMap( const UTF8 *filePath, const String &format ) const;

View file

@ -30,7 +30,8 @@ ImplementFeatureType( MFT_TerrainBaseMap, MFG_Texture, 100.0f, false );
ImplementFeatureType( MFT_TerrainParallaxMap, MFG_Texture, 101.0f, false );
ImplementFeatureType( MFT_TerrainDetailMap, MFG_Texture, 102.0f, false );
ImplementFeatureType( MFT_TerrainNormalMap, MFG_Texture, 103.0f, false );
ImplementFeatureType( MFT_TerrainLightMap, MFG_Texture, 104.0f, false );
ImplementFeatureType( MFT_TerrainSideProject, MFG_Texture, 105.0f, false );
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 );

View file

@ -28,6 +28,7 @@
#endif
DeclareFeatureType( MFT_TerrainBaseMap );
DeclareFeatureType( MFT_TerrainMacroMap );
DeclareFeatureType( MFT_TerrainDetailMap );
DeclareFeatureType( MFT_TerrainNormalMap );
DeclareFeatureType( MFT_TerrainParallaxMap );

View file

@ -683,7 +683,8 @@ void TerrainFile::setHeightMap( const Vector<U16> &heightmap, bool updateCollisi
void TerrainFile::import( const GBitmap &heightMap,
F32 heightScale,
const Vector<U8> &layerMap,
const Vector<String> &materials )
const Vector<String> &materials,
bool flipYAxis )
{
AssertFatal( heightMap.getWidth() == heightMap.getHeight(), "TerrainFile::import - Height map is not square!" );
AssertFatal( isPow2( heightMap.getWidth() ), "TerrainFile::import - Height map is not power of two!" );
@ -702,23 +703,48 @@ void TerrainFile::import( const GBitmap &heightMap,
{
const F32 toFixedPoint = ( 1.0f / (F32)U16_MAX ) * floatToFixed( heightScale );
const U16 *iBits = (const U16*)heightMap.getBits();
for ( U32 i = 0; i < mSize * mSize; i++ )
if ( flipYAxis )
{
U16 height = convertBEndianToHost( *iBits );
*oBits = (U16)mCeil( (F32)height * toFixedPoint );
++oBits;
++iBits;
for ( U32 i = 0; i < mSize * mSize; i++ )
{
U16 height = convertBEndianToHost( *iBits );
*oBits = (U16)mCeil( (F32)height * toFixedPoint );
++oBits;
++iBits;
}
}
else
{
for(S32 y = mSize - 1; y >= 0; y--) {
for(U32 x = 0; x < mSize; x++) {
U16 height = convertBEndianToHost( *iBits );
mHeightMap[x + y * mSize] = (U16)mCeil( (F32)height * toFixedPoint );
++iBits;
}
}
}
}
else
{
const F32 toFixedPoint = ( 1.0f / (F32)U8_MAX ) * floatToFixed( heightScale );
const U8 *iBits = heightMap.getBits();
for ( U32 i = 0; i < mSize * mSize; i++ )
if ( flipYAxis )
{
*oBits = (U16)mCeil( ((F32)*iBits) * toFixedPoint );
++oBits;
iBits += heightMap.getBytesPerPixel();
for ( U32 i = 0; i < mSize * mSize; i++ )
{
*oBits = (U16)mCeil( ((F32)*iBits) * toFixedPoint );
++oBits;
iBits += heightMap.getBytesPerPixel();
}
}
else
{
for(S32 y = mSize - 1; y >= 0; y--) {
for(U32 x = 0; x < mSize; x++) {
mHeightMap[x + y * mSize] = (U16)mCeil( ((F32)*iBits) * toFixedPoint );
iBits += heightMap.getBytesPerPixel();
}
}
}
}
@ -744,7 +770,12 @@ void TerrainFile::create( String *inOutFilename,
if ( !basePath.getExtension().equal("mis") )
{
// Use the default path and filename
basePath.setPath( "art/terrains" );
String terrainDirectory( Con::getVariable( "$pref::Directories::Terrain" ) );
if ( terrainDirectory.isEmpty() )
{
terrainDirectory = "art/terrains";
}
basePath.setPath( terrainDirectory );
basePath.setFileName( "terrain" );
}

View file

@ -152,7 +152,8 @@ public:
void import( const GBitmap &heightMap,
F32 heightScale,
const Vector<U8> &layerMap,
const Vector<String> &materials );
const Vector<String> &materials,
bool flipYAxis = true );
/// Updates the terrain grid for the specified area.
void updateGrid( const Point2I &minPt, const Point2I &maxPt );
@ -268,7 +269,7 @@ inline F32 fixedToFloat( U16 val )
/// Conversion from floating point to 11.5 fixed point.
inline U16 floatToFixed( F32 val )
{
return U16(val * 32.0);
return U16(val * 32.0 + 0.5f);
}
inline bool TerrainFile::isPointInTerrain( U32 x, U32 y ) const

View file

@ -31,6 +31,7 @@
#include "util/noise2d.h"
#include "core/volume.h"
using namespace Torque;
ConsoleStaticMethod( TerrainBlock, createNew, S32, 5, 5,
"TerrainBlock.create( String terrainName, U32 resolution, String materialName, bool genNoise )\n"
@ -50,8 +51,13 @@ ConsoleStaticMethod( TerrainBlock, createNew, S32, 5, 5,
// rename it themselves in their file browser. The main reason for this is so we can easily increment for ourselves;
// and because its too easy to rename the terrain object and forget to take care of the terrain filename afterwards.
FileName terrFileName( Con::getVariable("$Client::MissionFile") );
terrFileName.replace("tools/levels/", "art/terrains/");
terrFileName.replace("levels/", "art/terrains/");
String terrainDirectory( Con::getVariable( "$pref::Directories::Terrain" ) );
if ( terrainDirectory.isEmpty() )
{
terrainDirectory = "art/terrains/";
}
terrFileName.replace("tools/levels/", terrainDirectory);
terrFileName.replace("levels/", terrainDirectory);
TerrainFile::create( &terrFileName, resolution, materials );
@ -115,8 +121,8 @@ ConsoleStaticMethod( TerrainBlock, createNew, S32, 5, 5,
return terrain->getId();
}
ConsoleStaticMethod( TerrainBlock, import, S32, 7, 7,
"( String terrainName, String heightMap, F32 metersPerPixel, F32 heightScale, String materials, String opacityLayers )\n"
ConsoleStaticMethod( TerrainBlock, import, S32, 7, 8,
"( String terrainName, String heightMap, F32 metersPerPixel, F32 heightScale, String materials, String opacityLayers[, bool flipYAxis=true] )\n"
"" )
{
// Get the parameters.
@ -126,6 +132,7 @@ ConsoleStaticMethod( TerrainBlock, import, S32, 7, 7,
F32 heightScale = dAtof(argv[4]);
const UTF8 *opacityFiles = argv[5];
const UTF8 *materialsStr = argv[6];
bool flipYAxis = argc == 8? dAtob(argv[7]) : true;
// First load the height map and validate it.
Resource<GBitmap> heightmap = GBitmap::load( hmap );
@ -246,12 +253,12 @@ ConsoleStaticMethod( TerrainBlock, import, S32, 7, 7,
// Do we have an existing terrain with that name... then update it!
TerrainBlock *terrain = dynamic_cast<TerrainBlock*>( Sim::findObject( terrainName ) );
if ( terrain )
terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials );
terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials, flipYAxis );
else
{
terrain = new TerrainBlock();
terrain->assignName( terrainName );
terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials );
terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials, flipYAxis );
terrain->registerObject();
// Add to mission group!
@ -267,7 +274,8 @@ bool TerrainBlock::import( const GBitmap &heightMap,
F32 heightScale,
F32 metersPerPixel,
const Vector<U8> &layerMap,
const Vector<String> &materials )
const Vector<String> &materials,
bool flipYAxis)
{
AssertFatal( isServerObject(), "TerrainBlock::import - This should only be called on the server terrain!" );
@ -294,7 +302,7 @@ bool TerrainBlock::import( const GBitmap &heightMap,
}
// The file does a bunch of the work.
mFile->import( heightMap, heightScale, layerMap, materials );
mFile->import( heightMap, heightScale, layerMap, materials, flipYAxis );
// Set the square size.
mSquareSize = metersPerPixel;

View file

@ -23,6 +23,7 @@
#include "platform/platform.h"
#include "terrain/terrMaterial.h"
#include "console/consoleTypes.h"
#include "gfx/gfxTextureManager.h"
#include "gfx/bitmap/gBitmap.h"
@ -61,6 +62,9 @@ TerrainMaterial::TerrainMaterial()
mDetailSize( 5.0f ),
mDetailStrength( 1.0f ),
mDetailDistance( 50.0f ),
mMacroSize( 200.0f ),
mMacroStrength( 0.7f ),
mMacroDistance( 500.0f ),
mParallaxScale( 0.0f )
{
}
@ -83,6 +87,13 @@ void TerrainMaterial::initPersistFields()
addField( "detailDistance", TypeF32, Offset( mDetailDistance, TerrainMaterial ), "Changes how far camera can see the detail map rendering on the material" );
addField( "useSideProjection", TypeBool, Offset( mSideProjection, TerrainMaterial ),"Makes that terrain material project along the sides of steep "
"slopes instead of projected downwards");
//Macro maps additions
addField( "macroMap", TypeStringFilename, Offset( mMacroMap, TerrainMaterial ), "Macro map for the material" );
addField( "macroSize", TypeF32, Offset( mMacroSize, TerrainMaterial ), "Used to scale the Macro map to the material square" );
addField( "macroStrength", TypeF32, Offset( mMacroStrength, TerrainMaterial ), "Exponentially sharpens or lightens the Macro map rendering on the material" );
addField( "macroDistance", TypeF32, Offset( mMacroDistance, TerrainMaterial ), "Changes how far camera can see the Macro map rendering on the material" );
addField( "parallaxScale", TypeF32, Offset( mParallaxScale, TerrainMaterial ), "Used to scale the height from the normal map to give some self "
"occlusion effect (aka parallax) to the terrain material" );
@ -152,10 +163,12 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath )
// fallback here just in case it gets "lost".
mat = new TerrainMaterial();
mat->setInternalName( "warning_material" );
mat->mDiffuseMap = "core/art/warnMat.png";
mat->mDiffuseMap = GFXTextureManager::getWarningTexturePath();
mat->mDiffuseSize = 500;
mat->mDetailMap = "core/art/warnMat.png";
mat->mDetailMap = GFXTextureManager::getWarningTexturePath();
mat->mDetailSize = 5;
mat->mMacroMap = GFXTextureManager::getWarningTexturePath();
mat->mMacroSize = 200;
mat->registerObject();
Sim::getRootGroup()->addObject( mat );

View file

@ -66,6 +66,11 @@ protected:
/// planes.
bool mSideProjection;
FileName mMacroMap;
F32 mMacroSize;
F32 mMacroStrength;
F32 mMacroDistance;
///
F32 mParallaxScale;
@ -96,12 +101,20 @@ public:
const String& getDetailMap() const { return mDetailMap; }
const String& getMacroMap() const { return mMacroMap; }
F32 getDetailSize() const { return mDetailSize; }
F32 getDetailStrength() const { return mDetailStrength; }
F32 getDetailDistance() const { return mDetailDistance; }
F32 getMacroSize() const { return mMacroSize; }
F32 getMacroDistance() const { return mMacroDistance; }
F32 getMacroStrength() const { return mMacroStrength; }
bool useSideProjection() const { return mSideProjection; }
F32 getParallaxScale() const { return mParallaxScale; }

View file

@ -62,7 +62,7 @@ GFX_ImplementTextureProfile( TerrainLayerTexProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::PreserveSize |
GFXTextureProfile::Dynamic,
GFXTextureProfile::None );
GFXTextureProfile::NONE );
void TerrainBlock::_onFlushMaterials()
@ -94,6 +94,10 @@ void TerrainBlock::_updateMaterials()
if ( mat->getDetailMap().isNotEmpty() &&
mat->getDetailDistance() > mMaxDetailDistance )
mMaxDetailDistance = mat->getDetailDistance();
if ( mat->getMacroMap().isNotEmpty() &&
mat->getMacroDistance() > mMaxDetailDistance )
mMaxDetailDistance = mat->getMacroDistance();
}
if ( mCell )
@ -215,8 +219,12 @@ void TerrainBlock::_updateBaseTexture( bool writeToCache )
points[3].texCoord = Point2F( 1.0, needsYFlip ? 0.0f : 1.0f );
vb.set( GFX, 4, GFXBufferTypeVolatile );
dMemcpy( vb.lock(), points, sizeof(GFXVertexPT) * 4 );
vb.unlock();
GFXVertexPT *ptr = vb.lock();
if(ptr)
{
dMemcpy( ptr, points, sizeof(GFXVertexPT) * 4 );
vb.unlock();
}
}
GFXTexHandle blendTex;