Pure research Example For changing Speculatiry on the fly
From TDN
So, mainly to make sure I was following the Code-flow Correctly, I did a bit of research and came up with the following example
So let me start out by saying that the net effect of this particular little line of hackishness is not likely to blow a bunch of air up anyones skirts. The
example provied is arbitrarily small to make it as simple as possible to follow the logic, not so it'll be a drop-in totally usefull rescource.
That being said, just as with datablocks, theres times you'll want to change stock behavior from per type-of-asset, to per-asset, and that's where this
comes in.
Now then, for clarity, we'll be starting our code-journey at the material end, and work our way back from there with the following setup:
Engine:
Materials.cc/cpp
void Material::setShaderConstants( const SceneGraphData &sgData, U32 stageNum )
{
...
if (!mOverrideColor)
GFX->setPixelShaderConstF( PC_MAT_SPECCOLOR, (float*)&specular[stageNum], 1 );
else
GFX->setPixelShaderConstF( PC_MAT_SPECCOLOR, (float*)&sgData.mObjectColor, 1 );
...
}
1.7 note:
if using a 1.7 baseline, processedshadermaterials add another layer of indirection/abstraction to the mix, so the proper function is instead:
void ProcessedShaderMaterial::setShaderConstants(const SceneGraphData &sgData, U32 pass)
{
...
if (!mMaterial->mOverrideColor)
GFX->setPixelShaderConstF( PC_MAT_SPECCOLOR, (float*)&mMaterial->specular[stageNum], 1 );
else
GFX->setPixelShaderConstF( PC_MAT_SPECCOLOR, (float*)&sgData.mObjectColor, 1 );
...
}
1.8 note:
if using a 1.8 baseline, the proper function is instead:
void ProcessedShaderMaterial::_setShaderConstants(SceneState * state, const SceneGraphData &sgData, U32 pass)
{
...
if (handles->mSpecularColorSC)
{
if (!mMaterial->mOverrideColor)
shaderConsts->set(handles->mSpecularColorSC, mMaterial->mSpecular[stageNum]);
else
shaderConsts->set(handles->mSpecularColorSC, (float*)&sgData.mObjectColor);
shaderConsts->set(handles->mSpecularPowerSC, mMaterial->mSpecularPower[stageNum]);
}
...
}
Script:
new Material(buggy_body001a)
{
...
OverrideColor = true;
...
};
This is to ensure that only those flagged materials update, since you'll likely have a few you don't want to bother with.
now sgData get's it's info from struct RenderInst, so we parse in a ColorF mObjectColor; into renderInstMgr.h
In order to have a point of reffernece for that RenderInst, we go into
tsMesh.cc/cpp
void TSMesh::render(S32 frame, S32 matFrame, TSMaterialList * materials)
{
if( vertsPerFrame <= 0 ) return;
RenderInst *coreRI = gRenderInstManager.allocInst();
coreRI->type = RenderInstManager::RIT_Mesh;
coreRI->calcSortPoint( smObject, smSceneState->getCameraPosition() );
if (smObject) coreRI->mObjectColor = smObject->mObjectColor; //goes fatal if not assigned...
...
}
smObject refferences a sceneObject, so we need to add yet another mObjectColor to that definition,
as well as add in:
void SceneObject::initPersistFields()
{
...
addField("ObjectColor", TypeColorF, Offset(mObjectColor, SceneObject));
...
}
so that we can dynamicly update our values.
Wich brings us to the highly unoptimised quick-hack finish of the lil example:
U32 GameBase::packUpdate(NetConnection *, U32 mask, BitStream *stream)
{
...
stream->writeFloat(mObjectColor.red, 7);
stream->writeFloat(mObjectColor.green, 7);
stream->writeFloat(mObjectColor.blue, 7);
stream->writeFloat(mObjectColor.alpha, 7);
...
}
void GameBase::unpackUpdate(NetConnection *con, BitStream *stream)
{
...
mObjectColor.red = stream->readFloat(7);
mObjectColor.green = stream->readFloat(7);
mObjectColor.blue = stream->readFloat(7);
mObjectColor.alpha = stream->readFloat(7);
...
}
aaand finally, what's an explaination involving shaders without crappy programmer-art:
paletswapping on a texture based on the current mObjectColor setup: Working Example of a Colorpicker
multplying the alphachanel of a second damage texture laying on top of a healthy texture based on the object's health so it get's dirtier/more cracked/bloodier, whatever based on the damage it's taken: Texture Bleeding Based On damage
scrolling tank-treds using the GPU based on the tanks movement speed: GPU Tank Tred animation



