mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-22 16:13:45 +00:00
Merge pull request #968 from AtomicWalrus/TerrainMacroAndBlendHardness_PR
Enables terrain macro maps, adds height blend "hardness" setting
This commit is contained in:
commit
b6f3c25fea
10 changed files with 333 additions and 89 deletions
|
|
@ -45,7 +45,7 @@ namespace
|
|||
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 NamedFeatureGLSL("TerrainMacroMap Deprecated")); // new TerrainMacroMapFeatGLSL);
|
||||
FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatGLSL);
|
||||
FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatGLSL );
|
||||
FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureGLSL( "Terrain Side Projection" ) );
|
||||
FEATUREMGR->registerFeature(MFT_TerrainHeightBlend, new TerrainHeightMapBlendGLSL);
|
||||
|
|
@ -142,6 +142,24 @@ Var* TerrainFeatGLSL::_getDetailMapSampler()
|
|||
return detailMapSampler;
|
||||
}
|
||||
|
||||
Var* TerrainFeatGLSL::_getMacroMapSampler()
|
||||
{
|
||||
String name("macroMapSampler");
|
||||
Var* detailMapSampler = (Var*)LangElement::find(name);
|
||||
|
||||
if (!detailMapSampler)
|
||||
{
|
||||
detailMapSampler = new Var;
|
||||
detailMapSampler->setName(name);
|
||||
detailMapSampler->setType("sampler2DArray");
|
||||
detailMapSampler->uniform = true;
|
||||
detailMapSampler->sampler = true;
|
||||
detailMapSampler->constNum = Var::getTexUnitNum();
|
||||
}
|
||||
|
||||
return detailMapSampler;
|
||||
}
|
||||
|
||||
Var* TerrainFeatGLSL::_getNormalMapSampler()
|
||||
{
|
||||
String name("normalMapSampler");
|
||||
|
|
@ -200,18 +218,21 @@ Var* TerrainFeatGLSL::_getDetailIdStrengthParallax()
|
|||
|
||||
Var* TerrainFeatGLSL::_getMacroIdStrengthParallax()
|
||||
{
|
||||
String name(String::ToString("macroIdStrengthParallax%d", getProcessIndex()));
|
||||
String name(String::ToString("macroIdStrengthParallax", getProcessIndex()));
|
||||
|
||||
Var* detailInfo = (Var*)LangElement::find(name);
|
||||
if (!detailInfo)
|
||||
{
|
||||
detailInfo = new Var;
|
||||
detailInfo->setType("vec3");
|
||||
detailInfo->setType("vec4");
|
||||
detailInfo->setName(name);
|
||||
detailInfo->uniform = true;
|
||||
detailInfo->constSortPos = cspPotentialPrimitive;
|
||||
detailInfo->arraySize = getProcessIndex();
|
||||
}
|
||||
|
||||
detailInfo->arraySize = mMax(detailInfo->arraySize, getProcessIndex() + 1);
|
||||
|
||||
return detailInfo;
|
||||
}
|
||||
|
||||
|
|
@ -427,6 +448,19 @@ void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
|
|||
|
||||
detScaleAndFade->arraySize = mMax(detScaleAndFade->arraySize, detailIndex + 1);
|
||||
|
||||
// This is done here to make sure the macro array size/alignment is correct
|
||||
Var* macroScaleAndFade = (Var*)LangElement::find("macroScaleAndFade");
|
||||
if (macroScaleAndFade == NULL)
|
||||
{
|
||||
macroScaleAndFade = new Var;
|
||||
macroScaleAndFade->setType("vec4");
|
||||
macroScaleAndFade->setName("macroScaleAndFade");
|
||||
macroScaleAndFade->uniform = true;
|
||||
macroScaleAndFade->constSortPos = cspPotentialPrimitive;
|
||||
}
|
||||
|
||||
macroScaleAndFade->arraySize = mMax(macroScaleAndFade->arraySize, detailIndex + 1);
|
||||
|
||||
// Setup the detail coord.
|
||||
//
|
||||
// NOTE: You see here we scale the texture coord by 'xyx'
|
||||
|
|
@ -510,6 +544,9 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
|
|||
// Get the detail id.
|
||||
Var *detailInfo = _getDetailIdStrengthParallax();
|
||||
|
||||
// This is done here to make sure the macro arrays are the correct size
|
||||
Var* macroInfo = _getMacroIdStrengthParallax();
|
||||
|
||||
// Create the detail blend var.
|
||||
Var *detailBlend = new Var;
|
||||
detailBlend->setType( "float" );
|
||||
|
|
@ -568,7 +605,8 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
|
|||
detailColor, detailMapArray, detCoord, new IndexOp(detailInfo, detailIndex)));
|
||||
}
|
||||
|
||||
meta->addStatement(new GenOp(" @ *= @.y * @;\r\n", detailColor, new IndexOp(detailInfo, detailIndex), detailBlend));
|
||||
meta->addStatement(new GenOp(" @ *= @.y;\r\n",
|
||||
detailColor, new IndexOp(detailInfo, detailIndex)));
|
||||
|
||||
if (!fd.features.hasFeature(MFT_TerrainNormalMap))
|
||||
{
|
||||
|
|
@ -672,18 +710,23 @@ void TerrainMacroMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentL
|
|||
outTex->setStructName( "OUT" );
|
||||
outTex->setType( "vec4" );
|
||||
|
||||
// Get the detail scale and fade info.
|
||||
Var *macroScaleAndFade = new Var;
|
||||
Var* macroScaleAndFade = (Var*)LangElement::find("macroScaleAndFade");
|
||||
if (macroScaleAndFade == NULL)
|
||||
{
|
||||
macroScaleAndFade = new Var;
|
||||
macroScaleAndFade->setType( "vec4" );
|
||||
macroScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) );
|
||||
macroScaleAndFade->setName("macroScaleAndFade");
|
||||
macroScaleAndFade->uniform = true;
|
||||
macroScaleAndFade->constSortPos = cspPotentialPrimitive;
|
||||
}
|
||||
|
||||
macroScaleAndFade->arraySize = mMax(macroScaleAndFade->arraySize, detailIndex + 1);
|
||||
|
||||
// Setup the detail coord.
|
||||
meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, macroScaleAndFade ) );
|
||||
meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(macroScaleAndFade, detailIndex)) );
|
||||
|
||||
// And sneak the detail fade thru the w detailCoord.
|
||||
meta->addStatement( new GenOp( " @.w = ( @.z - @ ) * @.w;\r\n", outTex, macroScaleAndFade, dist, macroScaleAndFade ) );
|
||||
meta->addStatement( new GenOp( " @.w = ( @.z - @ ) * @.w;\r\n", outTex, new IndexOp(macroScaleAndFade, detailIndex), dist, new IndexOp(macroScaleAndFade, detailIndex)) );
|
||||
|
||||
output = meta;
|
||||
}
|
||||
|
|
@ -761,7 +804,7 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
|
|||
|
||||
// Calculate the blend for this detail texture.
|
||||
meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
|
||||
new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
|
||||
new DecOp( detailBlend ), new IndexOp(detailInfo, detailIndex), inTex, layerSize, layerSample ) );
|
||||
|
||||
// Check to see if we have a gbuffer normal.
|
||||
Var* gbNormal = (Var*)LangElement::find("gbNormal");
|
||||
|
|
@ -779,26 +822,17 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
|
|||
gbNormal, gbNormal, viewToTangent, detailBlend, detCoord ) );
|
||||
}
|
||||
|
||||
Var *detailColor = (Var*)LangElement::find( "macroColor" );
|
||||
Var* detailColor = (Var*)LangElement::find(String::ToString("macroColor%d", detailIndex));
|
||||
if ( !detailColor )
|
||||
{
|
||||
detailColor = new Var;
|
||||
detailColor->setType( "vec4" );
|
||||
detailColor->setName( "macroColor" );
|
||||
detailColor->setName(String::ToString("macroColor%d", detailIndex));
|
||||
meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
|
||||
}
|
||||
|
||||
// Get the detail texture.
|
||||
Var *detailMapArray = new Var;
|
||||
detailMapArray->setType( "sampler2D" );
|
||||
detailMapArray->setName( String::ToString( "macroMap%d", detailIndex ) );
|
||||
detailMapArray->uniform = true;
|
||||
detailMapArray->sampler = true;
|
||||
detailMapArray->constNum = Var::getTexUnitNum(); // used as texture unit num here
|
||||
|
||||
meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
|
||||
|
||||
meta->addStatement( new GenOp( " {\r\n" ) );
|
||||
Var* detailMapArray = _getMacroMapSampler();
|
||||
|
||||
// Note that we're doing the standard greyscale detail
|
||||
// map technique here which can darken and lighten the
|
||||
|
|
@ -818,20 +852,12 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
|
|||
}
|
||||
else
|
||||
{
|
||||
meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
|
||||
detailColor, detailMapArray, detCoord) );
|
||||
meta->addStatement(new GenOp(" @ = ( tex2D( @, vec3(@.xy, @.x) ) * 2.0 ) - 1.0;\r\n",
|
||||
detailColor, detailMapArray, detCoord, new IndexOp(detailInfo, detailIndex)));
|
||||
}
|
||||
|
||||
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", detailColor, detailInfo, detCoord) );
|
||||
|
||||
ShaderFeature::OutputTarget target = (fd.features[MFT_isDeferred]) ? RenderTarget1 : DefaultTarget;
|
||||
|
||||
Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
|
||||
|
||||
meta->addStatement(new GenOp(" @ += @ * @;\r\n",
|
||||
outColor, detailColor, detailBlend));
|
||||
|
||||
meta->addStatement( new GenOp( " }\r\n" ) );
|
||||
meta->addStatement(new GenOp(" @ *= @.y;\r\n",
|
||||
detailColor, new IndexOp(detailInfo, detailIndex)));
|
||||
|
||||
output = meta;
|
||||
}
|
||||
|
|
@ -844,15 +870,14 @@ ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFe
|
|||
{
|
||||
// If this is the first detail pass then we
|
||||
// samples from the layer tex.
|
||||
res.numTex = 1;
|
||||
res.numTexReg = 1;
|
||||
|
||||
// Add Detail TextureArray
|
||||
res.numTex += 1;
|
||||
res.numTexReg += 1;
|
||||
}
|
||||
|
||||
res.numTex += 1;
|
||||
|
||||
// Finally we always send the detail texture
|
||||
// coord to the pixel shader.
|
||||
res.numTexReg += 1;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1252,7 +1277,7 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
|
|||
}
|
||||
|
||||
Var* heightRange = new Var("heightRange", "vec2");
|
||||
meta->addStatement(new GenOp(" @ = vec2(2.0f,0);//x=min, y=max\r\n", new DecOp(heightRange)));
|
||||
meta->addStatement(new GenOp(" @ = vec2(0,0);//x=min, y=max\r\n", new DecOp(heightRange)));
|
||||
// Compute blend factors
|
||||
for (S32 idx = 0; idx < detailCount; ++idx)
|
||||
{
|
||||
|
|
@ -1301,7 +1326,20 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
|
|||
{
|
||||
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
|
||||
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
|
||||
meta->addStatement(new GenOp(" @ = (@-@.x)/(@.y-@.x)-@.x;\r\n", detailH, detailH, heightRange, heightRange, heightRange));
|
||||
Var* blendHardness = (Var*)LangElement::find(String::ToString("blendHardness%d", idx));
|
||||
if (!blendHardness)
|
||||
{
|
||||
blendHardness = new Var;
|
||||
blendHardness->setType("float");
|
||||
blendHardness->setName(String::ToString("blendHardness%d", idx));
|
||||
blendHardness->uniform = true;
|
||||
blendHardness->constSortPos = cspPrimitive;
|
||||
}
|
||||
meta->addStatement(new GenOp(" @ = (@-@.x)/(@.y-@.x)-@.x;\r\n", detailH, detailH, heightRange, heightRange, heightRange, heightRange));
|
||||
// Note that blendHardness is clamped between 0-0.99 at the terrain material level to avoid a divide by zero
|
||||
meta->addStatement(new GenOp(" @ = 1.0f / (1.0f - @) * (@ - @);\r\n", detailH, blendHardness, detailH, blendHardness));
|
||||
// This line equation will go out of our 0-1 range, clamp it
|
||||
meta->addStatement(new GenOp(" @ = clamp(@, 0.0f, 1.0f);\r\n", detailH, detailH));
|
||||
|
||||
}
|
||||
meta->addStatement(new GenOp("\r\n"));
|
||||
|
|
@ -1333,6 +1371,31 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
|
|||
|
||||
meta->addStatement(new GenOp(");\r\n"));
|
||||
|
||||
// Macro textures, if they exist
|
||||
bool didMacro = false;
|
||||
for (S32 idx = 0; idx < detailCount; ++idx)
|
||||
{
|
||||
Var* detailColor = (Var*)LangElement::find(String::ToString("macroColor%d", idx));
|
||||
if (detailColor) // only do this if the macro map exists for this layer
|
||||
{
|
||||
if (!didMacro)
|
||||
meta->addStatement(new GenOp(" @.rgb += (", outColor));
|
||||
|
||||
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
|
||||
Var* detCoord = (Var*)LangElement::find(String::ToString("macroCoord%d", idx));
|
||||
|
||||
if (idx > 0 && didMacro)
|
||||
{
|
||||
meta->addStatement(new GenOp(" + "));
|
||||
}
|
||||
|
||||
meta->addStatement(new GenOp("((@.rgb * @)*max(@.w,0))", detailColor, detailH, detCoord));
|
||||
didMacro = true;
|
||||
}
|
||||
}
|
||||
if (didMacro)
|
||||
meta->addStatement(new GenOp(");\r\n"));
|
||||
|
||||
// Compute ORM
|
||||
Var* ormOutput;
|
||||
if (fd.features[MFT_isDeferred])
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public:
|
|||
Var* _getInMacroCoord(Vector<ShaderComponent*> &componentList );
|
||||
|
||||
Var* _getDetailMapSampler();
|
||||
Var* _getMacroMapSampler();
|
||||
Var* _getNormalMapSampler();
|
||||
Var* _getOrmMapSampler();
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace
|
|||
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 NamedFeatureHLSL("TerrainMacroMap Deprecated")); // new TerrainMacroMapFeatHLSL);
|
||||
FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatHLSL);
|
||||
FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatHLSL );
|
||||
FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureHLSL( "Terrain Side Projection" ) );
|
||||
FEATUREMGR->registerFeature( MFT_TerrainHeightBlend, new TerrainHeightMapBlendHLSL );
|
||||
|
|
@ -160,6 +160,42 @@ Var* TerrainFeatHLSL::_getDetailMapArray()
|
|||
return detailMapArray;
|
||||
}
|
||||
|
||||
Var* TerrainFeatHLSL::_getMacroMapSampler()
|
||||
{
|
||||
String name("macroMapSampler");
|
||||
Var* detailMapSampler = (Var*)LangElement::find(name);
|
||||
|
||||
if (!detailMapSampler)
|
||||
{
|
||||
detailMapSampler = new Var;
|
||||
detailMapSampler->setName(name);
|
||||
detailMapSampler->setType("SamplerState");
|
||||
detailMapSampler->uniform = true;
|
||||
detailMapSampler->sampler = true;
|
||||
detailMapSampler->constNum = Var::getTexUnitNum();
|
||||
}
|
||||
|
||||
return detailMapSampler;
|
||||
}
|
||||
|
||||
Var* TerrainFeatHLSL::_getMacroMapArray()
|
||||
{
|
||||
String name("macroMapArray");
|
||||
Var* detailMapArray = (Var*)LangElement::find(name);
|
||||
|
||||
if (!detailMapArray)
|
||||
{
|
||||
detailMapArray = new Var;
|
||||
detailMapArray->setName(name);
|
||||
detailMapArray->setType("Texture2DArray");
|
||||
detailMapArray->uniform = true;
|
||||
detailMapArray->texture = true;
|
||||
detailMapArray->constNum = _getMacroMapSampler()->constNum;
|
||||
}
|
||||
|
||||
return detailMapArray;
|
||||
}
|
||||
|
||||
Var* TerrainFeatHLSL::_getNormalMapSampler()
|
||||
{
|
||||
String name("normalMapSampler");
|
||||
|
|
@ -254,18 +290,20 @@ Var* TerrainFeatHLSL::_getDetailIdStrengthParallax()
|
|||
|
||||
Var* TerrainFeatHLSL::_getMacroIdStrengthParallax()
|
||||
{
|
||||
String name( String::ToString( "macroIdStrengthParallax%d", getProcessIndex() ) );
|
||||
String name( String::ToString( "macroIdStrengthParallax", getProcessIndex() ) );
|
||||
|
||||
Var *detailInfo = (Var*)LangElement::find( name );
|
||||
if ( !detailInfo )
|
||||
{
|
||||
detailInfo = new Var;
|
||||
detailInfo->setType( "float3" );
|
||||
detailInfo->setType( "float4" );
|
||||
detailInfo->setName( name );
|
||||
detailInfo->uniform = true;
|
||||
detailInfo->constSortPos = cspPotentialPrimitive;
|
||||
}
|
||||
|
||||
detailInfo->arraySize = mMax(detailInfo->arraySize, getProcessIndex() + 1);
|
||||
|
||||
return detailInfo;
|
||||
}
|
||||
|
||||
|
|
@ -483,6 +521,19 @@ void TerrainDetailMapFeatHLSL::processVert( Vector<ShaderComponent*> &component
|
|||
|
||||
detScaleAndFade->arraySize = mMax(detScaleAndFade->arraySize, detailIndex + 1);
|
||||
|
||||
// Done here to keep array indexes aligned
|
||||
Var* macroScaleAndFade = (Var*)LangElement::find("macroScaleAndFade");
|
||||
if (macroScaleAndFade == NULL)
|
||||
{
|
||||
macroScaleAndFade = new Var;
|
||||
macroScaleAndFade->setType("float4");
|
||||
macroScaleAndFade->setName("macroScaleAndFade");
|
||||
macroScaleAndFade->uniform = true;
|
||||
macroScaleAndFade->constSortPos = cspPotentialPrimitive;
|
||||
}
|
||||
|
||||
macroScaleAndFade->arraySize = mMax(macroScaleAndFade->arraySize, detailIndex + 1);
|
||||
|
||||
// Setup the detail coord.
|
||||
//
|
||||
// NOTE: You see here we scale the texture coord by 'xyx'
|
||||
|
|
@ -572,6 +623,9 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
|
|||
// Get the detail id.
|
||||
Var *detailInfo = _getDetailIdStrengthParallax();
|
||||
|
||||
// Done here to keep array indexes aligned
|
||||
Var* macroInfo = _getMacroIdStrengthParallax();
|
||||
|
||||
// Create the detail blend var.
|
||||
Var *detailBlend = new Var;
|
||||
detailBlend->setType( "float" );
|
||||
|
|
@ -630,7 +684,8 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
|
|||
detailColor, detailMapArray, detailMapSampler, detCoord, new IndexOp(detailInfo, detailIndex)));
|
||||
}
|
||||
|
||||
meta->addStatement(new GenOp(" @ *= @.y * @;\r\n", detailColor, new IndexOp(detailInfo, detailIndex), detailBlend));
|
||||
meta->addStatement(new GenOp(" @ *= @.y;\r\n",
|
||||
detailColor, new IndexOp(detailInfo, detailIndex)));
|
||||
|
||||
if (!fd.features.hasFeature(MFT_TerrainNormalMap))
|
||||
{
|
||||
|
|
@ -854,24 +909,13 @@ void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentL
|
|||
gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
|
||||
}
|
||||
|
||||
Var *detailColor = (Var*)LangElement::find("macroColor");
|
||||
if (!detailColor)
|
||||
{
|
||||
detailColor = new Var;
|
||||
Var* detailColor = new Var;
|
||||
detailColor->setType( "float4" );
|
||||
detailColor->setName( "macroColor" );
|
||||
meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
|
||||
}
|
||||
detailColor->setName( String::ToString("macroColor%d", detailIndex) );
|
||||
meta->addStatement( new GenOp( " @ = float4(0.5f, 0.5f, 0.5f, 1.0f);\r\n", new DecOp( detailColor ) ) );
|
||||
|
||||
// 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" ) );
|
||||
|
||||
Var* detailMapArray = _getDetailMapArray();
|
||||
Var* detailMapSampler = _getDetailMapSampler();
|
||||
Var* detailMapArray = _getMacroMapArray();
|
||||
Var* detailMapSampler = _getMacroMapSampler();
|
||||
|
||||
// Note that we're doing the standard greyscale detail
|
||||
// map technique here which can darken and lighten the
|
||||
|
|
@ -895,17 +939,8 @@ void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentL
|
|||
detailColor, detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex)));
|
||||
}
|
||||
|
||||
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
|
||||
detailColor, new IndexOp(detailInfo, detailIndex), inDet ) );
|
||||
|
||||
ShaderFeature::OutputTarget target = (fd.features[MFT_isDeferred]) ? RenderTarget1 : DefaultTarget;
|
||||
|
||||
Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
|
||||
|
||||
meta->addStatement(new GenOp(" @ += @ * @;\r\n",
|
||||
outColor, detailColor, detailBlend));
|
||||
|
||||
meta->addStatement( new GenOp( " }\r\n" ) );
|
||||
meta->addStatement(new GenOp(" @ *= @.y;\r\n",
|
||||
detailColor, new IndexOp(detailInfo, detailIndex)));
|
||||
|
||||
output = meta;
|
||||
}
|
||||
|
|
@ -919,13 +954,12 @@ ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFe
|
|||
// If this is the first detail pass then we
|
||||
// samples from the layer tex.
|
||||
res.numTex += 1;
|
||||
}
|
||||
res.numTexReg += 1;
|
||||
|
||||
// Add Detail TextureArray
|
||||
res.numTex += 1;
|
||||
|
||||
// Finally we always send the detail texture
|
||||
// coord to the pixel shader.
|
||||
res.numTexReg += 1;
|
||||
res.numTexReg += 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1333,7 +1367,7 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
|
|||
}
|
||||
|
||||
Var* heightRange = new Var("heightRange", "float2");
|
||||
meta->addStatement(new GenOp(" @ = float2(2.0f,0);//x=min, y=max\r\n", new DecOp(heightRange)));
|
||||
meta->addStatement(new GenOp(" @ = float2(0,0);//x=min, y=max\r\n", new DecOp(heightRange)));
|
||||
// Compute blend factors
|
||||
for (S32 idx = 0; idx < detailCount; ++idx)
|
||||
{
|
||||
|
|
@ -1382,7 +1416,20 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
|
|||
{
|
||||
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
|
||||
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
|
||||
Var* blendHardness = (Var*)LangElement::find(String::ToString("blendHardness%d", idx));
|
||||
if (!blendHardness)
|
||||
{
|
||||
blendHardness = new Var;
|
||||
blendHardness->setType("float");
|
||||
blendHardness->setName(String::ToString("blendHardness%d", idx));
|
||||
blendHardness->uniform = true;
|
||||
blendHardness->constSortPos = cspPrimitive;
|
||||
}
|
||||
meta->addStatement(new GenOp(" @ = (@-@.x)/(@.y-@.x)-@.x;\r\n", detailH, detailH, heightRange, heightRange, heightRange, heightRange));
|
||||
// Note that blendHardness is clamped between 0-0.99 at the terrain material level to avoid a divide by zero
|
||||
meta->addStatement(new GenOp(" @ = 1.0f / (1.0f - @) * (@ - @);\r\n", detailH, blendHardness, detailH, blendHardness));
|
||||
// This line equation will go out of our 0-1 range, clamp it
|
||||
meta->addStatement(new GenOp(" @ = clamp(@, 0.0f, 1.0f);\r\n", detailH, detailH));
|
||||
}
|
||||
meta->addStatement(new GenOp("\r\n"));
|
||||
}
|
||||
|
|
@ -1413,6 +1460,31 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
|
|||
|
||||
meta->addStatement(new GenOp(");\r\n"));
|
||||
|
||||
// Macro textures, if they exist
|
||||
bool didMacro = false;
|
||||
for (S32 idx = 0; idx < detailCount; ++idx)
|
||||
{
|
||||
Var* detailColor = (Var*)LangElement::find(String::ToString("macroColor%d", idx));
|
||||
if (detailColor) // only do this if the macro map exists for this layer
|
||||
{
|
||||
if (!didMacro)
|
||||
meta->addStatement(new GenOp(" @.rgb += (", outColor));
|
||||
|
||||
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
|
||||
Var* detCoord = (Var*)LangElement::find(String::ToString("macroCoord%d", idx));
|
||||
|
||||
if (idx > 0 && didMacro)
|
||||
{
|
||||
meta->addStatement(new GenOp(" + "));
|
||||
}
|
||||
|
||||
meta->addStatement(new GenOp("((@.rgb * @)*max(@.w,0))", detailColor, detailH, detCoord));
|
||||
didMacro = true;
|
||||
}
|
||||
}
|
||||
if (didMacro)
|
||||
meta->addStatement(new GenOp(");\r\n"));
|
||||
|
||||
// Compute ORM
|
||||
Var* ormOutput;
|
||||
if (fd.features[MFT_isDeferred])
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ public:
|
|||
|
||||
Var* _getDetailMapSampler();
|
||||
Var* _getDetailMapArray();
|
||||
Var* _getMacroMapSampler();
|
||||
Var* _getMacroMapArray();
|
||||
Var* _getNormalMapSampler();
|
||||
Var* _getNormalMapArray();
|
||||
Var* _getOrmMapSampler();
|
||||
|
|
|
|||
|
|
@ -548,7 +548,7 @@ bool TerrainCellMaterial::_initShader(bool deferredMat,
|
|||
|
||||
mDetailInfoVArrayConst = mShader->getShaderConstHandle("$detailScaleAndFade");
|
||||
mDetailInfoPArrayConst = mShader->getShaderConstHandle("$detailIdStrengthParallax");
|
||||
mMacroInfoVArrayConst = mShader->getShaderConstHandle("$macroIdStrengthParallax");
|
||||
mMacroInfoVArrayConst = mShader->getShaderConstHandle("$macroScaleAndFade");
|
||||
mMacroInfoPArrayConst = mShader->getShaderConstHandle("$macroIdStrengthParallax");
|
||||
|
||||
mDetailTexArrayConst = mShader->getShaderConstHandle("$detailMapSampler");
|
||||
|
|
@ -637,6 +637,7 @@ bool TerrainCellMaterial::_initShader(bool deferredMat,
|
|||
|
||||
mMaterialInfos[i]->mBlendDepthConst = mShader->getShaderConstHandle(avar("$blendDepth%d", i));
|
||||
mMaterialInfos[i]->mBlendContrastConst = mShader->getShaderConstHandle(avar("$blendContrast%d", i));
|
||||
mMaterialInfos[i]->mBlendHardnessConst = mShader->getShaderConstHandle(avar("$blendHardness%d", i));
|
||||
}
|
||||
|
||||
// If we're doing deferred it requires some
|
||||
|
|
@ -689,6 +690,9 @@ void TerrainCellMaterial::_updateMaterialConsts( )
|
|||
AlignedArray<Point4F> detailInfoArray(detailMatCount, sizeof(Point4F));
|
||||
AlignedArray<Point4F> detailScaleAndFadeArray(detailMatCount, sizeof(Point4F));
|
||||
|
||||
AlignedArray<Point4F> macroInfoArray(detailMatCount, sizeof(Point4F));
|
||||
AlignedArray<Point4F> macroScaleAndFadeArray(detailMatCount, sizeof(Point4F));
|
||||
|
||||
int detailIndex = 0;
|
||||
for (MaterialInfo* matInfo : mMaterialInfos)
|
||||
{
|
||||
|
|
@ -745,12 +749,45 @@ void TerrainCellMaterial::_updateMaterialConsts( )
|
|||
{
|
||||
mConsts->setSafe(matInfo->mBlendContrastConst, matInfo->mat->getBlendContrast());
|
||||
}
|
||||
|
||||
if (matInfo->mBlendHardnessConst != NULL)
|
||||
{
|
||||
mConsts->setSafe(matInfo->mBlendHardnessConst, matInfo->mat->getBlendHardness());
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
Point4F macroIdStrengthParallax(matInfo->layerId,
|
||||
matInfo->mat->getMacroStrength(),
|
||||
0, 0);
|
||||
|
||||
macroScaleAndFadeArray[detailIndex] = macroScaleAndFade;
|
||||
macroInfoArray[detailIndex] = macroIdStrengthParallax;
|
||||
|
||||
detailIndex++;
|
||||
}
|
||||
|
||||
mConsts->setSafe(mDetailInfoVArrayConst, detailScaleAndFadeArray);
|
||||
mConsts->setSafe(mDetailInfoPArrayConst, detailInfoArray);
|
||||
|
||||
mConsts->setSafe(mMacroInfoVArrayConst, macroScaleAndFadeArray);
|
||||
mConsts->setSafe(mMacroInfoPArrayConst, macroInfoArray);
|
||||
}
|
||||
|
||||
bool TerrainCellMaterial::setupPass( const SceneRenderState *state,
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ protected:
|
|||
public:
|
||||
|
||||
MaterialInfo()
|
||||
:mat(NULL), layerId(0), mBlendDepthConst(NULL), mBlendContrastConst(NULL)
|
||||
:mat(NULL), layerId(0), mBlendDepthConst(NULL), mBlendContrastConst(NULL), mBlendHardnessConst(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +71,7 @@ protected:
|
|||
U32 layerId;
|
||||
GFXShaderConstHandle *mBlendDepthConst;
|
||||
GFXShaderConstHandle *mBlendContrastConst;
|
||||
GFXShaderConstHandle* mBlendHardnessConst;
|
||||
};
|
||||
|
||||
///
|
||||
|
|
@ -119,6 +120,7 @@ protected:
|
|||
GFXShaderConstHandle *mOrmTexArrayConst;
|
||||
|
||||
GFXShaderConstHandle* mBlendDepthConst;
|
||||
GFXShaderConstHandle* mBlendHeightFloorConst;
|
||||
|
||||
TerrainBlock *mTerrain;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "console/consoleTypes.h"
|
||||
#include "gfx/gfxTextureManager.h"
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
#include "console/typeValidators.h"
|
||||
|
||||
#ifdef TORQUE_TOOLS
|
||||
#include "console/persistenceManager.h"
|
||||
|
|
@ -76,6 +77,7 @@ TerrainMaterial::TerrainMaterial()
|
|||
mParallaxScale( 0.0f ),
|
||||
mBlendDepth( 0.0f ),
|
||||
mBlendContrast( 1.0f ),
|
||||
mBlendHardness( 0.0f ),
|
||||
mIsSRGB(false),
|
||||
mInvertRoughness(false)
|
||||
{
|
||||
|
|
@ -90,6 +92,8 @@ TerrainMaterial::~TerrainMaterial()
|
|||
{
|
||||
}
|
||||
|
||||
FRangeValidator hardnessValidator(0.0f, 0.999f);
|
||||
|
||||
void TerrainMaterial::initPersistFields()
|
||||
{
|
||||
docsURL;
|
||||
|
|
@ -106,6 +110,9 @@ void TerrainMaterial::initPersistFields()
|
|||
addField("blendHeightContrast", TypeF32, Offset(mBlendContrast, TerrainMaterial), "A fixed value to add while blending using heightmap-based blending."
|
||||
"Higher numbers = larger blend radius.");
|
||||
|
||||
addFieldV("blendHeightHardness", TypeF32, Offset(mBlendHardness, TerrainMaterial), &hardnessValidator, "How sharply this layer blends with other textures."
|
||||
"0->1, soft->hard.");
|
||||
|
||||
INITPERSISTFIELD_IMAGEASSET(DetailMap, TerrainMaterial, "Raises and lowers the RGB result of the Base Albedo up close.");
|
||||
addField( "detailSize", TypeF32, Offset( mDetailSize, TerrainMaterial ), "Used to scale the detail map to the material square" );
|
||||
addField( "detailStrength", TypeF32, Offset( mDetailStrength, TerrainMaterial ), "Exponentially sharpens or lightens the detail map rendering on the material" );
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ protected:
|
|||
|
||||
F32 mBlendContrast;
|
||||
|
||||
F32 mBlendHardness;
|
||||
|
||||
public:
|
||||
|
||||
TerrainMaterial();
|
||||
|
|
@ -138,6 +140,8 @@ public:
|
|||
|
||||
F32 getBlendContrast() const { return mBlendContrast; }
|
||||
|
||||
F32 getBlendHardness() const { return mBlendHardness; }
|
||||
|
||||
bool getIsSRGB() const { return mIsSRGB; }
|
||||
|
||||
bool getInvertRoughness() const { return mInvertRoughness; }
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) {
|
|||
};
|
||||
new GuiContainer(NormalMapContainer) {
|
||||
position = "6 205";
|
||||
extent = "261 100";
|
||||
extent = "261 120";
|
||||
horizSizing = "width";
|
||||
profile = "ToolsGuiDefaultProfile";
|
||||
tooltipProfile = "ToolsGuiToolTipProfile";
|
||||
|
|
@ -527,17 +527,45 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) {
|
|||
isContainer = "0";
|
||||
internalName = "blendHeightContrastTextEditCtrl";
|
||||
};
|
||||
new GuiTextEditCtrl(TerrainMaterialDlgBlendHeightHardnessTextEdit) {
|
||||
text = "0";
|
||||
anchorTop = "0";
|
||||
anchorLeft = "0";
|
||||
position = "1 99";
|
||||
extent = "35 18";
|
||||
profile = "ToolsGuiTextEditProfile";
|
||||
tooltipProfile = "ToolsGuiToolTipProfile";
|
||||
isContainer = "0";
|
||||
internalName = "blendHeightHardnessTextEditCtrl";
|
||||
};
|
||||
new GuiTextCtrl() {
|
||||
text = "Blend Hardness";
|
||||
position = "115 101";
|
||||
extent = "76 15";
|
||||
profile = "ToolsGuiTextProfile";
|
||||
tooltipProfile = "ToolsGuiToolTipProfile";
|
||||
};
|
||||
new GuiSliderCtrl(TerrainMaterialDlgBlendHeightHardnessSlider) {
|
||||
range = "0 0.999";
|
||||
ticks = "0";
|
||||
value = "0";
|
||||
position = "39 101";
|
||||
extent = "70 14";
|
||||
profile = "ToolsGuiSliderProfile";
|
||||
tooltipProfile = "ToolsGuiToolTipProfile";
|
||||
internalName = "blendHeightHardnessSliderCtrl";
|
||||
};
|
||||
};
|
||||
new GuiBitmapCtrl() {
|
||||
BitmapAsset = "ToolsModule:separator_v_image";
|
||||
position = "6 307";
|
||||
extent = "266 2";
|
||||
BitmapAsset = "ToolsModule:separator_v_image";
|
||||
position = "6 323";
|
||||
extent = "266 2";
|
||||
horizSizing = "width";
|
||||
profile = "ToolsGuiDefaultProfile";
|
||||
tooltipProfile = "ToolsGuiToolTipProfile";
|
||||
};
|
||||
new GuiContainer(ORMConfigMapContainer) {
|
||||
position = "6 314";
|
||||
position = "6 330";
|
||||
extent = "261 64";
|
||||
horizSizing = "width";
|
||||
profile = "ToolsGuiDefaultProfile";
|
||||
|
|
@ -615,14 +643,14 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) {
|
|||
};
|
||||
new GuiBitmapCtrl() {
|
||||
BitmapAsset = "ToolsModule:separator_v_image";
|
||||
position = "6 381";
|
||||
position = "6 397";
|
||||
extent = "266 2";
|
||||
horizSizing = "width";
|
||||
profile = "ToolsGuiDefaultProfile";
|
||||
tooltipProfile = "ToolsGuiToolTipProfile";
|
||||
};
|
||||
new GuiContainer(MacroMapContainer) {
|
||||
position = "6 388";
|
||||
position = "6 404";
|
||||
extent = "261 72";
|
||||
horizSizing = "width";
|
||||
profile = "ToolsGuiDefaultProfile";
|
||||
|
|
@ -746,7 +774,7 @@ $guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) {
|
|||
};
|
||||
};
|
||||
new GuiContainer(TerrainEffectsContainer) {
|
||||
position = "6 460";
|
||||
position = "6 476";
|
||||
extent = "265 97";
|
||||
horizSizing = "width";
|
||||
profile = "ToolsGuiDefaultProfile";
|
||||
|
|
|
|||
|
|
@ -477,6 +477,10 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
|
|||
%this-->blendHeightContrastTextEditCtrl.setText( %blendHeightContrast );
|
||||
%this-->blendHeightContrastSliderCtrl.setValue( %mat.blendHeightContrast );
|
||||
|
||||
%blendHeightHardness = mFloor(%mat.blendHeightHardness * 1000)/1000;
|
||||
%this-->blendHeightHardnessTextEditCtrl.setText( %blendHeightHardness );
|
||||
%this-->blendHeightHardnessSliderCtrl.setValue( %mat.blendHeightHardness );
|
||||
|
||||
%this-->macroSizeCtrl.setText( %mat.macroSize );
|
||||
%this-->macroStrengthCtrl.setText( %mat.macroStrength );
|
||||
%this-->macroDistanceCtrl.setText( %mat.macroDistance );
|
||||
|
|
@ -686,6 +690,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %materialAssetId )
|
|||
%parallaxScale = %this-->parallaxScaleCtrl.getText();
|
||||
%blendHeightBase = %this-->blendHeightBaseTextEditCtrl.getText();
|
||||
%blendHeightContrast = %this-->blendHeightContrastTextEditCtrl.getText();
|
||||
%blendHeightHardness = %this-->blendHeightHardnessTextEditCtrl.getText();
|
||||
|
||||
%macroSize = %this-->macroSizeCtrl.getText();
|
||||
%macroStrength = %this-->macroStrengthCtrl.getText();
|
||||
|
|
@ -725,6 +730,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %materialAssetId )
|
|||
%mat.parallaxScale == %parallaxScale &&
|
||||
%mat.blendHeightBase == %blendHeightBase &&
|
||||
%mat.blendHeightContrast == %blendHeightContrast &&
|
||||
%mat.blendHeightHardness == %blendHeightHardness &&
|
||||
%mat.isSRGB == %isSRGB &&
|
||||
%mat.invertRoughness == %invertRoughness &&
|
||||
%fxMat.effectColor[0] == %effectColor0 &&
|
||||
|
|
@ -772,6 +778,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %materialAssetId )
|
|||
%mat.parallaxScale = %parallaxScale;
|
||||
%mat.blendHeightBase = %blendHeightBase;
|
||||
%mat.blendHeightContrast = %blendHeightContrast;
|
||||
%mat.blendHeightHardness = %blendHeightHardness;
|
||||
%mat.isSRGB = %isSRGB;
|
||||
%mat.invertRoughness = %invertRoughness;
|
||||
|
||||
|
|
@ -861,6 +868,7 @@ function TerrainMaterialDlg::snapshotMaterials( %this )
|
|||
parallaxScale = %mat.parallaxScale;
|
||||
blendHeightBase = %mat.blendHeightBase;
|
||||
blendHeightContrast = %mat.blendHeightContrast;
|
||||
blendHeightHardness = %mat.blendHeightHardness;
|
||||
isSRGB = %mat.isSRGB;
|
||||
invertRoughness = %mat.invertRoughness;
|
||||
};
|
||||
|
|
@ -901,6 +909,7 @@ function TerrainMaterialDlg::restoreMaterials( %this )
|
|||
%mat.parallaxScale = %obj.parallaxScale;
|
||||
%mat.blendHeightBase = %obj.blendHeightBase;
|
||||
%mat.blendHeightContrast = %obj.blendHeightContrast;
|
||||
%mat.blendHeightHardness = %obj.blendHeightHardness;
|
||||
%mat.isSRGB = %obj.isSRGB;
|
||||
%mat.invertRoughness = %obj.invertRoughness;
|
||||
}
|
||||
|
|
@ -971,6 +980,25 @@ function TerrainMaterialDlgBlendHeightContrastTextEdit::onValidate(%this)
|
|||
TerrainMaterialDlg.matDirty = true;
|
||||
}
|
||||
|
||||
function TerrainMaterialDlgBlendHeightHardnessSlider::onMouseDragged(%this)
|
||||
{
|
||||
%value = mClamp(%this.value, 0.0, 0.999);
|
||||
%value = mFloor(%value * 1000)/1000;
|
||||
TerrainMaterialDlgBlendHeightHardnessTextEdit.setText(%value);
|
||||
TerrainMaterialDlg.activeMat.blendHeightHardness = %value;
|
||||
TerrainMaterialDlg.matDirty = true;
|
||||
}
|
||||
|
||||
function TerrainMaterialDlgBlendHeightHardnessTextEdit::onValidate(%this)
|
||||
{
|
||||
%value = mClamp(%this.getText(), 0.0, 0.999);
|
||||
%value = mFloor(%value * 1000)/1000;
|
||||
%this.setText(%value);
|
||||
TerrainMaterialDlgBlendHeightHardnessSlider.setValue(%value);
|
||||
TerrainMaterialDlg.activeMat.blendHeightHardness = %value;
|
||||
TerrainMaterialDlg.matDirty = true;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
function terrMatEdDragNDropMapAssignment(%mapName, %payload)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue