mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 15:44:36 +00:00
vertex position node
Cross api support for vertex positions matrixmultiplyop added for multiplying matrix with other types automatically expands or shortens vec types to suit the matrix Added identity to the matrix initialization op.
This commit is contained in:
parent
cff7a8060d
commit
a92ea1ffab
5 changed files with 418 additions and 56 deletions
|
|
@ -15,11 +15,13 @@
|
||||||
#include "materials/materialFeatureTypes.h"
|
#include "materials/materialFeatureTypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
ImplementFeatureType(SNF_VertexPosition, U32(-1), -1, false);
|
||||||
ImplementFeatureType(SNF_DefaultTexCoord, U32(-1), -1, false);
|
ImplementFeatureType(SNF_DefaultTexCoord, U32(-1), -1, false);
|
||||||
ImplementFeatureType(SNF_TextureFeature, U32(-1), -1, false);
|
ImplementFeatureType(SNF_TextureFeature, U32(-1), -1, false);
|
||||||
ImplementFeatureType(SNF_NormalMapFeature, U32(-1), -1, false);
|
ImplementFeatureType(SNF_NormalMapFeature, U32(-1), -1, false);
|
||||||
|
|
||||||
ImplementEnumType(ShaderNodeFeature_enum, "Shader node features. Each of thes relates to a specific node for generating a shader.\n\n")
|
ImplementEnumType(ShaderNodeFeature_enum, "Shader node features. Each of thes relates to a specific node for generating a shader.\n\n")
|
||||||
|
{ ShaderNodeFeature_enum::eSNF_VertexPosition, "SNF_VertexPosition", "Setup vertex position." },
|
||||||
{ ShaderNodeFeature_enum::eSNF_DefaultTexCoord, "SNF_DefaultTexCoord", "Setup the default texcoord." },
|
{ ShaderNodeFeature_enum::eSNF_DefaultTexCoord, "SNF_DefaultTexCoord", "Setup the default texcoord." },
|
||||||
{ ShaderNodeFeature_enum::eSNF_TextureFeature, "SNF_TextureFeature", "Sample a Texture - Params: (string,string,GFXSamplerStateData,bool)." },
|
{ ShaderNodeFeature_enum::eSNF_TextureFeature, "SNF_TextureFeature", "Sample a Texture - Params: (string,string,GFXSamplerStateData,bool)." },
|
||||||
{ ShaderNodeFeature_enum::eSNF_NormalMapFeature,"SNF_NormalMapFeature", "Convert a texture to a normalmap - Params: (string,float,bool,bool)." },
|
{ ShaderNodeFeature_enum::eSNF_NormalMapFeature,"SNF_NormalMapFeature", "Convert a texture to a normalmap - Params: (string,float,bool,bool)." },
|
||||||
|
|
@ -29,6 +31,7 @@ namespace
|
||||||
{
|
{
|
||||||
void register_node_features(GFXAdapterType type)
|
void register_node_features(GFXAdapterType type)
|
||||||
{
|
{
|
||||||
|
FEATUREMGR->registerFeature(SNF_VertexPosition, new NodeVertexPositionFeature);
|
||||||
FEATUREMGR->registerFeature(SNF_DefaultTexCoord, new DefaultTexcoordFeature);
|
FEATUREMGR->registerFeature(SNF_DefaultTexCoord, new DefaultTexcoordFeature);
|
||||||
FEATUREMGR->registerFeature(SNF_TextureFeature, new TextureFeature, TextureFeature::createFunction);
|
FEATUREMGR->registerFeature(SNF_TextureFeature, new TextureFeature, TextureFeature::createFunction);
|
||||||
FEATUREMGR->registerFeature(SNF_NormalMapFeature, new NormalMapFeature, NormalMapFeature::createFunction);
|
FEATUREMGR->registerFeature(SNF_NormalMapFeature, new NormalMapFeature, NormalMapFeature::createFunction);
|
||||||
|
|
@ -51,6 +54,125 @@ MODULE_INIT
|
||||||
|
|
||||||
MODULE_END;
|
MODULE_END;
|
||||||
|
|
||||||
|
Var* ShaderFeatureNode::getObjTrans(Vector<ShaderComponent*>& componentList,
|
||||||
|
bool useInstancing,
|
||||||
|
MultiLine* meta)
|
||||||
|
{
|
||||||
|
Var* objTrans = (Var*)LangElement::find("objTrans");
|
||||||
|
if (objTrans)
|
||||||
|
return objTrans;
|
||||||
|
|
||||||
|
if (useInstancing)
|
||||||
|
{
|
||||||
|
ShaderConnector* vertStruct = dynamic_cast<ShaderConnector*>(componentList[C_VERT_STRUCT]);
|
||||||
|
Var* instObjTrans = vertStruct->getElement(RT_TEXCOORD, 4, 4);
|
||||||
|
instObjTrans->setStructName("IN");
|
||||||
|
instObjTrans->setName("inst_objectTrans");
|
||||||
|
|
||||||
|
mInstancingFormat->addElement("objTrans", GFXDeclType_Float4, instObjTrans->constNum + 0);
|
||||||
|
mInstancingFormat->addElement("objTrans", GFXDeclType_Float4, instObjTrans->constNum + 1);
|
||||||
|
mInstancingFormat->addElement("objTrans", GFXDeclType_Float4, instObjTrans->constNum + 2);
|
||||||
|
mInstancingFormat->addElement("objTrans", GFXDeclType_Float4, instObjTrans->constNum + 3);
|
||||||
|
|
||||||
|
objTrans = new Var;
|
||||||
|
objTrans->setType(GFXSCT_Float4x4);
|
||||||
|
objTrans->setName("objTrans");
|
||||||
|
|
||||||
|
Vector<LangElement*> matrixVars;
|
||||||
|
matrixVars.push_back(instObjTrans);
|
||||||
|
meta->addStatement(new GenOp(" @ = @;", new DecOp(objTrans), new MatrixInitializeOp(objTrans, matrixVars)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
objTrans = new Var;
|
||||||
|
objTrans->setType(GFXSCT_Float4x4);
|
||||||
|
objTrans->setName("objTrans");
|
||||||
|
objTrans->uniform = true;
|
||||||
|
objTrans->constSortPos = cspPrimitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
return objTrans;
|
||||||
|
}
|
||||||
|
|
||||||
|
Var* ShaderFeatureNode::getModelView( Vector<ShaderComponent*>& componentList,
|
||||||
|
bool useInstancing,
|
||||||
|
MultiLine* meta)
|
||||||
|
{
|
||||||
|
Var* modelview = (Var*)LangElement::find("modelview");
|
||||||
|
if (modelview)
|
||||||
|
return modelview;
|
||||||
|
|
||||||
|
if (useInstancing)
|
||||||
|
{
|
||||||
|
Var* objTrans = getObjTrans(componentList, useInstancing, meta);
|
||||||
|
|
||||||
|
Var* viewProj = (Var*)LangElement::find("viewProj");
|
||||||
|
if (!viewProj)
|
||||||
|
{
|
||||||
|
viewProj = new Var;
|
||||||
|
viewProj->setType(GFXSCT_Float4x4);
|
||||||
|
viewProj->setName("viewProj");
|
||||||
|
viewProj->uniform = true;
|
||||||
|
viewProj->constSortPos = cspPass;
|
||||||
|
}
|
||||||
|
|
||||||
|
modelview = new Var;
|
||||||
|
modelview->setType(GFXSCT_Float4x4);
|
||||||
|
modelview->setName("modelview");
|
||||||
|
meta->addStatement(new GenOp(" @ = @; // Instancing!\r\n", new DecOp(modelview), new MatrixMultiplyOp(viewProj, objTrans)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modelview = new Var;
|
||||||
|
modelview->setType(GFXSCT_Float4x4);
|
||||||
|
modelview->setName("modelview");
|
||||||
|
modelview->uniform = true;
|
||||||
|
modelview->constSortPos = cspPrimitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelview;
|
||||||
|
}
|
||||||
|
|
||||||
|
Var* ShaderFeatureNode::getWorldView( Vector<ShaderComponent*>& componentList,
|
||||||
|
bool useInstancing,
|
||||||
|
MultiLine* meta)
|
||||||
|
{
|
||||||
|
Var* worldView = (Var*)LangElement::find("worldViewOnly");
|
||||||
|
if (worldView)
|
||||||
|
return worldView;
|
||||||
|
|
||||||
|
if (useInstancing)
|
||||||
|
{
|
||||||
|
Var* objTrans = getObjTrans(componentList, useInstancing, meta);
|
||||||
|
|
||||||
|
Var* worldToCamera = (Var*)LangElement::find("worldToCamera");
|
||||||
|
if (!worldToCamera)
|
||||||
|
{
|
||||||
|
worldToCamera = new Var;
|
||||||
|
worldToCamera->setType(GFXSCT_Float4x4);
|
||||||
|
worldToCamera->setName("worldToCamera");
|
||||||
|
worldToCamera->uniform = true;
|
||||||
|
worldToCamera->constSortPos = cspPass;
|
||||||
|
}
|
||||||
|
|
||||||
|
worldView = new Var;
|
||||||
|
worldView->setType(GFXSCT_Float4x4);
|
||||||
|
worldView->setName("worldViewOnly");
|
||||||
|
|
||||||
|
meta->addStatement(new GenOp(" @ = @; // Instancing!\r\n", new DecOp(worldView), new MatrixMultiplyOp(worldToCamera, objTrans) ));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
worldView = new Var;
|
||||||
|
worldView->setType(GFXSCT_Float4x4);
|
||||||
|
worldView->setName("worldViewOnly");
|
||||||
|
worldView->uniform = true;
|
||||||
|
worldView->constSortPos = cspPrimitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
return worldView;
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderFeatureNode::setupTextureSample( const String& samplerName,
|
void ShaderFeatureNode::setupTextureSample( const String& samplerName,
|
||||||
GFXShaderConstType samplerType,
|
GFXShaderConstType samplerType,
|
||||||
Vector<ShaderComponent*>& componentList,
|
Vector<ShaderComponent*>& componentList,
|
||||||
|
|
@ -69,43 +191,7 @@ void ShaderFeatureNode::setupTextureSample( const String& samplerName,
|
||||||
|
|
||||||
|
|
||||||
Var* samplerVar = dynamic_cast<Var*>(LangElement::find(sampVarName));
|
Var* samplerVar = dynamic_cast<Var*>(LangElement::find(sampVarName));
|
||||||
Var* textureVar;
|
Var* textureVar = NULL;
|
||||||
|
|
||||||
if (!isGL) // HLSL requires both Texture + SamplerState
|
|
||||||
{
|
|
||||||
if (!samplerVar)
|
|
||||||
{
|
|
||||||
samplerVar = new Var;
|
|
||||||
samplerVar->setType(isComparison ? "SamplerComparisonState" : "SamplerState");
|
|
||||||
samplerVar->setName(sampVarName);
|
|
||||||
samplerVar->uniform = true;
|
|
||||||
samplerVar->sampler = true;
|
|
||||||
samplerVar->constNum = Var::getTexUnitNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
textureVar = dynamic_cast<Var*>(LangElement::find(texVarName));
|
|
||||||
if (!textureVar)
|
|
||||||
{
|
|
||||||
textureVar = new Var;
|
|
||||||
textureVar->setType(LangElement::samplerTypeToString(samplerType)); // Texture2D, TextureCube, etc.
|
|
||||||
textureVar->setName(texVarName);
|
|
||||||
textureVar->uniform = true;
|
|
||||||
textureVar->texture = true;
|
|
||||||
textureVar->constNum = samplerVar->constNum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!samplerVar)
|
|
||||||
{
|
|
||||||
samplerVar = new Var;
|
|
||||||
samplerVar->setType(LangElement::samplerTypeToString(samplerType));
|
|
||||||
samplerVar->setName(sampVarName);
|
|
||||||
samplerVar->uniform = true;
|
|
||||||
samplerVar->sampler = true;
|
|
||||||
samplerVar->constNum = Var::getTexUnitNum();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The sampled color variable (e.g. "samplerName_col") should always be new but just in case
|
// The sampled color variable (e.g. "samplerName_col") should always be new but just in case
|
||||||
Var* sampledColor = (Var*)LangElement::find(resultVarName);
|
Var* sampledColor = (Var*)LangElement::find(resultVarName);
|
||||||
|
|
@ -123,6 +209,16 @@ void ShaderFeatureNode::setupTextureSample( const String& samplerName,
|
||||||
if (isGL)
|
if (isGL)
|
||||||
{
|
{
|
||||||
// ---------------- GLSL Sampling ----------------
|
// ---------------- GLSL Sampling ----------------
|
||||||
|
if (!samplerVar)
|
||||||
|
{
|
||||||
|
samplerVar = new Var;
|
||||||
|
samplerVar->setType(LangElement::constTypeToString(samplerType, true));
|
||||||
|
samplerVar->setName(sampVarName);
|
||||||
|
samplerVar->uniform = true;
|
||||||
|
samplerVar->sampler = true;
|
||||||
|
samplerVar->constNum = Var::getTexUnitNum();
|
||||||
|
}
|
||||||
|
|
||||||
if (isComparison)
|
if (isComparison)
|
||||||
{
|
{
|
||||||
if (useGather)
|
if (useGather)
|
||||||
|
|
@ -149,6 +245,27 @@ void ShaderFeatureNode::setupTextureSample( const String& samplerName,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ---------------- HLSL Sampling ----------------
|
// ---------------- HLSL Sampling ----------------
|
||||||
|
if (!samplerVar)
|
||||||
|
{
|
||||||
|
samplerVar = new Var;
|
||||||
|
samplerVar->setType(isComparison ? "SamplerComparisonState" : "SamplerState");
|
||||||
|
samplerVar->setName(sampVarName);
|
||||||
|
samplerVar->uniform = true;
|
||||||
|
samplerVar->sampler = true;
|
||||||
|
samplerVar->constNum = Var::getTexUnitNum();
|
||||||
|
}
|
||||||
|
|
||||||
|
textureVar = dynamic_cast<Var*>(LangElement::find(texVarName));
|
||||||
|
if (!textureVar)
|
||||||
|
{
|
||||||
|
textureVar = new Var;
|
||||||
|
textureVar->setType(LangElement::constTypeToString(samplerType, true)); // Texture2D, TextureCube, etc.
|
||||||
|
textureVar->setName(texVarName);
|
||||||
|
textureVar->uniform = true;
|
||||||
|
textureVar->texture = true;
|
||||||
|
textureVar->constNum = samplerVar->constNum;
|
||||||
|
}
|
||||||
|
|
||||||
if (isComparison)
|
if (isComparison)
|
||||||
{
|
{
|
||||||
if (useGather)
|
if (useGather)
|
||||||
|
|
@ -192,8 +309,7 @@ Var* ShaderFeatureNode::getOutTexCoord(const char* name, GFXShaderConstType type
|
||||||
|
|
||||||
// Statement allows for casting of different types which
|
// Statement allows for casting of different types which
|
||||||
// eliminates vector truncation problems.
|
// eliminates vector truncation problems.
|
||||||
String statement = String::ToString(" @ = (%s)@;\r\n", type);
|
meta->addStatement(new GenOp(" @ = (@)@;\r\n", texCoord, new TypeOp(type), inTex));
|
||||||
meta->addStatement(new GenOp(statement, texCoord, inTex));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,6 +381,57 @@ LangElement* ShaderFeatureNode::assignColor(LangElement* elem, Material::BlendOp
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// Vertex position.
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
void NodeVertexPositionFeature::processVert(Vector<ShaderComponent*>& componentList, const MaterialFeatureData& fd)
|
||||||
|
{
|
||||||
|
// First check for an input position from a previous feature
|
||||||
|
// then look for the default vertex position.
|
||||||
|
Var* inPosition = (Var*)LangElement::find("inPosition");
|
||||||
|
if (!inPosition)
|
||||||
|
inPosition = (Var*)LangElement::find("position");
|
||||||
|
|
||||||
|
const bool glsl = (GFX->getAdapterType() == OpenGL);
|
||||||
|
|
||||||
|
// grab connector position
|
||||||
|
ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(componentList[C_CONNECTOR]);
|
||||||
|
Var* outPosition = connectComp->getElement( glsl ? RT_POSITION : RT_SVPOSITION);
|
||||||
|
|
||||||
|
if (glsl)
|
||||||
|
{
|
||||||
|
outPosition->setName("gl_Position");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outPosition->setName("hpos");
|
||||||
|
outPosition->setStructName("OUT");
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiLine* meta = new MultiLine;
|
||||||
|
|
||||||
|
Var* modelview = getModelView(componentList, fd.features[MFT_UseInstancing], meta);
|
||||||
|
|
||||||
|
meta->addStatement(new GenOp(" @ = @;\r\n", outPosition, new MatrixMultiplyOp( modelview, new CastOp(inPosition, GFXSCT_Float4, "x;y;z"))));
|
||||||
|
|
||||||
|
output = meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeVertexPositionFeature::processPix(Vector<ShaderComponent*>& componentList, const MaterialFeatureData& fd)
|
||||||
|
{
|
||||||
|
const bool glsl = (GFX->getAdapterType() == OpenGL);
|
||||||
|
|
||||||
|
if (!glsl)
|
||||||
|
{
|
||||||
|
// grab connector position
|
||||||
|
ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(componentList[C_CONNECTOR]);
|
||||||
|
Var* outPosition = connectComp->getElement(RT_SVPOSITION);
|
||||||
|
outPosition->setName("vpos");
|
||||||
|
outPosition->setStructName("IN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------
|
//--------------------------------------------------------
|
||||||
// Setup the default texcoord
|
// Setup the default texcoord
|
||||||
//--------------------------------------------------------
|
//--------------------------------------------------------
|
||||||
|
|
@ -352,10 +519,10 @@ void NormalMapFeature::processPix(Vector<ShaderComponent*>& componentList, const
|
||||||
meta->addStatement(expandNormalMap(sampledColor, tempNormDecl, tempNorm, fd));
|
meta->addStatement(expandNormalMap(sampledColor, tempNormDecl, tempNorm, fd));
|
||||||
|
|
||||||
meta->addStatement(
|
meta->addStatement(
|
||||||
new GenOp(" @.xy *= float2(@, @);\r\n", tempNorm, params->flipX ? -1.0f : 1.0f, params->flipY ? -1.0f : 1.0f));
|
new GenOp(" @.xy *= @(@, @);\r\n", tempNorm, new TypeOp(GFXSCT_Float2), params->flipX ? -1.0f : 1.0f, params->flipY ? -1.0f : 1.0f));
|
||||||
|
|
||||||
meta->addStatement(new GenOp(" @.xyz = normalize( float3( @.xy * @, @.z ) );\r\n",
|
meta->addStatement(new GenOp(" @.xyz = normalize( @( @.xy * @, @.z ) );\r\n",
|
||||||
tempNorm, tempNorm, params->strength, tempNorm));
|
tempNorm, new TypeOp(GFXSCT_Float3), tempNorm, params->strength, tempNorm));
|
||||||
|
|
||||||
// write back into our known variable.
|
// write back into our known variable.
|
||||||
meta->addStatement(new GenOp(" @ = @;\r\n", sampledColor, tempNorm));
|
meta->addStatement(new GenOp(" @ = @;\r\n", sampledColor, tempNorm));
|
||||||
|
|
@ -363,3 +530,4 @@ void NormalMapFeature::processPix(Vector<ShaderComponent*>& componentList, const
|
||||||
output = meta;
|
output = meta;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include "gfx/gfxAPI.h"
|
#include "gfx/gfxAPI.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DeclareFeatureType(SNF_VertexPosition);
|
||||||
DeclareFeatureType(SNF_DefaultTexCoord);
|
DeclareFeatureType(SNF_DefaultTexCoord);
|
||||||
DeclareFeatureType(SNF_TextureFeature);
|
DeclareFeatureType(SNF_TextureFeature);
|
||||||
DeclareFeatureType(SNF_NormalMapFeature);
|
DeclareFeatureType(SNF_NormalMapFeature);
|
||||||
|
|
@ -29,6 +30,7 @@ DeclareFeatureType(SNF_NormalMapFeature);
|
||||||
/// </summary>
|
/// </summary>
|
||||||
enum ShaderNodeFeature_enum
|
enum ShaderNodeFeature_enum
|
||||||
{
|
{
|
||||||
|
eSNF_VertexPosition,
|
||||||
eSNF_DefaultTexCoord,
|
eSNF_DefaultTexCoord,
|
||||||
eSNF_TextureFeature,
|
eSNF_TextureFeature,
|
||||||
eSNF_NormalMapFeature,
|
eSNF_NormalMapFeature,
|
||||||
|
|
@ -39,6 +41,18 @@ DefineEnumType(ShaderNodeFeature_enum);
|
||||||
class ShaderFeatureNode : public ShaderFeature
|
class ShaderFeatureNode : public ShaderFeature
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
///
|
||||||
|
Var* getObjTrans( Vector<ShaderComponent*>& componentList,
|
||||||
|
bool useInstancing,
|
||||||
|
MultiLine* meta);
|
||||||
|
|
||||||
|
Var* getModelView(Vector<ShaderComponent*>& componentList,
|
||||||
|
bool useInstancing,
|
||||||
|
MultiLine* meta);
|
||||||
|
|
||||||
|
Var* getWorldView(Vector<ShaderComponent*>& componentList, bool useInstancing, MultiLine* meta);
|
||||||
|
|
||||||
void setupTextureSample(const String& samplerName,
|
void setupTextureSample(const String& samplerName,
|
||||||
GFXShaderConstType samplerType,
|
GFXShaderConstType samplerType,
|
||||||
Vector<ShaderComponent*>& componentList,
|
Vector<ShaderComponent*>& componentList,
|
||||||
|
|
@ -58,6 +72,19 @@ public:
|
||||||
LangElement* assignColor(LangElement* elem, Material::BlendOp blend, LangElement* lerpElem = NULL, ShaderFeature::OutputTarget outputTarget = ShaderFeature::DefaultTarget) override;
|
LangElement* assignColor(LangElement* elem, Material::BlendOp blend, LangElement* lerpElem = NULL, ShaderFeature::OutputTarget outputTarget = ShaderFeature::DefaultTarget) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NodeVertexPositionFeature : public ShaderFeatureNode
|
||||||
|
{
|
||||||
|
void processVert(Vector<ShaderComponent*>& componentList,
|
||||||
|
const MaterialFeatureData& fd) override;
|
||||||
|
|
||||||
|
void processPix(Vector<ShaderComponent*>& componentList,
|
||||||
|
const MaterialFeatureData& fd) override;
|
||||||
|
|
||||||
|
String getName() override
|
||||||
|
{
|
||||||
|
return "NodeVertexPositionFeature";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class DefaultTexcoordFeature : public ShaderFeatureNode
|
class DefaultTexcoordFeature : public ShaderFeatureNode
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,73 @@ void ShaderFeature::addDependency( const ShaderDependency *dependsOn )
|
||||||
mDependencies.push_back( dependsOn );
|
mDependencies.push_back( dependsOn );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Var* ShaderFeature::getVertTexCoord(const String& name)
|
||||||
|
{
|
||||||
|
Var* inTex = NULL;
|
||||||
|
|
||||||
|
for (U32 i = 0; i < LangElement::elementList.size(); i++)
|
||||||
|
{
|
||||||
|
if (!String::compare((char*)LangElement::elementList[i]->name, name.c_str()))
|
||||||
|
{
|
||||||
|
inTex = dynamic_cast<Var*>(LangElement::elementList[i]);
|
||||||
|
if (inTex)
|
||||||
|
{
|
||||||
|
// NOTE: This used to do this check...
|
||||||
|
//
|
||||||
|
// String::compare( (char*)inTex->structName, "IN" )
|
||||||
|
//
|
||||||
|
// ... to ensure that the var was from the input
|
||||||
|
// vertex structure, but this kept some features
|
||||||
|
// ( ie. imposter vert ) from decoding their own
|
||||||
|
// coords for other features to use.
|
||||||
|
//
|
||||||
|
// If we run into issues with collisions between
|
||||||
|
// IN vars and local vars we may need to revise.
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inTex;
|
||||||
|
}
|
||||||
|
|
||||||
|
LangElement* ShaderFeature::expandNormalMap(LangElement* sampleNormalOp, LangElement* normalDecl, LangElement* normalVar, const MaterialFeatureData& fd)
|
||||||
|
{
|
||||||
|
MultiLine* meta = new MultiLine;
|
||||||
|
const bool hasBc3 = fd.features.hasFeature(MFT_IsBC3nm, getProcessIndex());
|
||||||
|
const bool hasBc5 = fd.features.hasFeature(MFT_IsBC5nm, getProcessIndex());
|
||||||
|
|
||||||
|
if (hasBc3 || hasBc5)
|
||||||
|
{
|
||||||
|
if (fd.features[MFT_ImposterVert])
|
||||||
|
{
|
||||||
|
// The imposter system uses object space normals and
|
||||||
|
// encodes them with the z axis in the alpha component.
|
||||||
|
meta->addStatement(new GenOp(" @ = @( normalize( @.xyw * 2.0 - 1.0 ), 0.0 ); // Obj DXTnm\r\n", normalDecl, new TypeOp(GFXSCT_Float4), sampleNormalOp));
|
||||||
|
}
|
||||||
|
else if (hasBc3)
|
||||||
|
{
|
||||||
|
// BC3 Swizzle trick
|
||||||
|
meta->addStatement(new GenOp(" @ = @( @.ag * 2.0 - 1.0, 0.0, 0.0 ); // DXTnm\r\n", normalDecl, new TypeOp(GFXSCT_Float4), sampleNormalOp));
|
||||||
|
meta->addStatement(new GenOp(" @.z = sqrt( 1.0 - dot( @.xy, @.xy ) ); // DXTnm\r\n", normalVar, normalVar, normalVar));
|
||||||
|
}
|
||||||
|
else if (hasBc5)
|
||||||
|
{
|
||||||
|
// BC5
|
||||||
|
meta->addStatement(new GenOp(" @ = @( @.gr * 2.0 - 1.0, 0.0, 0.0 ); // bc5nm\r\n", normalDecl, new TypeOp(GFXSCT_Float4), sampleNormalOp));
|
||||||
|
meta->addStatement(new GenOp(" @.z = sqrt( 1.0 - dot( @.xy, @.xy ) ); // bc5nm\r\n", normalVar, normalVar, normalVar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta->addStatement(new GenOp(" @ = @;\r\n", normalDecl, sampleNormalOp));
|
||||||
|
meta->addStatement(new GenOp(" @.xyz = @.xyz * 2.0 - 1.0;\r\n", normalVar, normalVar));
|
||||||
|
}
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
ShaderFeature::Resources ShaderFeature::getResources( const MaterialFeatureData &fd )
|
ShaderFeature::Resources ShaderFeature::getResources( const MaterialFeatureData &fd )
|
||||||
{
|
{
|
||||||
Resources temp;
|
Resources temp;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "shaderOp.h"
|
#include "shaderOp.h"
|
||||||
|
|
||||||
bool resolveSourceType(LangElement* elem, Var*& outVar, const ShaderTypeInfo*& outInfo)
|
bool ShaderOp::resolveSourceType(LangElement* elem, Var*& outVar, const ShaderTypeInfo*& outInfo)
|
||||||
{
|
{
|
||||||
outVar = nullptr;
|
outVar = nullptr;
|
||||||
outInfo = nullptr;
|
outInfo = nullptr;
|
||||||
|
|
@ -35,18 +35,18 @@ bool resolveSourceType(LangElement* elem, Var*& outVar, const ShaderTypeInfo*& o
|
||||||
if (Var* v = dynamic_cast<Var*>(elem))
|
if (Var* v = dynamic_cast<Var*>(elem))
|
||||||
{
|
{
|
||||||
outVar = v;
|
outVar = v;
|
||||||
outInfo = LangElement::getTypeInfo(LangElement::stringToConstType((const char*)v->type));
|
outInfo = getTypeInfo(stringToConstType((const char*)v->type));
|
||||||
return outInfo != nullptr;
|
return outInfo != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// INDEX OP: arrVar[index]
|
// INDEX OP: arrVar[index]
|
||||||
if (IndexOp* idx = dynamic_cast<IndexOp*>(elem))
|
if (IndexOp* idx = dynamic_cast<IndexOp*>(elem))
|
||||||
{
|
{
|
||||||
Var* arr = idx->arrVar;
|
Var* arr = dynamic_cast<Var*>(idx->mInput[0]);
|
||||||
if (!arr)
|
if (!arr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const ShaderTypeInfo* arrInfo = LangElement::getTypeInfo(LangElement::stringToConstType((const char*)arr->type));
|
const ShaderTypeInfo* arrInfo = getTypeInfo(stringToConstType((const char*)arr->type));
|
||||||
if (!arrInfo)
|
if (!arrInfo)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -56,10 +56,23 @@ bool resolveSourceType(LangElement* elem, Var*& outVar, const ShaderTypeInfo*& o
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CastOp* cast = dynamic_cast<CastOp*>(elem))
|
||||||
|
{
|
||||||
|
Var* castVar = dynamic_cast<Var*>(cast->mInput[0]);
|
||||||
|
if (!castVar)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const ShaderTypeInfo* castInfo = getTypeInfo(cast->mTargetType);// get the casts target type.
|
||||||
|
if (!castInfo)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
outVar = castVar;
|
||||||
|
outInfo = castInfo;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// Shader Operations
|
// Shader Operations
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
@ -117,9 +130,8 @@ void EchoOp::print( Stream &stream )
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// Index operation
|
// Index operation
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
IndexOp::IndexOp( Var* var, U32 index ) : Parent( NULL, NULL )
|
IndexOp::IndexOp( Var* var, U32 index ) : Parent(var, NULL )
|
||||||
{
|
{
|
||||||
arrVar = var; // need to keep hold of it for casts.
|
|
||||||
mInput[0] = var;
|
mInput[0] = var;
|
||||||
mIndex = index;
|
mIndex = index;
|
||||||
}
|
}
|
||||||
|
|
@ -266,13 +278,13 @@ void CastOp::print(Stream& stream)
|
||||||
const ShaderTypeInfo* dstInfo = getTypeInfo(mTargetType);
|
const ShaderTypeInfo* dstInfo = getTypeInfo(mTargetType);
|
||||||
|
|
||||||
// no info? types match? nothing to do.
|
// no info? types match? nothing to do.
|
||||||
if (!srcInfo || !dstInfo || (srcInfo->type == dstInfo->type))
|
if (!srcInfo || !dstInfo)
|
||||||
{
|
{
|
||||||
srcElem->print(stream); // print something....
|
srcElem->print(stream); // print something....
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool glsl = (GFX->getAdapterType() == OpenGL);
|
const bool glsl = (GFX->getAdapterType() == OpenGL);
|
||||||
const char* dstName = glsl ? dstInfo->glslName : dstInfo->hlslName;
|
const char* dstName = glsl ? dstInfo->glslName : dstInfo->hlslName;
|
||||||
|
|
||||||
U32 srcSize = srcInfo->cols;
|
U32 srcSize = srcInfo->cols;
|
||||||
|
|
@ -322,7 +334,7 @@ void CastOp::print(Stream& stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
// vector -> vector widening
|
// vector -> vector widening
|
||||||
if (srcSize < dstSize)
|
if (srcSize <= dstSize)
|
||||||
{
|
{
|
||||||
WRITESTR(dstName);
|
WRITESTR(dstName);
|
||||||
WRITESTR("(");
|
WRITESTR("(");
|
||||||
|
|
@ -452,7 +464,18 @@ void MatrixInitializeOp::print(Stream& stream)
|
||||||
// If not enough elements → pad with zeros
|
// If not enough elements → pad with zeros
|
||||||
while (count < matSize)
|
while (count < matSize)
|
||||||
{
|
{
|
||||||
WRITESTR("0");
|
U32 row = count / cols;
|
||||||
|
U32 col = count % cols;
|
||||||
|
|
||||||
|
if (row == col)
|
||||||
|
{
|
||||||
|
WRITESTR("1");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WRITESTR("0");
|
||||||
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (count < matSize)
|
if (count < matSize)
|
||||||
|
|
@ -472,3 +495,71 @@ void MatrixInitializeOp::print(Stream& stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MatrixMultiplyOp::MatrixMultiplyOp(LangElement* left, LangElement* right) : Parent(left, right)
|
||||||
|
{
|
||||||
|
mInput[0] = left;
|
||||||
|
mInput[1] = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixMultiplyOp::print(Stream& stream)
|
||||||
|
{
|
||||||
|
LangElement* leftElem = mInput[0];
|
||||||
|
Var* leftVar = nullptr;
|
||||||
|
const ShaderTypeInfo* leftInfo = nullptr;
|
||||||
|
|
||||||
|
if (!resolveSourceType(leftElem, leftVar, leftInfo))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LangElement* rightElem = mInput[0];
|
||||||
|
Var* rightVar = nullptr;
|
||||||
|
const ShaderTypeInfo* rightInfo = nullptr;
|
||||||
|
|
||||||
|
if (!resolveSourceType(rightElem, rightVar, rightInfo))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftInfo->isMatrix() && rightInfo->isVector())
|
||||||
|
{
|
||||||
|
if (rightInfo->cols != leftInfo->cols)
|
||||||
|
{
|
||||||
|
rightElem = new CastOp(rightVar, (GFXShaderConstType)(GFXSCT_Float + (leftInfo->cols - 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftInfo->isVector() && rightInfo->isMatrix())
|
||||||
|
{
|
||||||
|
if (rightInfo->cols != leftInfo->cols)
|
||||||
|
{
|
||||||
|
leftElem = new CastOp(leftVar, (GFXShaderConstType)(GFXSCT_Float + (rightInfo->cols - 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (leftInfo->isMatrix() && rightInfo->isMatrix())
|
||||||
|
{
|
||||||
|
if (leftInfo->cols != rightInfo->rows)
|
||||||
|
Con::warnf("MatrixMultiplyOp: incompatible matrices: (%dx%d) × (%dx%d)",
|
||||||
|
leftInfo->rows, leftInfo->cols,
|
||||||
|
rightInfo->rows, rightInfo->cols);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool glsl = (GFX->getAdapterType() == OpenGL);
|
||||||
|
|
||||||
|
if (!glsl)
|
||||||
|
{
|
||||||
|
WRITESTR("mul(");
|
||||||
|
leftElem->print(stream);
|
||||||
|
WRITESTR(", ");
|
||||||
|
rightElem->print(stream);
|
||||||
|
WRITESTR(")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leftElem->print(stream);
|
||||||
|
WRITESTR(" * ");
|
||||||
|
rightElem->print(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
*/
|
*/
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
bool resolveSourceType(LangElement* elem, Var*& outVar, const ShaderTypeInfo*& outInfo);
|
|
||||||
|
|
||||||
///**************************************************************************
|
///**************************************************************************
|
||||||
/// Shader operation base class
|
/// Shader operation base class
|
||||||
|
|
@ -56,6 +56,7 @@ protected:
|
||||||
LangElement * mInput[2];
|
LangElement * mInput[2];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool resolveSourceType(LangElement* elem, Var*& outVar, const ShaderTypeInfo*& outInfo);
|
||||||
ShaderOp( LangElement *in1, LangElement *in2 );
|
ShaderOp( LangElement *in1, LangElement *in2 );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -118,7 +119,6 @@ class IndexOp : public ShaderOp
|
||||||
typedef ShaderOp Parent;
|
typedef ShaderOp Parent;
|
||||||
U32 mIndex;
|
U32 mIndex;
|
||||||
public:
|
public:
|
||||||
Var* arrVar;
|
|
||||||
IndexOp( Var* var, U32 index );
|
IndexOp( Var* var, U32 index );
|
||||||
void print( Stream &stream ) override;
|
void print( Stream &stream ) override;
|
||||||
};
|
};
|
||||||
|
|
@ -185,10 +185,10 @@ public:
|
||||||
class CastOp : public ShaderOp
|
class CastOp : public ShaderOp
|
||||||
{
|
{
|
||||||
typedef ShaderOp Parent;
|
typedef ShaderOp Parent;
|
||||||
GFXShaderConstType mTargetType;
|
|
||||||
Vector<String> mSwizzle; // "x", "y", "z", "w"
|
Vector<String> mSwizzle; // "x", "y", "z", "w"
|
||||||
Vector<String> mFillValues; // "0", "0", "0", "1"
|
Vector<String> mFillValues; // "0", "0", "0", "1"
|
||||||
public:
|
public:
|
||||||
|
GFXShaderConstType mTargetType;
|
||||||
CastOp( LangElement* srcVar,
|
CastOp( LangElement* srcVar,
|
||||||
GFXShaderConstType type,
|
GFXShaderConstType type,
|
||||||
const char* swizzleStr = "x;y;z;w",
|
const char* swizzleStr = "x;y;z;w",
|
||||||
|
|
@ -243,4 +243,13 @@ public:
|
||||||
*/
|
*/
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MatrixMultiplyOp : public ShaderOp
|
||||||
|
{
|
||||||
|
typedef ShaderOp Parent;
|
||||||
|
public:
|
||||||
|
MatrixMultiplyOp(LangElement* left, LangElement* right);
|
||||||
|
|
||||||
|
void print(Stream& stream) override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // _SHADEROP_H_
|
#endif // _SHADEROP_H_
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue