Material proxies: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (Robot: Automated text replacement (-\{\|\r +{| class=standard-table))
(Added more info on variables (from digging through Valve's material files))
Line 69: Line 69:
The following values are commonly used as $resultVar variables.
The following values are commonly used as $resultVar variables.
{| class=standard-table
{| class=standard-table
| <code>$alpha</code> || Fade value (0 = transparent, 1 = opaque)
| <code>$alpha</code> || Fade value (0 = transparent, 1 = opaque).
Won't do anything under the UnlitTwoTexture shader - use $color instead.
|-
|-
| <code>$color</code> || Modulation color (R,G,B) (1,1,1) = white, (0,0,0) = black
| <code>$color</code> || Modulation color (R,G,B) (1,1,1) = white, (0,0,0) = black. Accessed as a table.
Individual channels can be accessed using <code>"resultVar" "$color[0]"</code> for the Red channel, [1] for the Green channel and [2] for the Blue.
Can be used with UnlitTwoTexture materials to alter opacity (UnlitTwoTexture with $translucent considers black as transparent for both diffuse maps)
|-
|-
| <code>$envmapmaskscale</code> || An amount to scale the environment map mask
| <code>$envmaptint</code> || Modulation color for the environment map. Behaves the same as $color above.
|-
|-
| <code>$frame</code> || Frame number of an animated texture
| <code>$selfillumtint</code> || Modulation color for the self-illumination. Behaves the same as $color above.
|-
|-
| <code>$envmaptint</code> || Modulation color for the environment map
| <code>$envmapmaskscale</code> || An amount to scale the environment map mask.
|-
|-
| <code>$selfillumtint</code> || Modulation color for the self-illumination
| <code>$frame</code> || Frame number of an animated texture. Used as the <code>animatedtextureframenumvar</code> with the AnimatedTexture property, but can be advanced/decreased by other proxies too.
|-
| <code>$frame2</code> || $frame for the second texture in two-texture shaders ({{todo|Will this work with WorldVertexTransition?}}).
|-
| <code>$bumpframe</code> || Frame number of an animated texture. {{note|There doesn't appear to be a frame control for $bumpmap2. Would probably be overkill anyway}}
|-
| <code>$basetexture</code> || Used by the AnimatedTexture proxy, as the <code>animatedtexturevar</code> in conjunction with $frame.
|-
| <code>$texture2</code> || Used by the AnimatedTexture proxy, as the <code>animatedtexturevar</code> in conjunction with $frame2.
|-
| <code>$normalmap</code> || Used by the AnimatedTexture proxy, as the <code>animatedtexturevar</code> in conjunction with $bumpframe.
|-
| <code>$basetexturetransform</code> || Another array, holding two values for x and y respectively. Used predominantly by TextureScroll and ConveyorScroll (as the <code>textureScrollVar</code> in both cases) to scroll the texture.
|-
| <code>$texture2transform</code> || Operates in the same way as $basetexturetransform above, but for the second texture in a two-texture shader ({{todo|Again, WorldVertexTransition?}})
|-
| <code>$bumptransform</code> || Operates in the same way as $basetexturetransform above, but for the bumpmap ({{todo|Again, second texture bumpmaps?}})
|-
|-
|}
|}
{{Note|<code>$alpha</code> and <code>$color</code> values are clamped between 0 and 1.}}
{{Note|Certain variables like <code>$color</code> and <code>$baseTextureOffset</code> can be accessed like an [[array]]. <code>"$color[0]"</code> would access the red component of the variable.}}


== Writing material proxy implementations ==
== Writing material proxy implementations ==

Revision as of 05:14, 30 July 2009

The basics

Material proxies allow materials to change their rendering properties (color, alpha values, etc) using game state and scripted equations. Proxies are defined as a block of text, using key/value pairing, inside of the VMT description of a material. Proxies are available for all materials.

A proxy is defined as in the following example:

"LightmappedGeneric"
{
	"$basetexture" "shadertest/LightmappedTexture"

	// Inside these braces are where all the proxies go
	"Proxies"
	{
		// This is a sine proxy
		"Sine"
		{
			// This is the data for the sine proxy
			// Notice there is no '$' on the proxy variables
			"resultVar"	"$alpha"
			"sineperiod"	8
			"sinemin"	0
			"sinemax"	1
		}
	}
}

The above block of text instructs the material to use the Sine material proxy to modify the alpha value of the material when rendered. The other entries define parameters for the proxy to use in its calculations. Here the sine wave has a sineperiod of 8 seconds and oscillates between a value of "0" and "1".

It is possible to define multiple proxies in one material within the Proxies section of that material's definition. If multiple proxies are defined, they are executed in a top to bottom order.

"Proxies" 
{ 
	// This is executed first
	"A"
	{
		. . .
	}
	// This is executed second
	"B"
	{
		. . .
	}
}

Variables

Like a standard programming language, the material proxies may declare temporary local variables to be used to store intermediate values for further use later in the proxy. Variables are declared outside of the Proxies block and have default values specified on their right-hand side.

"LightmappedGeneric"
{
	"$basetexture" "shadertest/LightmappedTexture"

	// A local variable for this material, defaulting to "0.5"
	"$myScale" 0.5
	"Proxies"
	{
		. . .
	}
}

There is no practical limit to the number of local variables declared. Local variables may be used to store results from proxies, or to pass data into proxies as parameters. They are often employed to chain mathematic function proxies (i.e. Add, Subtract, etc) together into longer equations for rendering values.

Common result variables

The following values are commonly used as $resultVar variables.

$alpha Fade value (0 = transparent, 1 = opaque).

Won't do anything under the UnlitTwoTexture shader - use $color instead.

$color Modulation color (R,G,B) (1,1,1) = white, (0,0,0) = black. Accessed as a table.

Individual channels can be accessed using "resultVar" "$color[0]" for the Red channel, [1] for the Green channel and [2] for the Blue. Can be used with UnlitTwoTexture materials to alter opacity (UnlitTwoTexture with $translucent considers black as transparent for both diffuse maps)

$envmaptint Modulation color for the environment map. Behaves the same as $color above.
$selfillumtint Modulation color for the self-illumination. Behaves the same as $color above.
$envmapmaskscale An amount to scale the environment map mask.
$frame Frame number of an animated texture. Used as the animatedtextureframenumvar with the AnimatedTexture property, but can be advanced/decreased by other proxies too.
$frame2 $frame for the second texture in two-texture shaders (
Todo: Will this work with WorldVertexTransition?
).
$bumpframe Frame number of an animated texture.
Note.pngNote:There doesn't appear to be a frame control for $bumpmap2. Would probably be overkill anyway
$basetexture Used by the AnimatedTexture proxy, as the animatedtexturevar in conjunction with $frame.
$texture2 Used by the AnimatedTexture proxy, as the animatedtexturevar in conjunction with $frame2.
$normalmap Used by the AnimatedTexture proxy, as the animatedtexturevar in conjunction with $bumpframe.
$basetexturetransform Another array, holding two values for x and y respectively. Used predominantly by TextureScroll and ConveyorScroll (as the textureScrollVar in both cases) to scroll the texture.
$texture2transform Operates in the same way as $basetexturetransform above, but for the second texture in a two-texture shader (
Todo: Again, WorldVertexTransition?
)
$bumptransform Operates in the same way as $basetexturetransform above, but for the bumpmap (
Todo: Again, second texture bumpmaps?
)

Writing material proxy implementations

Although many generic proxies are included in the client already, it will sometimes be necessary to create a custom material proxy for your MOD. To do this, code will be required on the client-side. Material proxies are descended from the IMaterialProxy interface class. The proxy has three main functions to do its work in. The first is the Init() function, defined as:

bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
 pMaterial
 Material we're acting on

 pKeyValues
 List of key-value pairs for this material

The Init() function is called when a material is first created in a session. This function allows you to setup internal state for the material proxy, usually consisting of obtaining references to material variables for later use.

void OnBind( void *pC_BaseEntity );
 pC_BaseEntity
 Entity this material is being applied to (if any)

The OnBind() function is called every time Bind() is called on a material. This is where most of the material proxy's work is done.

Finally, the proxy must expose its interface so that the named reference to the proxy can be linked up to the class implementation. This is done via the EXPOSE_INTERFACE macro.

EXPOSE_INTERFACE( className, interfaceName, proxyName IMATERIAL_PROXY_INTERFACE_VERSION );
Note.pngNote:See DummyProxy.cpp for an example of a simple material proxy.


See also