Merge pull request #917 from Azaezel/alpha402/terrainBlendCleanups

cleanups for terrain blending
This commit is contained in:
Brian Roberts 2022-11-05 03:08:02 -05:00 committed by GitHub
commit 97eaab3f49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 253 additions and 567 deletions

View file

@ -250,10 +250,10 @@ void TerrainBaseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentLis
{ {
Var* inNormal = (Var*)LangElement::find("normal"); Var* inNormal = (Var*)LangElement::find("normal");
meta->addStatement( meta->addStatement(
new GenOp(" @.z = clamp(abs( dot( normalize( vec3( @.x, @.y, 0 ) ), vec3( 0, 1, 0 ) ) ), 0.0, 1.0);\r\n", new GenOp(" @.z = dot( normalize( vec3( @.x, @.y, 0 ) ), vec3( 0, 1, 0 ) );\r\n",
outTex, inNormal, inNormal)); outTex, inNormal, inNormal));
meta->addStatement( meta->addStatement(
new GenOp(" @.w = 1.0 - abs( dot( normalize( @.xyz ), vec3( 0, 0, 1 ) ) );\r\n", new GenOp(" @.w = 1.0 - dot( normalize( @.xyz ), vec3( 0, 0, 1 ) );\r\n",
outTex, inNormal)); outTex, inNormal));
} }
else else
@ -319,7 +319,7 @@ void TerrainBaseMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
} }
else else
{ {
ormConfig = new Var("ORMConfig", "float4"); ormConfig = new Var("ORMConfig", "vec4");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(ormConfig))); meta->addStatement(new GenOp(" @;\r\n", new DecOp(ormConfig)));
} }
@ -362,8 +362,8 @@ void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
// Grab incoming texture coords... the base map feature // Grab incoming texture coords... the base map feature
// made sure this was created. // made sure this was created.
Var *inTex = (Var*)LangElement::find( "texCoord" ); Var * inTexCoord = (Var*)LangElement::find( "texCoord" );
AssertFatal( inTex, "The texture coord is missing!" ); AssertFatal(inTexCoord, "The texture coord is missing!" );
// Grab the input position. // Grab the input position.
Var *inPos = (Var*)LangElement::find( "inPosition" ); Var *inPos = (Var*)LangElement::find( "inPosition" );
@ -409,14 +409,14 @@ void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
// grab connector texcoord register // grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outTex = connectComp->getElement( RT_TEXCOORD ); Var * detCoord = connectComp->getElement( RT_TEXCOORD );
outTex->setName( String::ToString( "detCoord%d", detailIndex ) ); detCoord->setName( String::ToString( "detCoord%d", detailIndex ) );
outTex->setStructName( "OUT" ); detCoord->setStructName( "OUT" );
outTex->setType( "vec4" ); detCoord->setType( "vec4" );
// Get the detail scale and fade info. // Get the detail scale and fade info.
Var *detScaleAndFade = (Var*)LangElement::find("detailScaleAndFade"); Var* detScaleAndFade = (Var*)LangElement::find("detailScaleAndFade");
if (!detScaleAndFade) if (detScaleAndFade == NULL)
{ {
detScaleAndFade = new Var; detScaleAndFade = new Var;
detScaleAndFade->setType("vec4"); detScaleAndFade->setType("vec4");
@ -436,11 +436,11 @@ void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
// //
// See TerrainBaseMapFeatGLSL::processVert(). // See TerrainBaseMapFeatGLSL::processVert().
// //
meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(detScaleAndFade, detailIndex) ) ); meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", detCoord, inTexCoord, new IndexOp(detScaleAndFade, detailIndex) ) );
// And sneak the detail fade thru the w detailCoord. // And sneak the detail fade thru the w detailCoord.
meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", meta->addStatement(new GenOp(" @.w = ( @.z - @ ) * @.w;\r\n",
outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex))); detCoord, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)));
output = meta; output = meta;
} }
@ -449,7 +449,7 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
const MaterialFeatureData &fd ) const MaterialFeatureData &fd )
{ {
const S32 detailIndex = getProcessIndex(); const S32 detailIndex = getProcessIndex();
Var *inTex = getVertTexCoord( "texCoord" ); Var *inTexCoord = getVertTexCoord( "texCoord" );
MultiLine *meta = new MultiLine; MultiLine *meta = new MultiLine;
@ -491,7 +491,7 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
// Read the layer texture to get the samples. // Read the layer texture to get the samples.
meta->addStatement( new GenOp( " @ = round( tex2D( @, @.xy ) * 255.0f );\r\n", meta->addStatement( new GenOp( " @ = round( tex2D( @, @.xy ) * 255.0f );\r\n",
new DecOp( layerSample ), layerTex, inTex ) ); new DecOp( layerSample ), layerTex, inTexCoord ) );
} }
Var *layerSize = (Var*)LangElement::find( "layerSize" ); Var *layerSize = (Var*)LangElement::find( "layerSize" );
@ -505,7 +505,7 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
} }
// Grab the incoming detail coord. // Grab the incoming detail coord.
Var *inDet = _getInDetailCoord( componentList ); Var * detCoord = _getInDetailCoord( componentList );
// Get the detail id. // Get the detail id.
Var *detailInfo = _getDetailIdStrengthParallax(); Var *detailInfo = _getDetailIdStrengthParallax();
@ -517,39 +517,39 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
// Calculate the blend for this detail texture. // Calculate the blend for this detail texture.
meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n", meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
new DecOp( detailBlend ), new IndexOp(detailInfo, detailIndex), inTex, layerSize, layerSample ) ); new DecOp( detailBlend ), new IndexOp(detailInfo, detailIndex), inTexCoord, layerSize, layerSample ) );
// If we had a parallax feature... then factor in the parallax // If we had a parallax feature... then factor in the parallax
// amount so that it fades out with the layer blending. // amount so that it fades out with the layer blending.
if (fd.features.hasFeature(MFT_TerrainParallaxMap, detailIndex)) if (fd.features.hasFeature(MFT_TerrainParallaxMap, detailIndex))
{ {
// Get the normal map texture. // Get the normal map textures.
Var* normalMap = _getNormalMapSampler(); Var* normalMapArray = _getNormalMapSampler();
// Call the library function to do the rest. // Call the library function to do the rest.
if (fd.features.hasFeature(MFT_IsBC3nm, detailIndex)) if (fd.features.hasFeature(MFT_IsBC3nm, detailIndex))
{ {
meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, vec3(@.xy, @.x), @, @.z * @ );\r\n", meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, vec3(@.xy, @.x), @, @.z * @ );\r\n",
inDet, normalMap, inDet, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend)); detCoord, normalMapArray, detCoord, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend));
} }
else else
{ {
meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, vec3(@.xy, @.x), @, @.z * @ );\r\n", meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, vec3(@.xy, @.x), @, @.z * @ );\r\n",
inDet, normalMap, inDet, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend)); detCoord, normalMapArray, detCoord, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend));
} }
} }
Var* detailColor = (Var*)LangElement::find(String::ToString("detailColor%d", detailIndex)); Var *detailColor = (Var*)LangElement::find(String::ToString("detailColor%d", detailIndex));
if (!detailColor) if ( !detailColor )
{ {
detailColor = new Var; detailColor = new Var;
detailColor->setType("vec4"); detailColor->setType( "vec4" );
detailColor->setName(String::ToString("detailColor%d", detailIndex)); detailColor->setName( String::ToString("detailColor%d", detailIndex) );
meta->addStatement(new GenOp(" @;\r\n", new DecOp(detailColor))); meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) );
} }
// Get the detail texture. // Get the detail texture.
Var *detailMap = _getDetailMapSampler(); Var *detailMapArray = _getDetailMapSampler();
// If we had a parallax feature... then factor in the parallax // If we had a parallax feature... then factor in the parallax
// amount so that it fades out with the layer blending. // amount so that it fades out with the layer blending.
@ -557,19 +557,18 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
{ {
meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, vec3(@.xy, @.x) ), lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z ), @.w) * 2.0 ) - 1.0;\r\n", meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, vec3(@.xy, @.x) ), lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z ), @.w) * 2.0 ) - 1.0;\r\n",
detailColor, detailColor,
detailMap, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detCoord, new IndexOp(detailInfo, detailIndex),
detailMap, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detCoord, new IndexOp(detailInfo, detailIndex),
detailMap, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detCoord, new IndexOp(detailInfo, detailIndex),
inTex, inTex)); inTexCoord, inTexCoord));
} }
else else
{ {
meta->addStatement(new GenOp(" @ = ( tex2D( @, vec3(@.xy, @.x) ) * 2.0 ) - 1.0;\r\n", meta->addStatement(new GenOp(" @ = ( tex2D( @, vec3(@.xy, @.x) ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, new IndexOp(detailInfo, detailIndex))); detailColor, detailMapArray, detCoord, new IndexOp(detailInfo, detailIndex)));
} }
meta->addStatement(new GenOp(" @ *= @.y * @.w;\r\n", meta->addStatement(new GenOp(" @ *= @.y * @;\r\n", detailColor, new IndexOp(detailInfo, detailIndex), detailBlend));
detailColor, new IndexOp(detailInfo, detailIndex), inDet));
if (!fd.features.hasFeature(MFT_TerrainNormalMap)) if (!fd.features.hasFeature(MFT_TerrainNormalMap))
{ {
@ -585,32 +584,14 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
{ {
Var* viewToTangent = getInViewToTangent(componentList); Var* viewToTangent = getInViewToTangent(componentList);
meta->addStatement(new GenOp(" @ = lerp( @, tGetMatrix3Row(@, 2), min( @, @.w ) );\r\n", meta->addStatement(new GenOp(" @ = lerp( @, tGetMatrix3Row(@, 2), @ ) );\r\n", gbNormal, gbNormal, viewToTangent, detailBlend));
gbNormal, gbNormal, viewToTangent, detailBlend, inDet));
} }
// If we're using SM 3.0 then take advantage of ShaderFeature::OutputTarget target = (fd.features[MFT_isDeferred]) ? RenderTarget1 : DefaultTarget;
// 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"));
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
if (fd.features.hasFeature(MFT_isDeferred))
target = ShaderFeature::RenderTarget1;
Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target)); Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target));
meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n", outColor, outColor)); meta->addStatement(new GenOp(" @ += @ * @;\r\n", outColor, detailColor, detailBlend));
meta->addStatement(new GenOp(" @ += @ * @;\r\n",
outColor, detailColor, detailBlend));
meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n", outColor, outColor));
meta->addStatement(new GenOp(" }\r\n"));
} }
output = meta; output = meta;
@ -691,18 +672,17 @@ void TerrainMacroMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentL
outTex->setType( "vec4" ); outTex->setType( "vec4" );
// Get the detail scale and fade info. // Get the detail scale and fade info.
Var *detScaleAndFade = new Var; Var *macroScaleAndFade = new Var;
detScaleAndFade->setType( "vec4" ); macroScaleAndFade->setType( "vec4" );
detScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) ); macroScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) );
detScaleAndFade->uniform = true; macroScaleAndFade->uniform = true;
detScaleAndFade->constSortPos = cspPotentialPrimitive; macroScaleAndFade->constSortPos = cspPotentialPrimitive;
// Setup the detail coord. // Setup the detail coord.
meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) ); meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, macroScaleAndFade ) );
// And sneak the detail fade thru the w detailCoord. // And sneak the detail fade thru the w detailCoord.
meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", meta->addStatement( new GenOp( " @.w = ( @.z - @ ) * @.w;\r\n", outTex, macroScaleAndFade, dist, macroScaleAndFade ) );
outTex, detScaleAndFade, dist, detScaleAndFade ) );
output = meta; output = meta;
} }
@ -768,7 +748,7 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
} }
// Grab the incoming detail coord. // Grab the incoming detail coord.
Var *inDet = _getInMacroCoord( componentList ); Var *detCoord = _getInMacroCoord( componentList );
// Get the detail id. // Get the detail id.
Var *detailInfo = _getMacroIdStrengthParallax(); Var *detailInfo = _getMacroIdStrengthParallax();
@ -792,10 +772,10 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
if (gbNormal && if (gbNormal &&
!fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex)) !fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex))
{ {
Var* viewToTangent = getInViewToTangent(componentList); Var *viewToTangent = getInViewToTangent( componentList );
meta->addStatement(new GenOp(" @ = lerp( @, @[2], min( @, @.w ) );\r\n", meta->addStatement( new GenOp( " @ = lerp( @, @[2], min( @, @.w ) );\r\n",
gbNormal, gbNormal, viewToTangent, detailBlend, inDet)); gbNormal, gbNormal, viewToTangent, detailBlend, detCoord ) );
} }
Var *detailColor = (Var*)LangElement::find( "macroColor" ); Var *detailColor = (Var*)LangElement::find( "macroColor" );
@ -808,17 +788,14 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
} }
// Get the detail texture. // Get the detail texture.
Var *detailMap = new Var; Var *detailMapArray = new Var;
detailMap->setType( "sampler2D" ); detailMapArray->setType( "sampler2D" );
detailMap->setName( String::ToString( "macroMap%d", detailIndex ) ); detailMapArray->setName( String::ToString( "macroMap%d", detailIndex ) );
detailMap->uniform = true; detailMapArray->uniform = true;
detailMap->sampler = true; detailMapArray->sampler = true;
detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here detailMapArray->constNum = Var::getTexUnitNum(); // used as texture unit num here
// If we're using SM 3.0 then take advantage of meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) );
// 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" ) ); meta->addStatement( new GenOp( " {\r\n" ) );
@ -829,45 +806,35 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
// We take two color samples and lerp between them for // We take two color samples and lerp between them for
// side projection layers... else a single sample. // side projection layers... else a single sample.
// //
if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) ) if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
{ {
meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, vec3(@.xy, @.x) ), lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z ), @.w) * 2.0 ) - 1.0;\r\n", meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, vec3(@.xy, @.x) ), lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z ), @.w) * 2.0 ) - 1.0;\r\n",
detailColor, detailColor,
detailMap, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detCoord, new IndexOp(detailInfo, detailIndex),
detailMap, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detCoord, new IndexOp(detailInfo, detailIndex),
detailMap, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detCoord, new IndexOp(detailInfo, detailIndex),
inTex, inTex)); inTex, inTex));
} }
else else
{ {
meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n", meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet ) ); detailColor, detailMapArray, detCoord) );
} }
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", detailColor, detailInfo, detCoord) );
detailColor, detailInfo, inDet ) );
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget; ShaderFeature::OutputTarget target = (fd.features[MFT_isDeferred]) ? RenderTarget1 : DefaultTarget;
if (fd.features.hasFeature(MFT_isDeferred))
target= ShaderFeature::RenderTarget1;
Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) ); Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n", outColor, outColor));
meta->addStatement(new GenOp(" @ += @ * @;\r\n", meta->addStatement(new GenOp(" @ += @ * @;\r\n",
outColor, detailColor, detailBlend)); outColor, detailColor, detailBlend));
meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n", outColor, outColor));
meta->addStatement( new GenOp( " }\r\n" ) ); meta->addStatement( new GenOp( " }\r\n" ) );
output = meta; output = meta;
} }
ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFeatureData &fd ) ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFeatureData &fd )
{ {
Resources res; Resources res;
@ -902,7 +869,7 @@ void TerrainNormalMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
MultiLine *meta = new MultiLine; MultiLine *meta = new MultiLine;
if (!fd.features.hasFeature(MFT_TerrainHeightBlend)) if ( !fd.features.hasFeature(MFT_TerrainHeightBlend) )
{ {
// Make sure the world to tangent transform // Make sure the world to tangent transform
// is created and available for the pixel shader. // is created and available for the pixel shader.
@ -927,36 +894,36 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
AssertFatal( detailBlend, "The detail blend is missing!" ); AssertFatal( detailBlend, "The detail blend is missing!" );
// Get the normal map texture. // Get the normal map texture.
Var *normalMap = _getNormalMapSampler(); Var *normalMapArray = _getNormalMapSampler();
/// Get the texture coord. /// Get the texture coord.
Var *inDet = _getInDetailCoord( componentList ); Var* inDet = _getInDetailCoord(componentList);
Var *inTex = getVertTexCoord( "texCoord" ); Var* inTex = getVertTexCoord("texCoord");
Var* detailInfo = _getDetailIdStrengthParallax(); Var* detailInfo = _getDetailIdStrengthParallax();
// Sample the normal map. // Sample the normal map.
// //
// We take two normal samples and lerp between them for // We take two normal samples and lerp between them for
// side projection layers... else a single sample. // side projection layers... else a single sample.
LangElement *texOp; LangElement* texOp;
if ( fd.features.hasFeature( MFT_TerrainSideProject, normalIndex ) ) if (fd.features.hasFeature(MFT_TerrainSideProject, normalIndex))
{ {
texOp = new GenOp("lerp( tex2D( @, float3(@.xy, @.x) ), lerp( tex2D( @, float3(@.yz, @.x) ), tex2D( @, float3(@.xz, @.x) ), @.z ), @.w )", texOp = new GenOp("lerp( tex2D( @, float3(@.xy, @.x) ), lerp( tex2D( @, float3(@.yz, @.x) ), tex2D( @, float3(@.xz, @.x) ), @.z ), @.w )",
normalMap, inDet, new IndexOp(detailInfo, normalIndex), normalMapArray, inDet, new IndexOp(detailInfo, normalIndex),
normalMap, inDet, new IndexOp(detailInfo, normalIndex), normalMapArray, inDet, new IndexOp(detailInfo, normalIndex),
normalMap, inDet, new IndexOp(detailInfo, normalIndex), normalMapArray, inDet, new IndexOp(detailInfo, normalIndex),
inTex, inTex); inTex, inTex);
} }
else else
texOp = new GenOp( String::ToString("tex2D(@, vec3(@.xy, @.x))", normalIndex), normalMap, inDet, new IndexOp(detailInfo, normalIndex)); texOp = new GenOp( String::ToString("tex2D(@, vec3(@.xy, @.x))", normalIndex), normalMapArray, inDet, new IndexOp(detailInfo, normalIndex));
// create bump normal // create bump normal
Var *bumpNorm = new Var; Var* bumpNorm = new Var;
bumpNorm->setName( String::ToString("bumpNormal%d", normalIndex) ); bumpNorm->setName(String::ToString("bumpNormal%d", normalIndex));
bumpNorm->setType( "vec4" ); bumpNorm->setType("vec4");
LangElement *bumpNormDecl = new DecOp( bumpNorm ); LangElement* bumpNormDecl = new DecOp(bumpNorm);
meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) ); meta->addStatement(expandNormalMap(texOp, bumpNormDecl, bumpNorm, fd));
if (!fd.features.hasFeature(MFT_TerrainNormalMap)) if (!fd.features.hasFeature(MFT_TerrainNormalMap))
{ {
@ -996,7 +963,6 @@ ShaderFeature::Resources TerrainNormalMapFeatGLSL::getResources( const MaterialF
{ {
Resources res; Resources res;
// We only need to process normals during the deferred.
if (!fd.features.hasFeature(MFT_DeferredConditioner)) if (!fd.features.hasFeature(MFT_DeferredConditioner))
{ {
return res; return res;
@ -1248,11 +1214,7 @@ void TerrainHeightMapBlendGLSL::processVert(
void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentList, void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentList,
const MaterialFeatureData& fd) const MaterialFeatureData& fd)
{ {
ShaderFeature::OutputTarget target = (fd.features[MFT_isDeferred]) ? RenderTarget1 : DefaultTarget;
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
if (fd.features.hasFeature(MFT_isDeferred))
target = ShaderFeature::RenderTarget1;
Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target)); Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target));
@ -1261,14 +1223,7 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
MultiLine* meta = new MultiLine; MultiLine* meta = new MultiLine;
Var* detailTot = (Var*)LangElement::find("detailTot"); // Count number of detail layers
if (detailTot == NULL)
{
detailTot = new Var("detailTot", "float");
meta->addStatement(new GenOp("@=0;\r\n", new DecOp(detailTot)));
}
// Count the number of detail textures
int detailCount = 0; int detailCount = 0;
while (true) while (true)
{ {
@ -1285,10 +1240,21 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
return; return;
} }
// Compute the "height" of each detail layer and store it detailHX Var* depth = (Var*)LangElement::find("baseBlendDepth");
if (depth == NULL)
{
depth = new Var;
depth->setType("float");
depth->setName("baseBlendDepth");
depth->uniform = true;
depth->constSortPos = cspPrimitive;
}
Var* heightRange = new Var("heightRange", "vec2");
meta->addStatement(new GenOp(" @ = vec2(2.0f,0);//x=min, y=max\r\n", new DecOp(heightRange)));
// Compute blend factors
for (S32 idx = 0; idx < detailCount; ++idx) for (S32 idx = 0; idx < detailCount; ++idx)
{ {
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx)); Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx));
Var* blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", idx)); Var* blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", idx));
if (!blendDepth) if (!blendDepth)
@ -1309,136 +1275,79 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
blendContrast->uniform = true; blendContrast->uniform = true;
blendContrast->constSortPos = cspPrimitive; blendContrast->constSortPos = cspPrimitive;
} }
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx)); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
if (!detailH) if (!detailH)
{ {
detailH = new Var; detailH = new Var;
detailH->setType("float"); detailH->setType("float");
detailH->setName(String::ToString("detailH%d", idx)); detailH->setName(String::ToString("detailH%d", idx));
meta->addStatement(new GenOp(" @ = 0;\r\n", meta->addStatement(new GenOp(" @ = @+@;\r\n", new DecOp(detailH), blendDepth, depth));
new DecOp(detailH)));
meta->addStatement(new GenOp(" if (@ > 0.0f) {\r\n", detailBlend));
if (bumpNormal != NULL) if (bumpNormal != NULL)
{ {
meta->addStatement(new GenOp(" @ = clamp(@.a + @, 0.0, 1.0);\r\n", meta->addStatement(new GenOp(" @ += @.a * @;\r\n", detailH, bumpNormal, blendContrast));
detailH, bumpNormal, blendDepth));
} }
else meta->addStatement(new GenOp(" @ *= @;\r\n", detailH, detailBlend));
{ meta->addStatement(new GenOp(" @ = vec2(min(@.x,@),max(@.y,@));\r\n", heightRange, heightRange, detailH, heightRange, detailH));
meta->addStatement(new GenOp(" @ = clamp(@, 0.0, 1.0);\r\n",
detailH, blendDepth));
}
meta->addStatement(new GenOp(" @ = max((@ * 2.0f - 1.0f) * @, 0.0f);\r\n",
detailH, detailH, blendContrast));
meta->addStatement(new GenOp(" }\r\n"));
} }
} }
meta->addStatement(new GenOp("\r\n")); meta->addStatement(new GenOp("\r\n"));
if (detailCount > 1)
// Compute blending factors
Var* depth = (Var*)LangElement::find("baseBlendDepth");
if (depth == NULL)
{ {
depth = new Var; for (S32 idx = 0; idx < detailCount; ++idx)
depth->setType("float");
depth->setName("baseBlendDepth");
depth->uniform = true;
depth->constSortPos = cspPrimitive;
}
Var* ma = (Var*)LangElement::find("ma");
if (ma == NULL)
{
ma = new Var;
ma->setType("float");
ma->setName("ma");
meta->addStatement(new GenOp(" @ = 0;\r\n",
new DecOp(ma)));
}
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
meta->addStatement(new GenOp(" @ = max(@, @ + @);\r\n",
ma, ma, detailH, detailBlend));
}
meta->addStatement(new GenOp(" @ -= @;\r\n",
ma, depth));
meta->addStatement(new GenOp("\r\n"));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
if (!detailB)
{ {
detailB = new Var; Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
detailB->setType("float"); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
detailB->setName(String::ToString("detailB%d", idx)); meta->addStatement(new GenOp(" @ = (@-@.x)/(@.y-@.x);\r\n", detailH, detailH, heightRange, heightRange, heightRange));
meta->addStatement(new GenOp(" @ = max(@ + @ - @, 0);\r\n",
new DecOp(detailB), detailH, detailBlend, ma));
} }
meta->addStatement(new GenOp(" @ += @;\r\n", detailTot, detailB)); meta->addStatement(new GenOp("\r\n"));
}
else
{
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
meta->addStatement(new GenOp(" @ = 1.0;\r\n", detailH));
}
} }
meta->addStatement(new GenOp("\r\n")); meta->addStatement(new GenOp(" @.rgb += (", outColor));
// Compute albedo
meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n",
outColor, outColor));
meta->addStatement(new GenOp(" @.rgb += (",
outColor));
for (S32 idx = 0; idx < detailCount; ++idx) for (S32 idx = 0; idx < detailCount; ++idx)
{ {
Var* detailColor = (Var*)LangElement::find(String::ToString("detailColor%d", idx)); Var* detailColor = (Var*)LangElement::find(String::ToString("detailColor%d", idx));
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx)); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx));
if (idx > 0) if (idx > 0)
{ {
meta->addStatement(new GenOp(" + ")); meta->addStatement(new GenOp(" + "));
} }
meta->addStatement(new GenOp("@.rgb * @", detailColor, detailB)); meta->addStatement(new GenOp("((@.rgb * @)*max(@.w,0))", detailColor, detailH, detCoord));
} }
meta->addStatement(new GenOp(") / @;\r\n", detailTot)); meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n",
outColor, outColor));
meta->addStatement(new GenOp("\r\n"));
// Compute ORM // Compute ORM
Var* ormOutput; Var* ormOutput;
OutputTarget targ = DefaultTarget;
if (fd.features[MFT_isDeferred]) if (fd.features[MFT_isDeferred])
{ {
targ = RenderTarget2; ormOutput = (Var*)LangElement::find(getOutputTargetVarName(RenderTarget2));
} }
ormOutput = (Var*)LangElement::find(getOutputTargetVarName(targ)); else
{
meta->addStatement(new GenOp(" @.gba = (", ormOutput = (Var*)LangElement::find("ORMConfig");
ormOutput)); }
meta->addStatement(new GenOp(" @.gba = (", ormOutput));
for (S32 idx = 0; idx < detailCount; ++idx) for (S32 idx = 0; idx < detailCount; ++idx)
{ {
Var* matinfoCol = (Var*)LangElement::find(String::ToString("matinfoCol%d", idx)); Var* matinfoCol = (Var*)LangElement::find(String::ToString("matinfoCol%d", idx));
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx)); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
if (idx > 0) if (idx > 0)
{ {
@ -1446,104 +1355,42 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
} }
if (matinfoCol) if (matinfoCol)
{ {
meta->addStatement(new GenOp("@ * @", matinfoCol, detailB)); meta->addStatement(new GenOp("(@ * @)", matinfoCol, detailH));
} }
else else
{ {
meta->addStatement(new GenOp("vec3(1.0, 1.0, 0.0) * @", detailB)); meta->addStatement(new GenOp("(vec3(1.0, 1.0, 0.0) * @)", detailH));
} }
} }
meta->addStatement(new GenOp(") / @;\r\n", detailTot)); meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp("\r\n")); // Compute normals
Var* viewToTangent = getInViewToTangent(componentList);
// Compute normal-specific blending factors Var* bumpSum = new Var("bumpNorm", "vec3");
// LukasPJ: I'm not sure why this is necessary, it might not be.
Var* normalMa = (Var*)LangElement::find("normalMa");
if (normalMa == NULL)
{
normalMa = new Var;
normalMa->setType("float");
normalMa->setName("normalMa");
meta->addStatement(new GenOp(" @ = 0;\r\n",
new DecOp(normalMa)));
}
meta->addStatement(new GenOp(" @ = vec3(0, 0, 1)", new DecOp(bumpSum)));
for (S32 idx = 0; idx < detailCount; ++idx) for (S32 idx = 0; idx < detailCount; ++idx)
{ {
Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx));
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx)); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx)); Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx));
meta->addStatement(new GenOp(" @ = max(@, @ + min(@, @.w));\r\n",
normalMa, normalMa, detailH, detailBlend, detCoord));
}
meta->addStatement(new GenOp(" @ -= @;\r\n",
normalMa, depth));
meta->addStatement(new GenOp("\r\n"));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx)); Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx));
if (bumpNormal != NULL)
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
Var* normalDetailB = (Var*)LangElement::find(String::ToString("normalDetailB%d", idx));
if (!normalDetailB)
{ {
normalDetailB = new Var; meta->addStatement(new GenOp("+(@.xyz * @*max(@.w,0))", bumpNormal, detailH, detCoord));
normalDetailB->setType("float");
normalDetailB->setName(String::ToString("normalDetailB%d", idx));
meta->addStatement(new GenOp(" @ = max(@ + min(@, @.w) - @, 0);\r\n",
new DecOp(normalDetailB), detailH, detailBlend, detCoord, normalMa));
} }
}
// Compute normals }
meta->addStatement(new GenOp(";\r\n"));
Var* gbNormal = (Var*)LangElement::find("gbNormal"); Var* gbNormal = (Var*)LangElement::find("gbNormal");
if (!gbNormal) if (!gbNormal)
{ {
gbNormal = new Var; gbNormal = new Var("gbNormal","vec3");
gbNormal->setName("gbNormal"); meta->addStatement(new GenOp(" @ = ", new DecOp(gbNormal)));
gbNormal->setType("vec3");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(gbNormal)));
} }
else
if (gbNormal != NULL) meta->addStatement(new GenOp(" @ = ", gbNormal));
{ meta->addStatement(new GenOp("tMul(normalize(@),@);\r\n", bumpSum, viewToTangent));
meta->addStatement(new GenOp(" @ = (",
gbNormal));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* normalDetailB = (Var*)LangElement::find(String::ToString("normalDetailB%d", idx));
Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx));
Var* viewToTangent = getInViewToTangent(componentList);
if (idx > 0)
{
meta->addStatement(new GenOp(" + "));
}
if (bumpNormal != NULL)
{
meta->addStatement(new GenOp("tMul(@.xyz, @) * @", bumpNormal, viewToTangent, normalDetailB));
}
else
{
meta->addStatement(new GenOp("tGetMatrix3Row(@, 2) * @", viewToTangent, normalDetailB));
}
}
meta->addStatement(new GenOp(") / @;\r\n", detailTot));
}
output = meta; output = meta;
} }

View file

@ -305,10 +305,10 @@ void TerrainBaseMapFeatHLSL::processVert(Vector<ShaderComponent*>& componentList
{ {
Var* inNormal = (Var*)LangElement::find("normal"); Var* inNormal = (Var*)LangElement::find("normal");
meta->addStatement( meta->addStatement(
new GenOp(" @.z = clamp(abs( dot( normalize( float3( @.x, @.y, 0 ) ), float3( 0, 1, 0 ) ) ), 0.0, 1.0);\r\n", new GenOp(" @.z = dot( normalize( float3( @.x, @.y, 0 ) ), float3( 0, 1, 0 ) );\r\n",
outTex, inNormal, inNormal)); outTex, inNormal, inNormal));
meta->addStatement( meta->addStatement(
new GenOp(" @.w = 1.0 - abs( dot( normalize( @.xyz ), float3( 0, 0, 1 ) ) );\r\n", new GenOp(" @.w = 1.0 - dot( normalize( @.xyz ), float3( 0, 0, 1 ) );\r\n",
outTex, inNormal)); outTex, inNormal));
} }
else else
@ -418,8 +418,8 @@ void TerrainDetailMapFeatHLSL::processVert( Vector<ShaderComponent*> &component
// Grab incoming texture coords... the base map feature // Grab incoming texture coords... the base map feature
// made sure this was created. // made sure this was created.
Var *inTex = (Var*)LangElement::find( "texCoord" ); Var * inTexCoord = (Var*)LangElement::find( "texCoord" );
AssertFatal( inTex, "The texture coord is missing!" ); AssertFatal(inTexCoord, "The texture coord is missing!" );
// Grab the input position. // Grab the input position.
Var *inPos = (Var*)LangElement::find( "inPosition" ); Var *inPos = (Var*)LangElement::find( "inPosition" );
@ -465,10 +465,10 @@ void TerrainDetailMapFeatHLSL::processVert( Vector<ShaderComponent*> &component
// grab connector texcoord register // grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outTex = connectComp->getElement( RT_TEXCOORD ); Var * detCoord = connectComp->getElement( RT_TEXCOORD );
outTex->setName( String::ToString( "detCoord%d", detailIndex ) ); detCoord->setName( String::ToString( "detCoord%d", detailIndex ) );
outTex->setStructName( "OUT" ); detCoord->setStructName( "OUT" );
outTex->setType( "float4" ); detCoord->setType( "float4" );
// Get the detail scale and fade info. // Get the detail scale and fade info.
Var* detScaleAndFade = (Var*)LangElement::find("detailScaleAndFade"); Var* detScaleAndFade = (Var*)LangElement::find("detailScaleAndFade");
@ -492,11 +492,11 @@ void TerrainDetailMapFeatHLSL::processVert( Vector<ShaderComponent*> &component
// //
// See TerrainBaseMapFeatHLSL::processVert(). // See TerrainBaseMapFeatHLSL::processVert().
// //
meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(detScaleAndFade, detailIndex) ) ); meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", detCoord, inTexCoord, new IndexOp(detScaleAndFade, detailIndex) ) );
// And sneak the detail fade thru the w detailCoord. // And sneak the detail fade thru the w detailCoord.
meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", meta->addStatement(new GenOp(" @.w = ( @.z - @ ) * @.w;\r\n",
outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex))); detCoord, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)));
output = meta; output = meta;
} }
@ -505,7 +505,7 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
const MaterialFeatureData &fd ) const MaterialFeatureData &fd )
{ {
const S32 detailIndex = getProcessIndex(); const S32 detailIndex = getProcessIndex();
Var *inTex = getVertTexCoord( "texCoord" ); Var *inTexCoord = getVertTexCoord( "texCoord" );
MultiLine *meta = new MultiLine; MultiLine *meta = new MultiLine;
@ -553,7 +553,7 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
layerTexObj->constNum = layerTex->constNum; layerTexObj->constNum = layerTex->constNum;
// Read the layer texture to get the samples. // Read the layer texture to get the samples.
meta->addStatement(new GenOp(" @ = round( @.Sample( @, @.xy ) * 255.0f );\r\n", meta->addStatement(new GenOp(" @ = round( @.Sample( @, @.xy ) * 255.0f );\r\n",
new DecOp(layerSample), layerTexObj, layerTex, inTex)); new DecOp(layerSample), layerTexObj, layerTex, inTexCoord));
} }
Var *layerSize = (Var*)LangElement::find( "layerSize" ); Var *layerSize = (Var*)LangElement::find( "layerSize" );
@ -567,7 +567,7 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
} }
// Grab the incoming detail coord. // Grab the incoming detail coord.
Var *inDet = _getInDetailCoord( componentList ); Var * detCoord = _getInDetailCoord( componentList );
// Get the detail id. // Get the detail id.
Var *detailInfo = _getDetailIdStrengthParallax(); Var *detailInfo = _getDetailIdStrengthParallax();
@ -579,7 +579,7 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
// Calculate the blend for this detail texture. // Calculate the blend for this detail texture.
meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n", meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n",
new DecOp( detailBlend ), new IndexOp(detailInfo, detailIndex), inTex, layerSize, layerSample ) ); new DecOp( detailBlend ), new IndexOp(detailInfo, detailIndex), inTexCoord, layerSize, layerSample ) );
// If we had a parallax feature... then factor in the parallax // If we had a parallax feature... then factor in the parallax
// amount so that it fades out with the layer blending. // amount so that it fades out with the layer blending.
@ -592,12 +592,12 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
if (fd.features.hasFeature(MFT_IsBC3nm, detailIndex)) if (fd.features.hasFeature(MFT_IsBC3nm, detailIndex))
{ {
meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnmTexArray( @, @, float3(@.xy, @.x), @, @.z * @ );\r\n", meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnmTexArray( @, @, float3(@.xy, @.x), @, @.z * @ );\r\n",
inDet, normalMapArray, normalMapSampler, inDet, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend)); detCoord, normalMapArray, normalMapSampler, detCoord, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend));
} }
else else
{ {
meta->addStatement(new GenOp(" @.xy += parallaxOffsetTexArray( @, @, float3(@.xy, @.x), @, @.z * @ );\r\n", meta->addStatement(new GenOp(" @.xy += parallaxOffsetTexArray( @, @, float3(@.xy, @.x), @, @.z * @ );\r\n",
inDet, normalMapArray, normalMapSampler, inDet, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend)); detCoord, normalMapArray, normalMapSampler, detCoord, new IndexOp(detailInfo, detailIndex), negViewTS, new IndexOp(detailInfo, detailIndex), detailBlend));
} }
} }
@ -619,19 +619,18 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
{ {
meta->addStatement(new GenOp(" @ = ( lerp( @.Sample( @, float3(@.xy, @.x) ), lerp( @.Sample( @, float3(@.yz, @.x) ), @.Sample( @, float3(@.xz, @.x) ), @.z ), @.w) * 2.0 ) - 1.0;\r\n", meta->addStatement(new GenOp(" @ = ( lerp( @.Sample( @, float3(@.xy, @.x) ), lerp( @.Sample( @, float3(@.yz, @.x) ), @.Sample( @, float3(@.xz, @.x) ), @.z ), @.w) * 2.0 ) - 1.0;\r\n",
detailColor, detailColor,
detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detailMapSampler, detCoord, new IndexOp(detailInfo, detailIndex),
detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detailMapSampler, detCoord, new IndexOp(detailInfo, detailIndex),
detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detailMapSampler, detCoord, new IndexOp(detailInfo, detailIndex),
inTex, inTex)); inTexCoord, inTexCoord));
} }
else else
{ {
meta->addStatement(new GenOp(" @ = ( @.Sample( @, float3(@.xy, @.x) ) * 2.0 ) - 1.0;\r\n", meta->addStatement(new GenOp(" @ = ( @.Sample( @, float3(@.xy, @.x) ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex))); detailColor, detailMapArray, detailMapSampler, detCoord, new IndexOp(detailInfo, detailIndex)));
} }
meta->addStatement(new GenOp(" @ *= @.y * @.w;\r\n", meta->addStatement(new GenOp(" @ *= @.y * @;\r\n", detailColor, new IndexOp(detailInfo, detailIndex), detailBlend));
detailColor, new IndexOp(detailInfo, detailIndex), inDet));
if (!fd.features.hasFeature(MFT_TerrainNormalMap)) if (!fd.features.hasFeature(MFT_TerrainNormalMap))
{ {
@ -647,32 +646,14 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
{ {
Var* viewToTangent = getInViewToTangent(componentList); Var* viewToTangent = getInViewToTangent(componentList);
meta->addStatement(new GenOp(" @ = lerp( @, @[2], min( @, @.w ) );\r\n", meta->addStatement(new GenOp(" @ = lerp( @, @[2], @ );\r\n", gbNormal, gbNormal, viewToTangent, detailBlend));
gbNormal, gbNormal, viewToTangent, detailBlend, inDet));
} }
// If we're using SM 3.0 then take advantage of ShaderFeature::OutputTarget target = (fd.features[MFT_isDeferred]) ? RenderTarget1 : DefaultTarget;
// 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"));
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
if (fd.features.hasFeature(MFT_isDeferred))
target = ShaderFeature::RenderTarget1;
Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target)); Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target));
meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n", outColor, outColor)); meta->addStatement(new GenOp(" @ += @ * @;\r\n", outColor, detailColor, detailBlend));
meta->addStatement(new GenOp(" @ += @ * @;\r\n",
outColor, detailColor, detailBlend));
meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n", outColor, outColor));
meta->addStatement(new GenOp(" }\r\n"));
} }
output = meta; output = meta;
@ -769,7 +750,7 @@ void TerrainMacroMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentL
meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(macroScaleAndFade, detailIndex)) ); meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(macroScaleAndFade, detailIndex)) );
// And sneak the detail fade thru the w detailCoord. // And sneak the detail fade thru the w detailCoord.
meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", meta->addStatement( new GenOp( " @.w = ( @.z - @ ) * @.w;\r\n",
outTex, new IndexOp(macroScaleAndFade, detailIndex), dist, new IndexOp(macroScaleAndFade, detailIndex)) ); outTex, new IndexOp(macroScaleAndFade, detailIndex), dist, new IndexOp(macroScaleAndFade, detailIndex)) );
output = meta; output = meta;
@ -916,20 +897,13 @@ void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentL
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, new IndexOp(detailInfo, detailIndex), inDet ) ); detailColor, new IndexOp(detailInfo, detailIndex), inDet ) );
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget; ShaderFeature::OutputTarget target = (fd.features[MFT_isDeferred]) ? RenderTarget1 : DefaultTarget;
if (fd.features.hasFeature(MFT_isDeferred))
target= ShaderFeature::RenderTarget1;
Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) ); Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n", outColor, outColor));
meta->addStatement(new GenOp(" @ += @ * @;\r\n", meta->addStatement(new GenOp(" @ += @ * @;\r\n",
outColor, detailColor, detailBlend)); outColor, detailColor, detailBlend));
meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n", outColor, outColor));
meta->addStatement( new GenOp( " }\r\n" ) ); meta->addStatement( new GenOp( " }\r\n" ) );
output = meta; output = meta;
@ -1321,11 +1295,7 @@ void TerrainHeightMapBlendHLSL::processVert(Vector<ShaderComponent*>& componentL
void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentList, void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentList,
const MaterialFeatureData& fd) const MaterialFeatureData& fd)
{ {
ShaderFeature::OutputTarget target = (fd.features[MFT_isDeferred]) ? RenderTarget1 : DefaultTarget;
ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
if (fd.features.hasFeature(MFT_isDeferred))
target = ShaderFeature::RenderTarget1;
Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target)); Var* outColor = (Var*)LangElement::find(getOutputTargetVarName(target));
@ -1334,18 +1304,11 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
MultiLine* meta = new MultiLine; MultiLine* meta = new MultiLine;
Var* detailTot = (Var*)LangElement::find("detailTot");
if (detailTot == NULL)
{
detailTot = new Var("detailTot","float");
meta->addStatement(new GenOp("@=0;\r\n", new DecOp(detailTot)));
}
// Count number of detail layers // Count number of detail layers
int detailCount = 0; int detailCount = 0;
while (true) while (true)
{ {
if(LangElement::find(String::ToString("detailBlend%d", detailCount)) == NULL) if (LangElement::find(String::ToString("detailBlend%d", detailCount)) == NULL)
{ {
break; break;
} }
@ -1353,15 +1316,26 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
++detailCount; ++detailCount;
} }
if ( detailCount == 0 ) if (detailCount == 0)
{ {
return; return;
} }
Var* depth = (Var*)LangElement::find("baseBlendDepth");
if (depth == NULL)
{
depth = new Var;
depth->setType("float");
depth->setName("baseBlendDepth");
depth->uniform = true;
depth->constSortPos = cspPrimitive;
}
Var* heightRange = new Var("heightRange", "float2");
meta->addStatement(new GenOp(" @ = float2(2.0f,0);//x=min, y=max\r\n", new DecOp(heightRange)));
// Compute blend factors // Compute blend factors
for (S32 idx = 0; idx < detailCount; ++idx) for (S32 idx = 0; idx < detailCount; ++idx)
{ {
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx)); Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx));
Var* blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", idx)); Var* blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", idx));
if (!blendDepth) if (!blendDepth)
@ -1382,134 +1356,78 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
blendContrast->uniform = true; blendContrast->uniform = true;
blendContrast->constSortPos = cspPrimitive; blendContrast->constSortPos = cspPrimitive;
} }
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx)); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
if (!detailH) if (!detailH)
{ {
detailH = new Var; detailH = new Var;
detailH->setType("float"); detailH->setType("float");
detailH->setName(String::ToString("detailH%d", idx)); detailH->setName(String::ToString("detailH%d", idx));
meta->addStatement(new GenOp(" @ = 0;\r\n", meta->addStatement(new GenOp(" @ = @+@;\r\n", new DecOp(detailH), blendDepth, depth));
new DecOp(detailH)));
meta->addStatement(new GenOp(" if (@ > 0.0f) {\r\n", detailBlend));
if (bumpNormal != NULL) if (bumpNormal != NULL)
{ {
meta->addStatement(new GenOp(" @ = clamp(@.a + @, 0.0, 1.0);\r\n", meta->addStatement(new GenOp(" @ += @.a * @;\r\n", detailH, bumpNormal, blendContrast));
detailH, bumpNormal, blendDepth));
} }
else meta->addStatement(new GenOp(" @ *= @;\r\n", detailH, detailBlend));
{ meta->addStatement(new GenOp(" @ = float2(min(@.x,@),max(@.y,@));\r\n", heightRange, heightRange, detailH, heightRange, detailH));
meta->addStatement(new GenOp(" @ = clamp(@, 0.0, 1.0);\r\n",
detailH, blendDepth));
}
meta->addStatement(new GenOp(" @ = max((@ * 2.0f - 1.0f) * @, 0.0f);\r\n",
detailH, detailH, blendContrast));
meta->addStatement(new GenOp(" }\r\n"));
} }
} }
meta->addStatement(new GenOp("\r\n")); meta->addStatement(new GenOp("\r\n"));
if (detailCount > 1)
Var* depth = (Var*)LangElement::find("baseBlendDepth");
if (depth == NULL)
{ {
depth = new Var; for (S32 idx = 0; idx < detailCount; ++idx)
depth->setType("float");
depth->setName("baseBlendDepth");
depth->uniform = true;
depth->constSortPos = cspPrimitive;
}
Var* ma = (Var*)LangElement::find("ma");
if (ma == NULL)
{
ma = new Var;
ma->setType("float");
ma->setName("ma");
meta->addStatement(new GenOp(" @ = 0;\r\n",
new DecOp(ma)));
}
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
meta->addStatement(new GenOp(" @ = max(@, @ + @);\r\n",
ma, ma, detailH, detailBlend));
}
meta->addStatement(new GenOp(" @ -= @;\r\n",
ma, depth));
meta->addStatement(new GenOp("\r\n"));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
if (!detailB)
{ {
detailB = new Var; Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
detailB->setType("float"); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
detailB->setName(String::ToString("detailB%d", idx)); meta->addStatement(new GenOp(" @ = (@-@.x)/(@.y-@.x);\r\n", detailH, detailH, heightRange, heightRange, heightRange));
}
meta->addStatement(new GenOp(" @ = max(@ + @ - @, 0);\r\n", meta->addStatement(new GenOp("\r\n"));
new DecOp(detailB), detailH, detailBlend, ma)); }
else
{
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
meta->addStatement(new GenOp(" @ = 1.0;\r\n", detailH));
} }
meta->addStatement(new GenOp(" @ += @;\r\n", detailTot, detailB));
} }
meta->addStatement(new GenOp("\r\n")); meta->addStatement(new GenOp(" @.rgb += (", outColor));
// Compute albedo
meta->addStatement(new GenOp(" @.rgb = toGamma(@.rgb);\r\n",
outColor, outColor));
meta->addStatement(new GenOp(" @.rgb += (",
outColor));
for (S32 idx = 0; idx < detailCount; ++idx) for (S32 idx = 0; idx < detailCount; ++idx)
{ {
Var* detailColor = (Var*)LangElement::find(String::ToString("detailColor%d", idx)); Var* detailColor = (Var*)LangElement::find(String::ToString("detailColor%d", idx));
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx)); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx));
if (idx > 0) if (idx > 0)
{ {
meta->addStatement(new GenOp(" + ")); meta->addStatement(new GenOp(" + "));
} }
meta->addStatement(new GenOp("@.rgb * @", detailColor, detailB)); meta->addStatement(new GenOp("((@.rgb * @)*max(@.w,0))", detailColor, detailH, detCoord));
} }
meta->addStatement(new GenOp(") / @;\r\n", detailTot)); meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n",
outColor, outColor));
meta->addStatement(new GenOp("\r\n"));
// Compute ORM // Compute ORM
Var* ormOutput; Var* ormOutput;
OutputTarget targ = DefaultTarget;
if (fd.features[MFT_isDeferred]) if (fd.features[MFT_isDeferred])
{ {
targ = RenderTarget2; ormOutput = (Var*)LangElement::find(getOutputTargetVarName(RenderTarget2));
} }
ormOutput = (Var*)LangElement::find(getOutputTargetVarName(targ)); else
{
meta->addStatement(new GenOp(" @.gba = (", ormOutput = (Var*)LangElement::find("ORMConfig");
ormOutput)); }
meta->addStatement(new GenOp(" @.gba = (", ormOutput));
for (S32 idx = 0; idx < detailCount; ++idx) for (S32 idx = 0; idx < detailCount; ++idx)
{ {
Var* matinfoCol = (Var*)LangElement::find(String::ToString("matinfoCol%d", idx)); Var* matinfoCol = (Var*)LangElement::find(String::ToString("matinfoCol%d", idx));
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx)); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
if (idx > 0) if (idx > 0)
{ {
@ -1517,104 +1435,42 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
} }
if (matinfoCol) if (matinfoCol)
{ {
meta->addStatement(new GenOp("@ * @", matinfoCol, detailB)); meta->addStatement(new GenOp("(@ * @)", matinfoCol, detailH));
} }
else else
{ {
meta->addStatement(new GenOp("float3(1.0, 1.0, 0.0) * @", detailB)); meta->addStatement(new GenOp("(float3(1.0, 1.0, 0.0) * @)", detailH));
} }
} }
meta->addStatement(new GenOp(") / @;\r\n", detailTot)); meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp("\r\n")); // Compute normals
Var* viewToTangent = getInViewToTangent(componentList);
// Compute normal-specific blending factors Var* bumpSum = new Var("bumpNorm", "float3");
// LukasPJ: I'm not sure why this is necessary, it might not be.
Var* normalMa = (Var*)LangElement::find("normalMa");
if (normalMa == NULL)
{
normalMa = new Var;
normalMa->setType("float");
normalMa->setName("normalMa");
meta->addStatement(new GenOp(" @ = 0;\r\n",
new DecOp(normalMa)));
}
meta->addStatement(new GenOp(" @ = float3(0, 0, 1)", new DecOp(bumpSum)));
for (S32 idx = 0; idx < detailCount; ++idx) for (S32 idx = 0; idx < detailCount; ++idx)
{ {
Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx));
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx)); Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx)); Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx));
meta->addStatement(new GenOp(" @ = max(@, @ + min(@, @.w));\r\n",
normalMa, normalMa, detailH, detailBlend, detCoord));
}
meta->addStatement(new GenOp(" @ -= @;\r\n",
normalMa, depth));
meta->addStatement(new GenOp("\r\n"));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx)); Var* detCoord = (Var*)LangElement::find(String::ToString("detCoord%d", idx));
if (bumpNormal != NULL)
Var* detailH = (Var*)LangElement::find(String::ToString("detailH%d", idx));
Var* detailBlend = (Var*)LangElement::find(String::ToString("detailBlend%d", idx));
Var* normalDetailB = (Var*)LangElement::find(String::ToString("normalDetailB%d", idx));
if (!normalDetailB)
{ {
normalDetailB = new Var; meta->addStatement(new GenOp("+(@.xyz * @*max(@.w,0))", bumpNormal, detailH, detCoord));
normalDetailB->setType("float");
normalDetailB->setName(String::ToString("normalDetailB%d", idx));
meta->addStatement(new GenOp(" @ = max(@ + min(@, @.w) - @, 0);\r\n",
new DecOp(normalDetailB), detailH, detailBlend, detCoord, normalMa));
} }
}
// Compute normals }
meta->addStatement(new GenOp(";\r\n"));
Var* gbNormal = (Var*)LangElement::find("gbNormal"); Var* gbNormal = (Var*)LangElement::find("gbNormal");
if (!gbNormal) if (!gbNormal)
{ {
gbNormal = new Var; gbNormal = new Var("gbNormal","float3");
gbNormal->setName("gbNormal"); meta->addStatement(new GenOp(" @ = ", new DecOp(gbNormal)));
gbNormal->setType("float3");
meta->addStatement(new GenOp(" @;\r\n", new DecOp(gbNormal)));
} }
else
if (gbNormal != NULL) meta->addStatement(new GenOp(" @ = ", gbNormal));
{ meta->addStatement(new GenOp("mul(normalize(@),@);\r\n", bumpSum, viewToTangent));
meta->addStatement(new GenOp(" @ = (",
gbNormal));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* normalDetailB = (Var*)LangElement::find(String::ToString("normalDetailB%d", idx));
Var* bumpNormal = (Var*)LangElement::find(String::ToString("bumpNormal%d", idx));
Var* viewToTangent = getInViewToTangent(componentList);
if (idx > 0)
{
meta->addStatement(new GenOp(" + "));
}
if (bumpNormal != NULL)
{
meta->addStatement(new GenOp("mul(@.xyz, @) * @", bumpNormal, viewToTangent, normalDetailB));
}
else
{
meta->addStatement(new GenOp("@[2] * @", viewToTangent, normalDetailB));
}
}
meta->addStatement(new GenOp(") / @;\r\n", detailTot));
}
output = meta; output = meta;
} }

View file

@ -374,43 +374,36 @@ bool TerrainCellMaterial::_initShader(bool deferredMat,
// We only include materials that // We only include materials that
// have more than a base texture. // have more than a base texture.
if (mat->getDetailSize() <= 0 || if (!(mat->DetailMapValid() && mat->getDetailSize() > 0 && mat->getDetailDistance()>0))
mat->getDetailDistance() <= 0 ||
mat->getDetailMap() == StringTable->EmptyString())
continue; continue;
// check for macro detail texture
if (!(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap() == StringTable->EmptyString()))
{
if (deferredMat)
features.addFeature(MFT_isDeferred, featureIndex);
features.addFeature(MFT_TerrainMacroMap, featureIndex);
}
if (deferredMat) if (deferredMat)
features.addFeature(MFT_isDeferred, featureIndex); features.addFeature(MFT_isDeferred, featureIndex);
features.addFeature(MFT_TerrainDetailMap, featureIndex); features.addFeature(MFT_TerrainDetailMap, featureIndex);
if (deferredMat) // check for macro detail texture
if (mat->MacroMapValid() && mat->getMacroSize() > 0 && mat->getMacroDistance() > 0)
{ {
if (!(mat->getORMConfigMap() == StringTable->EmptyString())) features.addFeature(MFT_TerrainMacroMap, featureIndex);
{ }
features.addFeature(MFT_TerrainORMMap, featureIndex);
} if (mat->ORMConfigMapValid())
else {
{ features.addFeature(MFT_TerrainORMMap, featureIndex);
features.addFeature(MFT_DeferredTerrainBlankInfoMap, featureIndex); }
} else
{
features.addFeature(MFT_DeferredTerrainBlankInfoMap, featureIndex);
} }
if (mat->getInvertRoughness()) if (mat->getInvertRoughness())
features.addFeature(MFT_InvertRoughness, featureIndex); features.addFeature(MFT_InvertRoughness, featureIndex);
normalMaps.increment();
// Skip normal maps if we need to. // Skip normal maps if we need to.
if (!disableNormalMaps && mat->getNormalMap() != StringTable->EmptyString()) if (!disableNormalMaps && mat->NormalMapValid())
{ {
normalMaps.increment();
features.addFeature(MFT_TerrainNormalMap, featureIndex); features.addFeature(MFT_TerrainNormalMap, featureIndex);
normalMaps.last() = mat->getNormalMapResource(); normalMaps.last() = mat->getNormalMapResource();
@ -639,9 +632,7 @@ bool TerrainCellMaterial::_initShader(bool deferredMat,
// We only include materials that // We only include materials that
// have more than a base texture. // have more than a base texture.
if (mat->getDetailSize() <= 0 || if (!(mat->DetailMapValid() && mat->getDetailSize() > 0 && mat->getDetailDistance() > 0))
mat->getDetailDistance() <= 0 ||
mat->getDetailMap() == StringTable->EmptyString())
continue; continue;
mMaterialInfos[i]->mBlendDepthConst = mShader->getShaderConstHandle(avar("$blendDepth%d", i)); mMaterialInfos[i]->mBlendDepthConst = mShader->getShaderConstHandle(avar("$blendDepth%d", i));
@ -684,11 +675,7 @@ void TerrainCellMaterial::_updateMaterialConsts( )
if (mat == NULL) if (mat == NULL)
continue; continue;
// We only include materials that if (!(mat->DetailMapValid() && mat->getDetailSize() > 0 && mat->getDetailDistance() > 0))
// have more than a base texture.
if (mat->getDetailSize() <= 0 ||
mat->getDetailDistance() <= 0 ||
mat->getDetailMap() == StringTable->EmptyString())
continue; continue;
detailMatCount++; detailMatCount++;
@ -713,11 +700,7 @@ void TerrainCellMaterial::_updateMaterialConsts( )
if (mat == NULL) if (mat == NULL)
continue; continue;
// We only include materials that if (!(mat->DetailMapValid() && mat->getDetailSize() > 0 && mat->getDetailDistance() > 0))
// have more than a base texture.
if (mat->getDetailSize() <= 0 ||
mat->getDetailDistance() <= 0 ||
mat->getDetailMap() == StringTable->EmptyString())
continue; continue;
F32 detailSize = matInfo->mat->getDetailSize(); F32 detailSize = matInfo->mat->getDetailSize();