How to pass data to a custom shader
by Heron Huang · in Torque Game Engine Advanced · 06/22/2005 (4:12 pm) · 4 replies
Hi all:
I wanna define a material with custom shaders,but how can i pass constant data to the shaders?
Is it needed to overload custommaterial class in some cpp or simply define them in a script file?
I wanna define a material with custom shaders,but how can i pass constant data to the shaders?
Is it needed to overload custommaterial class in some cpp or simply define them in a script file?
#2
06/23/2005 (12:53 am)
I'll give a try, Thanks Kevin :o)
#3
Newb question:
How would I go about setting a SimTime shdr Constant? Here's how I've done it so far:
bool ITickable::advanceTime( U32 timeDelta )
{
U32 targetTime = smLastTime + timeDelta;
U32 targetTick = ( targetTime + smTickMask ) & ~smTickMask;
U32 tickCount = ( targetTick - smLastTick ) >> smTickShift;
// If we are going to send a tick, call interpolateTick(0) so that the objects
// will reset back to their position at the last full tick
if( smLastDelta && tickCount )
for( ProcessListIterator i = smProcessList.begin(); i != smProcessList.end(); i++ )
if( (*i)->isProcessingTicks() )
(*i)->interpolateTick( 0.f );
// Advance objects
if( tickCount )
for( ; smLastTick != targetTick; smLastTick += smTickMs )
for( ProcessListIterator i = smProcessList.begin(); i != smProcessList.end(); i++ )
if( (*i)->isProcessingTicks() )
(*i)->processTick();
smLastDelta = ( smTickMs - ( targetTime & smTickMask ) ) & smTickMask;
F32 dt = smLastDelta / F32( smTickMs );
// Now interpolate objects that want ticks
for( ProcessListIterator i = smProcessList.begin(); i != smProcessList.end(); i++ )
if( (*i)->isProcessingTicks() )
(*i)->interpolateTick( dt );
// Inform ALL objects that time was advanced
dt = F32( timeDelta ) / 1000.f;
for( ProcessListIterator i = smProcessList.begin(); i != smProcessList.end(); i++ )
(*i)->advanceTime( dt );
GFX->setVertexShaderConstF(VC_TIME, (float*)&tickCount, 1); //***************Notice
GFX->setPixelShaderConstF(PC_TIME, (float*)&tickCount, 1); // *********These two lines are added
smLastTime = targetTime;
return tickCount != 0;
}
that's my change to core/iTickable.cpp (I also did #include "gfx/gfxDevice.h" at the top)
I'm kinda new to the C++ side of things, but the way I see it, now in addition to informing all objects that time was advanced it will now also inform the Shader constant PV/VC_TIME what time it is also, now all I have to do is add #define VC_TIME; and #define PC_TIME; in shdrConsts.h. Is that correct? I have some questions if it's correct (Or if it's incorrect for that matter)
-What's the difference between a Pixel and a vertex Constant? A constant's a constant I would think, unless it is simply a naming convention to keep ShdrConsts.h more organized, with no different functionality?
-edit- Before compiling I commented the old GFX->setPixelShaderConstF(PC_TIME, (float*)&tickCount, 1); now I get an VC_TIME has an undeclared identifier, another change I made was #include "console/consoleTypes.h" at the top
11/27/2006 (8:28 pm)
I don't want to hijack this thread, but this seems on topic enough:Newb question:
How would I go about setting a SimTime shdr Constant? Here's how I've done it so far:
bool ITickable::advanceTime( U32 timeDelta )
{
U32 targetTime = smLastTime + timeDelta;
U32 targetTick = ( targetTime + smTickMask ) & ~smTickMask;
U32 tickCount = ( targetTick - smLastTick ) >> smTickShift;
// If we are going to send a tick, call interpolateTick(0) so that the objects
// will reset back to their position at the last full tick
if( smLastDelta && tickCount )
for( ProcessListIterator i = smProcessList.begin(); i != smProcessList.end(); i++ )
if( (*i)->isProcessingTicks() )
(*i)->interpolateTick( 0.f );
// Advance objects
if( tickCount )
for( ; smLastTick != targetTick; smLastTick += smTickMs )
for( ProcessListIterator i = smProcessList.begin(); i != smProcessList.end(); i++ )
if( (*i)->isProcessingTicks() )
(*i)->processTick();
smLastDelta = ( smTickMs - ( targetTime & smTickMask ) ) & smTickMask;
F32 dt = smLastDelta / F32( smTickMs );
// Now interpolate objects that want ticks
for( ProcessListIterator i = smProcessList.begin(); i != smProcessList.end(); i++ )
if( (*i)->isProcessingTicks() )
(*i)->interpolateTick( dt );
// Inform ALL objects that time was advanced
dt = F32( timeDelta ) / 1000.f;
for( ProcessListIterator i = smProcessList.begin(); i != smProcessList.end(); i++ )
(*i)->advanceTime( dt );
GFX->setVertexShaderConstF(VC_TIME, (float*)&tickCount, 1); //***************Notice
GFX->setPixelShaderConstF(PC_TIME, (float*)&tickCount, 1); // *********These two lines are added
smLastTime = targetTime;
return tickCount != 0;
}
that's my change to core/iTickable.cpp (I also did #include "gfx/gfxDevice.h" at the top)
I'm kinda new to the C++ side of things, but the way I see it, now in addition to informing all objects that time was advanced it will now also inform the Shader constant PV/VC_TIME what time it is also, now all I have to do is add #define VC_TIME; and #define PC_TIME; in shdrConsts.h. Is that correct? I have some questions if it's correct (Or if it's incorrect for that matter)
-What's the difference between a Pixel and a vertex Constant? A constant's a constant I would think, unless it is simply a naming convention to keep ShdrConsts.h more organized, with no different functionality?
-edit- Before compiling I commented the old GFX->setPixelShaderConstF(PC_TIME, (float*)&tickCount, 1); now I get an VC_TIME has an undeclared identifier, another change I made was #include "console/consoleTypes.h" at the top
#4
The constants are "scoped" (i believe that is the correct term) So you can reuse registers. if they werent it would cut down the avail registers in half.. As you develop more complex shaders (an support various PS models) you will see that running out of registers is VERY easy to do..
12/04/2006 (10:27 pm)
What's the difference between a Pixel and a vertex Constant? The constants are "scoped" (i believe that is the correct term) So you can reuse registers. if they werent it would cut down the avail registers in half.. As you develop more complex shaders (an support various PS models) you will see that running out of registers is VERY easy to do..
Torque Owner Kevin Johnson
here is an example:
//setShaderConstants GFX->setVertexShaderConstF( VC_LIGHT_POS1, (float*)&lightPos, 1 ); GFX->setVertexShaderConstF( VC_LIGHT_DIR1, (float*)&lightDir, 1 );then in your shaderor if you include shdrConsts.h
You can pass whatever you need to, color, vector etc..