A clean implementation of Lukas' Fix side projection #684 PR with Az's addendum fix rolled in

This commit is contained in:
JeffR 2021-12-13 15:56:14 -06:00
parent 1f4c488640
commit 434c6c26fe
3 changed files with 147 additions and 359 deletions

View file

@ -223,29 +223,16 @@ void TerrainBaseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentLis
output = meta;
// Generate the incoming texture var.
Var *inTex;
{
Var *inPos = (Var*)LangElement::find( "inPosition" );
if ( !inPos )
inPos = (Var*)LangElement::find( "position" );
Var* inPos = (Var*)LangElement::find("inPosition");
if (!inPos)
inPos = (Var*)LangElement::find("position");
inTex = new Var( "texCoord", "vec3" );
Var* inTex = new Var("texCoord", "vec3");
Var *oneOverTerrainSize = _getUniformVar( "oneOverTerrainSize", "float", cspPass );
Var* oneOverTerrainSize = _getUniformVar("oneOverTerrainSize", "float", cspPass);
// NOTE: The y coord here should be negative to have
// the texture maps not end up flipped which also caused
// normal and parallax mapping to be incorrect.
//
// This mistake early in development means that the layer
// id bilinear blend depends on it being that way.
//
// So instead i fixed this by flipping the base and detail
// coord y scale to compensate when rendering.
//
meta->addStatement( new GenOp( " @ = @.xyz * vec3( @, @, -@ );\r\n",
new DecOp( inTex ), inPos, oneOverTerrainSize, oneOverTerrainSize, oneOverTerrainSize ) );
}
meta->addStatement(new GenOp(" @ = @.xyz * vec3( @, @, @ );\r\n",
new DecOp(inTex), inPos, oneOverTerrainSize, oneOverTerrainSize, oneOverTerrainSize));
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
@ -253,21 +240,27 @@ void TerrainBaseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentLis
Var *outTex = connectComp->getElement( RT_TEXCOORD );
outTex->setName( "outTexCoord" );
outTex->setStructName( "OUT" );
outTex->setType( "vec3" );
outTex->setType( "vec4" );
meta->addStatement( new GenOp( " @.xy = @.xy;\r\n", outTex, inTex ) );
// If this shader has a side projected layer then we
// pass the dot product between the +Y and the normal
// thru outTexCoord.z for use in blending the textures.
// thru outTexCoord.z and w for use in blending the textures.
if ( fd.features.hasFeature( MFT_TerrainSideProject ) )
{
Var *inNormal = (Var*)LangElement::find( "normal" );
Var* inNormal = (Var*)LangElement::find("normal");
meta->addStatement(
new GenOp(" @.z = clamp(abs( dot( normalize( vec3( @.x, @.y, 0 ) ), vec3( 0, 1, 0 ) ) ), 0.0, 1.0);\r\n",
outTex, inNormal, inNormal));
meta->addStatement(
new GenOp( " @.z = pow( abs( dot( normalize( vec3( @.x, @.y, 0 ) ), vec3( 0, 1, 0 ) ) ), 10.0 );\r\n",
outTex, inNormal, inNormal ) );
new GenOp(" @.w = 1.0 - abs( dot( normalize( @.xyz ), vec3( 0, 0, 1 ) ) );\r\n",
outTex, inNormal));
}
else
meta->addStatement( new GenOp( " @.z = 0;\r\n", outTex ) );
{
meta->addStatement(new GenOp(" @.z = 0;\r\n", outTex));
meta->addStatement(new GenOp(" @.w = 0;\r\n", outTex));
}
// HACK: This is sort of lazy... we generate the tanget
// vector here so that we're sure it exists in the parallax
@ -289,7 +282,7 @@ void TerrainBaseMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
const MaterialFeatureData &fd )
{
// grab connector texcoord register
Var *texCoord = getInTexCoord( "texCoord", "vec3", componentList );
Var *texCoord = getInTexCoord( "texCoord", "vec4", componentList );
// create texture var
Var *diffuseMap = new Var;
@ -446,8 +439,8 @@ void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &component
meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(detScaleAndFade, detailIndex) ) );
// And sneak the detail fade thru the w detailCoord.
meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)) );
meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)));
output = meta;
}
@ -562,8 +555,12 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
// amount so that it fades out with the layer blending.
if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
{
meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, new IndexOp(detailInfo, detailIndex), detailMap, inDet, new IndexOp(detailInfo, detailIndex), inTex));
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,
detailMap, inDet, new IndexOp(detailInfo, detailIndex),
detailMap, inDet, new IndexOp(detailInfo, detailIndex),
detailMap, inDet, new IndexOp(detailInfo, detailIndex),
inTex, inTex));
}
else
{
@ -574,7 +571,7 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
meta->addStatement(new GenOp(" @ *= @.y * @.w;\r\n",
detailColor, new IndexOp(detailInfo, detailIndex), inDet));
if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
if (!fd.features.hasFeature(MFT_TerrainNormalMap))
{
// Check to see if we have a gbuffer normal.
Var* gbNormal = (Var*)LangElement::find("gbNormal");
@ -834,8 +831,12 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
//
if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
{
meta->addStatement( new GenOp( " @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, vec3(@.xy, @.x) ), lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z ), @.w) * 2.0 ) - 1.0;\r\n",
detailColor,
detailMap, inDet, new IndexOp(detailInfo, detailIndex),
detailMap, inDet, new IndexOp(detailInfo, detailIndex),
detailMap, inDet, new IndexOp(detailInfo, detailIndex),
inTex, inTex));
}
else
{
@ -940,8 +941,11 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
LangElement *texOp;
if ( fd.features.hasFeature( MFT_TerrainSideProject, normalIndex ) )
{
texOp = new GenOp( "lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z )",
normalMap, inDet, new IndexOp(detailInfo, normalIndex), normalMap, inDet, inTex, new IndexOp(detailInfo, normalIndex));
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),
normalMap, inDet, new IndexOp(detailInfo, normalIndex),
normalMap, inDet, new IndexOp(detailInfo, normalIndex),
inTex, inTex);
}
else
texOp = new GenOp( String::ToString("tex2D(@, vec3(@.xy, @.x))", normalIndex), normalMap, inDet, new IndexOp(detailInfo, normalIndex));
@ -954,7 +958,7 @@ void TerrainNormalMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
LangElement *bumpNormDecl = new DecOp( bumpNorm );
meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
if (!fd.features.hasFeature(MFT_TerrainNormalMap))
{
Var* viewToTangent = getInViewToTangent(componentList);
@ -1059,100 +1063,22 @@ ShaderFeature::Resources TerrainLightMapFeatGLSL::getResources( const MaterialFe
return res;
}
//standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO),
//.b = specular strength, a= spec power.
void TerrainORMMapFeatGLSL::processVert(Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd)
{
const S32 detailIndex = getProcessIndex();
// We only need to process normals during the deferred.
if (!fd.features.hasFeature(MFT_DeferredConditioner))
return;
// Grab incoming texture coords... the base map feature
// made sure this was created.
Var *inTex = (Var*)LangElement::find("texCoord");
AssertFatal(inTex, "The texture coord is missing!");
MultiLine* meta = new MultiLine;
// Grab the input position.
Var *inPos = (Var*)LangElement::find("inPosition");
if (!inPos)
inPos = (Var*)LangElement::find("position");
// Get the object space eye position.
Var *eyePos = _getUniformVar("eyePos", "vec3", cspPotentialPrimitive);
MultiLine *meta = new MultiLine;
// If we have parallax mapping then make sure we've sent
// the negative view vector to the pixel shader.
if (fd.features.hasFeature(MFT_TerrainParallaxMap) &&
!LangElement::find("outNegViewTS"))
if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
{
// Get the object to tangent transform which
// will consume 3 output registers.
Var *objToTangentSpace = getOutObjToTangentSpace(componentList, meta, fd);
// Now use a single output register to send the negative
// view vector in tangent space to the pixel shader.
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
Var *outNegViewTS = connectComp->getElement(RT_TEXCOORD);
outNegViewTS->setName("outNegViewTS");
outNegViewTS->setStructName("OUT");
outNegViewTS->setType("vec3");
meta->addStatement(new GenOp(" @ = @ * vec3( @ - @.xyz );\r\n",
outNegViewTS, objToTangentSpace, eyePos, inPos));
// Make sure the world to tangent transform
// is created and available for the pixel shader.
getOutViewToTangent(componentList, meta, fd);
}
// Get the distance from the eye to this vertex.
Var *dist = (Var*)LangElement::find("dist");
if (!dist)
{
dist = new Var;
dist->setType("float");
dist->setName("dist");
meta->addStatement(new GenOp(" @ = distance( @.xyz, @ );\r\n",
new DecOp(dist), inPos, eyePos));
}
// grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
Var *outTex = (Var*)LangElement::find(String::ToString("detCoord%d", detailIndex));
if (outTex == NULL)
{
outTex = new Var;
outTex = connectComp->getElement(RT_TEXCOORD);
outTex->setName(String::ToString("detCoord%d", detailIndex));
outTex->setStructName("OUT");
outTex->setType("vec4");
}
// Get the detail scale and fade info.
Var *detScaleAndFade = (Var*)LangElement::find("detailScaleAndFade");
if (detScaleAndFade == NULL)
{
detScaleAndFade = new Var;
detScaleAndFade->setType("vec4");
detScaleAndFade->setName("detailScaleAndFade");
detScaleAndFade->uniform = true;
detScaleAndFade->constSortPos = cspPotentialPrimitive;
}
detScaleAndFade->arraySize = mMax(detScaleAndFade->arraySize, detailIndex + 1);
// Setup the detail coord.
//
// NOTE: You see here we scale the texture coord by 'xyx'
// to generate the detail coord. This y is here because
// its scale is flipped to correct for the non negative y
// in texCoord.
//
// See TerrainBaseMapFeatGLSL::processVert().
//
meta->addStatement(new GenOp(" @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(detScaleAndFade, detailIndex)));
// And sneak the detail fade thru the w detailCoord.
meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)));
output = meta;
}
@ -1180,8 +1106,11 @@ void TerrainORMMapFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
if (fd.features.hasFeature(MFT_TerrainSideProject, compositeIndex))
{
texOp = new GenOp("lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z )",
ormConfigMap, inDet, new IndexOp(detailInfo, compositeIndex), ormConfigMap, inDet, new IndexOp(detailInfo, compositeIndex), inTex);
texOp = new GenOp("lerp( tex2D( @, vec3(@.xy, @.x) ), lerp( tex2D( @, vec3(@.yz, @.x) ), tex2D( @, vec3(@.xz, @.x) ), @.z ), @.w )",
ormConfigMap, inDet, new IndexOp(detailInfo, compositeIndex),
ormConfigMap, inDet, new IndexOp(detailInfo, compositeIndex),
ormConfigMap, inDet, new IndexOp(detailInfo, compositeIndex),
inTex, inTex);
}
else
texOp = new GenOp("tex2D(@, vec3(@.xy, @.x))", ormConfigMap, inDet, new IndexOp(detailInfo, compositeIndex));
@ -1332,6 +1261,13 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
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 the number of detail textures
int detailCount = 0;
while (true)
@ -1391,11 +1327,11 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
}
else
{
meta->addStatement(new GenOp(" @ = clamp(0.5 + @, 0.0, 1.0);\r\n",
meta->addStatement(new GenOp(" @ = clamp(@, 0.0, 1.0);\r\n",
detailH, blendDepth));
}
meta->addStatement(new GenOp(" @ = max((@ * 2.0f - 1.0f) * @ + 0.5f, 0.0f);\r\n",
meta->addStatement(new GenOp(" @ = max((@ * 2.0f - 1.0f) * @, 0.0f);\r\n",
detailH, detailH, blendContrast));
meta->addStatement(new GenOp(" }\r\n"));
@ -1453,6 +1389,7 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
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"));
@ -1478,22 +1415,7 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
meta->addStatement(new GenOp("@.rgb * @", detailColor, detailB));
}
meta->addStatement(new GenOp(") / ("));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
if (idx > 0)
{
meta->addStatement(new GenOp(" + "));
}
meta->addStatement(new GenOp("@", detailB));
}
meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp(") / @;\r\n", detailTot));
meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n",
outColor, outColor));
@ -1532,23 +1454,7 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
}
}
meta->addStatement(new GenOp(") / ("));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
if (idx > 0)
{
meta->addStatement(new GenOp(" + "));
}
meta->addStatement(new GenOp("@", detailB));
}
meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp(") / @;\r\n", detailTot));
meta->addStatement(new GenOp("\r\n"));
@ -1635,22 +1541,7 @@ void TerrainHeightMapBlendGLSL::processPix(Vector<ShaderComponent*>& componentLi
}
}
meta->addStatement(new GenOp(") / ("));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* normalDetailB = (Var*)LangElement::find(String::ToString("normalDetailB%d", idx));
if (idx > 0)
{
meta->addStatement(new GenOp(" + "));
}
meta->addStatement(new GenOp("@", normalDetailB));
}
meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp(") / @;\r\n", detailTot));
}

View file

@ -270,58 +270,52 @@ Var* TerrainFeatHLSL::_getMacroIdStrengthParallax()
}
void TerrainBaseMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
void TerrainBaseMapFeatHLSL::processVert(Vector<ShaderComponent*>& componentList,
const MaterialFeatureData& fd)
{
MultiLine *meta = new MultiLine;
MultiLine* meta = new MultiLine;
output = meta;
// Generate the incoming texture var.
Var *inTex;
{
Var *inPos = (Var*)LangElement::find( "inPosition" );
if ( !inPos )
inPos = (Var*)LangElement::find( "position" );
inTex = new Var( "texCoord", "float3" );
Var* inPos = (Var*)LangElement::find("inPosition");
if (!inPos)
inPos = (Var*)LangElement::find("position");
Var *oneOverTerrainSize = _getUniformVar( "oneOverTerrainSize", "float", cspPass );
Var* inTex = new Var("texCoord", "float3");
// NOTE: The y coord here should be negative to have
// the texture maps not end up flipped which also caused
// normal and parallax mapping to be incorrect.
//
// This mistake early in development means that the layer
// id bilinear blend depends on it being that way.
//
// So instead i fixed this by flipping the base and detail
// coord y scale to compensate when rendering.
//
meta->addStatement( new GenOp( " @ = @.xyz * float3( @, @, -@ );\r\n",
new DecOp( inTex ), inPos, oneOverTerrainSize, oneOverTerrainSize, oneOverTerrainSize ) );
}
Var* oneOverTerrainSize = _getUniformVar("oneOverTerrainSize", "float", cspPass);
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
meta->addStatement(new GenOp(" @ = @.xyz * @;\r\n",
new DecOp(inTex), inPos, oneOverTerrainSize));
ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(componentList[C_CONNECTOR]);
// Pass the texture coord to the pixel shader.
Var *outTex = connectComp->getElement( RT_TEXCOORD );
outTex->setName( "outTexCoord" );
outTex->setStructName( "OUT" );
outTex->setType( "float3" );
meta->addStatement( new GenOp( " @.xy = @.xy;\r\n", outTex, inTex ) );
Var* outTex = connectComp->getElement(RT_TEXCOORD);
outTex->setName("outTexCoord");
outTex->setStructName("OUT");
outTex->setType("float4");
meta->addStatement(new GenOp(" @.xy = @.xy;\r\n", outTex, inTex));
// If this shader has a side projected layer then we
// pass the dot product between the +Y and the normal
// thru outTexCoord.z for use in blending the textures.
if ( fd.features.hasFeature( MFT_TerrainSideProject ) )
if (fd.features.hasFeature(MFT_TerrainSideProject))
{
Var *inNormal = (Var*)LangElement::find( "normal" );
Var* inNormal = (Var*)LangElement::find("normal");
meta->addStatement(
new GenOp( " @.z = pow( abs( dot( normalize( float3( @.x, @.y, 0 ) ), float3( 0, 1, 0 ) ) ), 10.0 );\r\n",
outTex, inNormal, inNormal ) );
new GenOp(" @.z = clamp(abs( dot( normalize( float3( @.x, @.y, 0 ) ), float3( 0, 1, 0 ) ) ), 0.0, 1.0);\r\n",
outTex, inNormal, inNormal));
meta->addStatement(
new GenOp(" @.w = 1.0 - abs( dot( normalize( @.xyz ), float3( 0, 0, 1 ) ) );\r\n",
outTex, inNormal));
}
else
meta->addStatement( new GenOp( " @.z = 0;\r\n", outTex ) );
{
meta->addStatement(new GenOp(" @.z = 0;\r\n", outTex));
meta->addStatement(new GenOp(" @.w = 0;\r\n", outTex));
}
// HACK: This is sort of lazy... we generate the tanget
// vector here so that we're sure it exists in the parallax
@ -341,7 +335,7 @@ void TerrainBaseMapFeatHLSL::processPix(Vector<ShaderComponent*>& componentList,
const MaterialFeatureData& fd)
{
// grab connector texcoord register
Var* texCoord = getInTexCoord("texCoord", "float3", componentList);
Var *texCoord = getInTexCoord( "texCoord", "float4", componentList );
// create texture var
Var* diffuseMap = new Var;
@ -501,8 +495,8 @@ void TerrainDetailMapFeatHLSL::processVert( Vector<ShaderComponent*> &component
meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(detScaleAndFade, detailIndex) ) );
// And sneak the detail fade thru the w detailCoord.
meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)) );
meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)));
output = meta;
}
@ -623,8 +617,12 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
{
meta->addStatement(new GenOp(" @ = ( lerp( @.Sample( @, float3(@.yz, @.x) ), @.Sample( @, float3(@.xz, @.x) ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex), inTex));
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,
detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex),
detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex),
detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex),
inTex, inTex));
}
else
{
@ -635,7 +633,7 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
meta->addStatement(new GenOp(" @ *= @.y * @.w;\r\n",
detailColor, new IndexOp(detailInfo, detailIndex), inDet));
if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
if (!fd.features.hasFeature(MFT_TerrainNormalMap))
{
// Check to see if we have a gbuffer normal.
Var* gbNormal = (Var*)LangElement::find("gbNormal");
@ -902,8 +900,12 @@ void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentL
//
if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
{
meta->addStatement(new GenOp(" @ = ( lerp( @.Sample( @, float3(@.yz, @.x) ), @.Sample( @, float3(@.xz, @.x) ), @.z ) * 2.0 ) - 1.0;\r\n",
detailColor, detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex), detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex), inTex));
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,
detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex),
detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex),
detailMapArray, detailMapSampler, inDet, new IndexOp(detailInfo, detailIndex),
inTex, inTex));
}
else
{
@ -1007,8 +1009,11 @@ void TerrainNormalMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
if (fd.features.hasFeature(MFT_TerrainSideProject, normalIndex))
{
texOp = new GenOp("lerp( @.Sample( @, float3(@.yz, @.x) ), @.Sample( @, float3(@.xz, @.x) ), @.z )",
normalMapArray, normalMapSampler, inDet, new IndexOp(detailInfo, normalIndex), normalMapArray, normalMapSampler, inDet, new IndexOp(detailInfo, normalIndex), inTex);
texOp = new GenOp("lerp( @.Sample( @, float3(@.xy, @.x) ), lerp( @.Sample( @, float3(@.yz, @.x) ), @.Sample( @, float3(@.xz, @.x) ), @.z ), @.w )",
normalMapArray, normalMapSampler, inDet, new IndexOp(detailInfo, normalIndex),
normalMapArray, normalMapSampler, inDet, new IndexOp(detailInfo, normalIndex),
normalMapArray, normalMapSampler, inDet, new IndexOp(detailInfo, normalIndex),
inTex, inTex);
}
else
texOp = new GenOp("@.Sample(@, float3(@.xy, @.x))", normalMapArray, normalMapSampler, inDet, new IndexOp(detailInfo, normalIndex));
@ -1021,7 +1026,7 @@ void TerrainNormalMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
LangElement* bumpNormDecl = new DecOp(bumpNorm);
meta->addStatement(expandNormalMap(texOp, bumpNormDecl, bumpNorm, fd));
if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
if (!fd.features.hasFeature(MFT_TerrainNormalMap))
{
Var* viewToTangent = getInViewToTangent(componentList);
@ -1131,98 +1136,22 @@ ShaderFeature::Resources TerrainLightMapFeatHLSL::getResources( const MaterialFe
return res;
}
//standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO),
//.b = specular strength, a= spec power.
void TerrainORMMapFeatHLSL::processVert(Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd)
{
const S32 detailIndex = getProcessIndex();
// We only need to process normals during the deferred.
if (!fd.features.hasFeature(MFT_DeferredConditioner))
return;
// Grab incoming texture coords... the base map feature
// made sure this was created.
Var *inTex = (Var*)LangElement::find("texCoord");
AssertFatal(inTex, "The texture coord is missing!");
MultiLine* meta = new MultiLine;
// Grab the input position.
Var *inPos = (Var*)LangElement::find("inPosition");
if (!inPos)
inPos = (Var*)LangElement::find("position");
// Get the object space eye position.
Var *eyePos = _getUniformVar("eyePos", "float3", cspPotentialPrimitive);
MultiLine *meta = new MultiLine;
// If we have parallax mapping then make sure we've sent
// the negative view vector to the pixel shader.
if (fd.features.hasFeature(MFT_TerrainParallaxMap) &&
!LangElement::find("outNegViewTS"))
if (!fd.features.hasFeature(MFT_TerrainHeightBlend))
{
// Get the object to tangent transform which
// will consume 3 output registers.
Var *objToTangentSpace = getOutObjToTangentSpace(componentList, meta, fd);
// Now use a single output register to send the negative
// view vector in tangent space to the pixel shader.
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
Var *outNegViewTS = connectComp->getElement(RT_TEXCOORD);
outNegViewTS->setName("outNegViewTS");
outNegViewTS->setStructName("OUT");
outNegViewTS->setType("float3");
meta->addStatement(new GenOp(" @ = mul( @, float3( @ - @.xyz ) );\r\n",
outNegViewTS, objToTangentSpace, eyePos, inPos));
// Make sure the world to tangent transform
// is created and available for the pixel shader.
getOutViewToTangent(componentList, meta, fd);
}
// Get the distance from the eye to this vertex.
Var *dist = (Var*)LangElement::find("dist");
if (!dist)
{
dist = new Var;
dist->setType("float");
dist->setName("dist");
meta->addStatement(new GenOp(" @ = distance( @.xyz, @ );\r\n",
new DecOp(dist), inPos, eyePos));
}
// grab connector texcoord register
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
Var *outTex = (Var*)LangElement::find(String::ToString("detCoord%d", detailIndex));
if (outTex == NULL)
{
outTex = connectComp->getElement(RT_TEXCOORD);
outTex->setName(String::ToString("detCoord%d", detailIndex));
outTex->setStructName("OUT");
outTex->setType("float4");
}
// Get the detail scale and fade info.
Var *detScaleAndFade = (Var*)LangElement::find("detailScaleAndFade");
if (detScaleAndFade == NULL)
{
detScaleAndFade = new Var;
detScaleAndFade->setType("float4");
detScaleAndFade->setName("detailScaleAndFade");
detScaleAndFade->uniform = true;
detScaleAndFade->constSortPos = cspPotentialPrimitive;
}
detScaleAndFade->arraySize = mMax(detScaleAndFade->arraySize, detailIndex + 1);
// Setup the detail coord.
//
// NOTE: You see here we scale the texture coord by 'xyx'
// to generate the detail coord. This y is here because
// its scale is flipped to correct for the non negative y
// in texCoord.
//
// See TerrainBaseMapFeatHLSL::processVert().
//
meta->addStatement(new GenOp(" @.xyz = @ * @.xyx;\r\n", outTex, inTex, new IndexOp(detScaleAndFade, detailIndex)));
// And sneak the detail fade thru the w detailCoord.
meta->addStatement(new GenOp(" @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n",
outTex, new IndexOp(detScaleAndFade, detailIndex), dist, new IndexOp(detScaleAndFade, detailIndex)));
output = meta;
}
@ -1251,8 +1180,11 @@ void TerrainORMMapFeatHLSL::processPix(Vector<ShaderComponent*> &componentList,
Var* ormMapSampler = _getOrmMapSampler();
if (fd.features.hasFeature(MFT_TerrainSideProject, compositeIndex))
{
texOp = new GenOp("lerp( @.Sample( @, float3(@.yz, @.x) ), @.Sample( @, float3(@.xz, @.x) ), @.z )",
ormMapArray, ormMapSampler, inDet, new IndexOp(detailInfo, compositeIndex), ormMapArray, ormMapSampler, inDet, new IndexOp(detailInfo, compositeIndex), inTex);
texOp = new GenOp("lerp( @.Sample( @, float3(@.xy, @.x) ), lerp( @.Sample( @, float3(@.yz, @.x) ), @.Sample( @, float3(@.xz, @.x) ), @.z ), @.w )",
ormMapArray, ormMapSampler, inDet, new IndexOp(detailInfo, compositeIndex),
ormMapArray, ormMapSampler, inDet, new IndexOp(detailInfo, compositeIndex),
ormMapArray, ormMapSampler, inDet, new IndexOp(detailInfo, compositeIndex),
inTex, inTex);
}
else
texOp = new GenOp("@.Sample(@, float3(@.xy, @.x))", ormMapArray, ormMapSampler, inDet, new IndexOp(detailInfo, compositeIndex));
@ -1402,6 +1334,13 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
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
int detailCount = 0;
while (true)
@ -1461,11 +1400,11 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
}
else
{
meta->addStatement(new GenOp(" @ = clamp(0.5 + @, 0.0, 1.0);\r\n",
meta->addStatement(new GenOp(" @ = clamp(@, 0.0, 1.0);\r\n",
detailH, blendDepth));
}
meta->addStatement(new GenOp(" @ = max((@ * 2.0f - 1.0f) * @ + 0.5f, 0.0f);\r\n",
meta->addStatement(new GenOp(" @ = max((@ * 2.0f - 1.0f) * @, 0.0f);\r\n",
detailH, detailH, blendContrast));
meta->addStatement(new GenOp(" }\r\n"));
@ -1522,6 +1461,7 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
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"));
@ -1547,23 +1487,7 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
meta->addStatement(new GenOp("@.rgb * @", detailColor, detailB));
}
meta->addStatement(new GenOp(") / ("));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
if (idx > 0)
{
meta->addStatement(new GenOp(" + "));
}
meta->addStatement(new GenOp("@", detailB));
}
meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp(") / @;\r\n", detailTot));
meta->addStatement(new GenOp(" @.rgb = toLinear(clamp(@.rgb, 0, 1));\r\n",
outColor, outColor));
@ -1601,23 +1525,7 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
}
}
meta->addStatement(new GenOp(") / ("));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* detailB = (Var*)LangElement::find(String::ToString("detailB%d", idx));
if (idx > 0)
{
meta->addStatement(new GenOp(" + "));
}
meta->addStatement(new GenOp("@", detailB));
}
meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp(") / @;\r\n", detailTot));
meta->addStatement(new GenOp("\r\n"));
@ -1704,22 +1612,7 @@ void TerrainHeightMapBlendHLSL::processPix(Vector<ShaderComponent*>& componentLi
}
}
meta->addStatement(new GenOp(") / ("));
for (S32 idx = 0; idx < detailCount; ++idx)
{
Var* normalDetailB = (Var*)LangElement::find(String::ToString("normalDetailB%d", idx));
if (idx > 0)
{
meta->addStatement(new GenOp(" + "));
}
meta->addStatement(new GenOp("@", normalDetailB));
}
meta->addStatement(new GenOp(");\r\n"));
meta->addStatement(new GenOp(") / @;\r\n", detailTot));
}

View file

@ -26,6 +26,10 @@
#include "gfx/gfxTextureManager.h"
#include "gfx/bitmap/gBitmap.h"
#ifdef TORQUE_TOOLS
#include "console\persistenceManager.h"
#endif
#include <string>