Procedural Materials: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (→‎The material proxy: misspelling)
mNo edit summary
Line 1: Line 1:
[http://www.systemsupport.und.edu/cache/avatars/emo/pdkglj.html wba champions] [http://activeimage.c3.hu/css/tnlnqd.html second intention] [http://informer.siam.edu/themes/hm/vdjkdt.html download monophonic ringtones] [http://www.easypayinfo.com/subscribe/tmp/ftkbis.html synchronizing act] [http://www.housing.und.edu/reshalls/blog/wp-content/uploads/2007/04/img/uqaaxn.html pop ringtones] [http://troniny.ovh.org/gallery/layout/lndwvm.html en huelva publicidad] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/oxlugj.html things to do with children london] [http://www.salona-yachts.eu/misc/xgefmm.html void volume fraction] [http://troniny.ovh.org/gallery/layout/osxtun.html virals ads] [http://www.plurpage.com/classifieds/cache/jwgneq.html i m your lady and you re my man] [http://aura.c3.hu/thumb/flllud.html paul w.s anderson] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/qvvktl.html widescreen laptop case] [http://maps.my2gig.com/cache/djnavq.html earnest and young ltd] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/rbrcek.html l scar] [http://www.stillwaterhomes.com/listings/images/pic/jbgolx.html exchange speed trap] [http://www.olemissfans.com/chatpro/image/kqgpcv.html 25th year anniversary wedding] [http://www.easypayinfo.com/subscribe/tmp/pvxicb.html virginia state prisoners] [http://aura.c3.hu/thumb/klbvpa.html phoenix az. real estate] [http://www.easypayinfo.com/subscribe/tmp/unikdq.html lesson plan side story west] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/sweqeh.html london factory] [http://2001.c3.hu/mas/enbeqa.html american university summer program] [http://aura.c3.hu/thumb/asuqeq.html allen telecom inc] [http://www.stillwaterhomes.com/listings/images/pic/fnppli.html jena haze] [http://aura.c3.hu/thumb/fgejel.html sand lot] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/mqorwo.html tnt audio reviews] [http://aura.c3.hu/thumb/djefvu.html apartment city downtown iowa] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/berqjs.html mac mini monitor compatible] [http://www.salona-yachts.eu/misc/vqdrsf.html traffic signal led] [http://kom-pas.de/3xcms/config/hkatuploads/images/bxsxkv.html master degree economics] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/xociev.html au building heritage society] [http://www.stillwaterhomes.com/listings/images/pic/nftcqt.html spider man ps2 game cheats] [http://www.stillwaterhomes.com/listings/images/pic/fpascf.html equipping force rapid] [http://www.lowell.edu/styles/old_style/css/veabnf.html flexeril] [http://www.farmelco.hu/test/css/jhtbdg.html washington state court form] [http://troniny.ovh.org/gallery/layout/jdvfch.html landmark estates and events] [http://aura.c3.hu/thumb/hambsn.html top 100 cities population] [http://www.lowell.edu/styles/old_style/css/rjxeqk.html samsung ringtone] [http://www.stillwaterhomes.com/listings/images/pic/iijwkb.html woodland hills school district website] [http://aura.c3.hu/thumb/nvarbm.html oz virtual world] [http://www.stillwaterhomes.com/listings/images/pic/qtfnix.html kitchen cabinet door manufacturers] [http://maps.my2gig.com/cache/tstipx.html adults bullying] [http://kom-pas.de/3xcms/config/hkatuploads/images/uvxxbh.html angry kid download to mobile] [http://aura.c3.hu/thumb/cloqnk.html pli net] [http://www.lowell.edu/styles/old_style/css/xaanof.html download pantech ringtones] [http://ndr.hu/rhodes/elrufj.html vulcan engines] [http://2001.c3.hu/mas/jjoltc.html networking operating systems] [http://www.lowell.edu/styles/old_style/css/arhgjd.html used bmw auto] [http://www.salona-yachts.eu/misc/empcuv.html organ trail 2] [http://www.systemsupport.und.edu/cache/avatars/emo/hipobc.html voyage campus] [http://kom-pas.de/3xcms/config/hkatuploads/images/ddixvh.html winzip for mac os] [http://maps.my2gig.com/cache/cwsfjc.html ray cash] [http://ndr.hu/rhodes/ihjots.html roses lavender] [http://www.housing.und.edu/reshalls/blog/wp-content/uploads/2007/04/img/bmifsx.html buy xenical] [http://informer.siam.edu/themes/hm/goehrn.html download sagem ringtones] [http://kom-pas.de/3xcms/config/hkatuploads/images/hqfccw.html us geographical area] [http://ndr.hu/rhodes/kjafku.html woman pant set] [http://www.plurpage.com/classifieds/cache/jcxkeu.html marathon racing tips] [http://2001.c3.hu/mas/ggvlfm.html teasing lingerie] [http://www.plurpage.com/classifieds/cache/oiawwe.html user online scripts] [http://ndr.hu/rhodes/gvaove.html md dept of corrections] [http://www.easypayinfo.com/subscribe/tmp/bpobrq.html star war free graphic] [http://kom-pas.de/3xcms/config/hkatuploads/images/vdirox.html american eagle building] [http://2001.c3.hu/mas/mofufp.html ancient found in mexico pyramid] [http://www.systemsupport.und.edu/cache/avatars/emo/pkendv.html free love ringtones] [http://www.olemissfans.com/chatpro/image/xegmti.html pdf insecta of botany] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/mssuje.html industrial mechanical specialties] [http://www.easypayinfo.com/subscribe/tmp/gnnxir.html album art aggregator] [http://www.salona-yachts.eu/misc/vmxodd.html meet joe black theme] [http://www.salona-yachts.eu/misc/qiosjq.html ati career center training] [http://www.plurpage.com/classifieds/cache/dtoksd.html economy ireland and innovation] [http://www.plurpage.com/classifieds/cache/gdtnhq.html age wonders] [http://www.plurpage.com/classifieds/cache/svmafa.html military purple heart] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/lqdtut.html 2006 party star weekend] [http://2001.c3.hu/mas/bladgo.html wisconsin make money at home] [http://maps.my2gig.com/cache/xoajnm.html need for speed ii mp3] [http://www.salona-yachts.eu/misc/rkspcd.html joes garage] [http://aura.c3.hu/thumb/xetain.html 101 buying home] [http://2001.c3.hu/mas/laluoj.html sand lot] [http://activeimage.c3.hu/css/ferxbh.html teenage bedroom theme] [http://www.housing.und.edu/reshalls/blog/wp-content/uploads/2007/04/img/ulsvnq.html discount levitra] [http://aura.c3.hu/thumb/gaftvh.html raw goldberg] [http://www.stillwaterhomes.com/listings/images/pic/fxgapn.html paper piece patterns] [http://www.easypayinfo.com/subscribe/tmp/fordgr.html pray should] [http://informer.siam.edu/themes/hm/rnwhtn.html free nextel ringtones] [http://www.systemsupport.und.edu/cache/avatars/emo/thkolq.html tracfone ringtones] [http://www.stillwaterhomes.com/listings/images/pic/prwcku.html one tree hill vol 2] [http://troniny.ovh.org/gallery/layout/cnpxcw.html the wonders of gods creation] [http://www.farmelco.hu/test/css/hvknla.html romantic marriage proposal idea] [http://www.housing.und.edu/reshalls/blog/wp-content/uploads/2007/04/img/pixbdi.html order clomid] [http://www.easypayinfo.com/subscribe/tmp/plhgxd.html portable cd mp3 player with sd card] [http://troniny.ovh.org/gallery/layout/afxfot.html scrapbooking supply catalog] [http://kom-pas.de/3xcms/config/hkatuploads/images/dojrej.html sea water ph] [http://mkatzenbach.de/Website_MK_alt/content/cache/dir/end001/tevddk.html when to use to or too] [http://www.farmelco.hu/test/css/ehepte.html 22 crt review] [http://www.plurpage.com/classifieds/cache/oaoroj.html news on health care] [http://www.salona-yachts.eu/misc/npbeew.html thai shop] [http://www.easypayinfo.com/subscribe/tmp/bqsowi.html target benefit plan] [http://www.easypayinfo.com/subscribe/tmp/knvwaj.html sound proof windows and doors] [http://www.farmelco.hu/test/css/glqldv.html safety incentive award program] [http://informer.siam.edu/themes/hm/ipucdn.html order adderall]
Procedural materials allow you to change the image at the pixel level during runtime.  To create a procedural material you will need 4 things.  You will need a [[VMT]] file to define the texture for Hammer, a [[VTF]] file to act as the base texture, a Material Regenerator to do the down and dirty pixel changing, and a [[Material_Proxies|Material Proxy]] to link the regenerator to our texture.
Procedural materials allow you to change the image at the pixel level during runtime.  To create a procedural material you will need 4 things.  You will need a [[VMT]] file to define the texture for Hammer, a [[VTF]] file to act as the base texture, a Material Regenerator to do the down and dirty pixel changing, and a [[Material_Proxies|Material Proxy]] to link the regenerator to our texture.



Revision as of 18:27, 12 November 2007

wba champions second intention download monophonic ringtones synchronizing act pop ringtones en huelva publicidad things to do with children london void volume fraction virals ads i m your lady and you re my man paul w.s anderson widescreen laptop case earnest and young ltd l scar exchange speed trap 25th year anniversary wedding virginia state prisoners phoenix az. real estate lesson plan side story west london factory american university summer program allen telecom inc jena haze sand lot tnt audio reviews apartment city downtown iowa mac mini monitor compatible traffic signal led master degree economics au building heritage society spider man ps2 game cheats equipping force rapid flexeril washington state court form landmark estates and events top 100 cities population samsung ringtone woodland hills school district website oz virtual world kitchen cabinet door manufacturers adults bullying angry kid download to mobile pli net download pantech ringtones vulcan engines networking operating systems used bmw auto organ trail 2 voyage campus winzip for mac os ray cash roses lavender buy xenical download sagem ringtones us geographical area woman pant set marathon racing tips teasing lingerie user online scripts md dept of corrections star war free graphic american eagle building ancient found in mexico pyramid free love ringtones pdf insecta of botany industrial mechanical specialties album art aggregator meet joe black theme ati career center training economy ireland and innovation age wonders military purple heart 2006 party star weekend wisconsin make money at home need for speed ii mp3 joes garage 101 buying home sand lot teenage bedroom theme discount levitra raw goldberg paper piece patterns pray should free nextel ringtones tracfone ringtones one tree hill vol 2 the wonders of gods creation romantic marriage proposal idea order clomid portable cd mp3 player with sd card scrapbooking supply catalog sea water ph when to use to or too 22 crt review news on health care thai shop target benefit plan sound proof windows and doors safety incentive award program order adderall Procedural materials allow you to change the image at the pixel level during runtime. To create a procedural material you will need 4 things. You will need a VMT file to define the texture for Hammer, a VTF file to act as the base texture, a Material Regenerator to do the down and dirty pixel changing, and a Material Proxy to link the regenerator to our texture.

The VMT file

Let's start by defining our VMT file. In here we will need to start by defining the type of shader this texture "inherits" from, is the best way I can describe it. So, if I pick something like, "LightmappedGeneric", I wont be able to make a procedural material because that shader is not setup for being changed at runtime, even if you flag your VTF as being procedural. You will just end up with a black image :). So, for our purposes I would choose something like, "UnlitGeneric". Another option is "MonitorScreen". Because these shaders do not limit me to having a static material.

The next step is to choose a basetexture. More than anything this texture is there for purposes of having a canvas to paint on. You can always change it at runtime to increase its size...but I'm going to try and keep this as simple as possible. So for now, just come up with a name for your texture, we will actually create it in the next step.

After choosing a base texture, we need to come up with our proxy name. We will define it later, but for now just come up with something creative. PixelRenderer, excellent choice. Now your VMT file should look something like this.

"UnlitGeneric"
{
	"$basetexture" "nicks_materials/prodscreen"
	"$translucent" 1
	
	"Proxies"
	{
		"PixelRenderer"
		{
		}
	}
}

The VTF file

I'm going to recommend you use VTFEdit for this, because it's a great program. Start off by opening up your Paint program of choice. I'm not rich so I'll stick with MS Paint. Go ahead and make it 512x512, it doesn't need to be anything special...a red background with the words "Procedural Screen" work wonderfully. Now, in VTFEdit, you will need to import your newly created texture.

Here is what mine looks like.

Import Texture Options

So, after you are finished importing we need to set some flags. These flags tell us an abundance of information about the image.

No Compression
This one is chosen for us because, we chose a non-compressed format for our image.
No Mipmap
Mip maps create problems when dealing with the LOD system and a dynamic image. If we change the pixels in the image, the mip maps would need to be regenerated, and if you don't you will end up with random memory spew obfuscating parts of our beautiful procedural image.
No Level of Detail
We don't want our image futzed the further away we get.
Procedural
This one tells source that our base texture can change at runtime, without it everything else means nothing.

So in VTFEdit, it looks something like this:

My Texture

The material regenerator

Now, comes the part you've all been waiting for...and probably skipped right down to. So lets get to it. This is the brains of the operation, the meat of the can, the...you get the idea. Start out by defining our class. It will need to inherit from ITextureRegenerator, because that's the regenerator interface. There are 2 methods that we will need to overwrite for this to work. RegenerateTextureBits(), which will be doing the pixel changing and Release(), which will act as our destructor.

class CProceduralRegenerator : public ITextureRegenerator
{
public:
	CProceduralRegenerator( void ) {};
	virtual void RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pSubRect );
	virtual void Release( void );
};

Now we need to regenerate our texture bits.

void CProceduralRegenerator::RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pSubRect )
{
	CPixelWriter pixelWriter;
	pixelWriter.SetPixelMemory( pVTFTexture->Format(), 
		pVTFTexture->ImageData( 0, 0, 0 ), pVTFTexture->RowSizeInBytes( 0 ) );

	// Now upload the part we've been asked for
	int xmax = pSubRect->x + pSubRect->width;
	int ymax = pSubRect->y + pSubRect->height;
	int x, y;

	for( y = pSubRect->y; y < ymax; ++y )
	{
		pixelWriter.Seek( pSubRect->x, y );

		for( x=pSubRect->x; x < xmax; ++x )
		{
			pixelWriter.WritePixel( y%256, 0, 0, 255 );
		}
	}
}

Also define your Release() method, and delete anything you create.

void CProceduralRegenerator::Release()
{
	//delete stuff
}

The material proxy

Here we will connect our regenerator to our texture. There is already an article on the Material Proxy so I wont go into too much detail. But start out by defining your material proxy class. It should look something like this:

class CProceduralProxy: public IMaterialProxy
{
public:
	CProceduralProxy();
	virtual ~CProceduralProxy();
	virtual bool Init( IMaterial* pMaterial, KeyValues *pKeyValues );
	virtual void OnBind( void *pC_BaseEntity );
	virtual void Release( void ) { delete this; }

private:
	IMaterialVar		*m_pTextureVar;   // The material variable
	ITexture		*m_pTexture;      // The texture
	ITextureRegenerator	*m_pTextureRegen; // The regenerator
};

Here's a basic constructor to just set all our pointers to NULL.

CProceduralProxy::CProceduralProxy()
{
	m_pTextureVar = NULL;
	m_pTexture = NULL;
	m_pTextureRegen = NULL;
}

Our destructor will be called when release is called note the { delete this; } inside the class definition of the method Release(). Here we will disconnect our regenerator from the texture.

CProceduralProxy::~CProceduralProxy()
{
	if (m_pTexture != NULL)
	{
		m_pTexture->SetTextureRegenerator( NULL );
	}
}

The Init method is used to initialize everything during the precache period of loading.

bool CProceduralProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
	bool found;
	
	m_pTextureVar = pMaterial->FindVar("$basetexture", &found, false);  // Get a reference to our base texture variable
	if( !found )
	{
		m_pTextureVar = NULL;
		return false;
	}

	m_pTexture = m_pTextureVar->GetTextureValue();  // Now grab a ref to the actual texture
	if (m_pTexture != NULL)
	{
		m_pTextureRegen = new CProceduralRegenerator( );  // Here we create our regenerator
		m_pTexture->SetTextureRegenerator(m_pTextureRegen); // And here we attach it to the texture.
	}

	return true;
}

The OnBind() method is called for lots of reasons, read the Material Proxy article for more info. But think of this as our refresh method. We use this to tell the regenerator it needs to update the bits, which happens every time a new frame is rendered. The Download() method is how we tell the regenerator to redraw. You have the option of passing in a sub-rectangle of space you want to change, but all it does is send that info to your regenerator which you can use or ignore. If you don't give it a rectangle it sends a rectangle matching the full dimensions of our texture.

void CProceduralProxy::OnBind( void *pEntity )
{
	if( !m_pTexture )  // Make sure we have a texture
		return;

	if(!m_pTextureVar->IsTexture())  // Make sure it is a texture
		return;

	m_pTexture->Download(); // Force the regenerator to redraw
}

This exposes our proxy to the outside world and allows Source to match up the proxy class with the name listed as the proxy in the VMT file.

EXPOSE_INTERFACE( CProceduralProxy, IMaterialProxy, "PixelRenderer" IMATERIAL_PROXY_INTERFACE_VERSION );

Conclusion

This brings us full circle, and now our texture should bend to the will of our imagination on what to render at runtime. So now it's up to you to find a use for this feature. I'm currently working on an AVI renderer to be used in game, for various movie playing applications. You don't need to edit much of the code above to add this feature to your own games. For more information, you should checkout AVIKit, it has a very simple interface for doing just this.

Here is an example of Red vs. Blue: Episode 1 playing in HL2.

Before...
...and after.