Phong materials: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
Line 17: Line 17:


[[Image:Phong reflection.jpg|right|250px|thumb|The Phong reflection equation expressed graphically.]]
[[Image:Phong reflection.jpg|right|250px|thumb|The Phong reflection equation expressed graphically.]]
===The Phong Reflection Model===
===The Phong reflection model===


The Phong reflection model is basically a simplified method of deciding the shade of a specific point on a 3D surface.
The Phong reflection model is basically a simplified method of deciding the shade of a specific point on a 3D surface.
Line 27: Line 27:


[[Image:Flatvsphong.jpg|right|250px|thumb|Phong interpolation example.]]
[[Image:Flatvsphong.jpg|right|250px|thumb|Phong interpolation example.]]
===Phong Interpolation===
===Phong interpolation===


Phong shading provides a better approximation to a per-pixel application of an underlying reflection model by assuming a smoothly varying surface normal vector. The Phong interpolation method works particularly well when applied to the Phong reflection model or to any reflection model that has small specular highlights.
Phong shading provides a better approximation to a per-pixel application of an underlying reflection model by assuming a smoothly varying surface normal vector. The Phong interpolation method works particularly well when applied to the Phong reflection model or to any reflection model that has small specular highlights.
Line 44: Line 44:
The rest of this document will focus on the Phong part of the shading tree explaining how the components work and how to create them.
The rest of this document will focus on the Phong part of the shading tree explaining how the components work and how to create them.


==Using the shader==
==Using the Phong shader==


The most basic method of using the phong shader is to enable it in your model texture using the <code>"$phong" "1"</code> directive and including a phong mask in the alpha channel of the normal texture and either a phong exponent texture or phong constant.
To use phong shading with your models, you need to add the directive <code>"$phong" "1"</code> into your material's VMT file. This tells the shader to include a phong pass when executing the shader code. You then need to define a phong mask in your normal maps alpha channel, a phong exponent either as a texture or constant and finally, parameters for remapping the fresnel output.


The following example is taken from [[Half-Life 2: Episode One]] and comes from the file <code>materials/models/Alyx/alyx_faceandhair.vmt</code> which controls the texture on Alyx's face:
===Phong shader parameters===
 
The following is a list of confirmed VMT parameters that are needed to enable the phong effect.
 
*<code>"$phong" "0/1"</code> - Disable/enabled a phong pass for this material.
*<code>"$phongexponenttexture" "path/to/vtf"</code> - Filename of texture which defines phong exponent per texel.
*<code>"$phongexponent" "0..255"</code> - Phong exponent for local specular lights. Overides <code>$phongexponenttexture</code> applying a defined constant exponent value over the whole texture. Default 5.0.
*<code>"$phongboost" "0..n"</code> - Phong overbrightening factor. The phong mask channel should be authored to account for this. Default 1.0.
*<code>"$phongfresnelranges" "[n n n]"</code> - Parameters for remapping fresnel output, Default [0 0.5 1].
 
{{warning|You must include all of these parameters, even if you only intend to use the default values, and also include an alpha channel in your normal map texture (as defined in <code>$bumpmap</code>). Ommiting one or more can result in the phong effect not being rendered.}}
 
===Example VMT for Phong===
 
The following simplified example is taken from [[Half-Life 2: Episode One]] and comes from the file <code>materials/models/Alyx/alyx_faceandhair.vmt</code> which controls the texture on Alyx's face:


<pre>
<pre>
Line 59: Line 73:
"$model" "1"
"$model" "1"


// -- From here down is new stuff which will only be applied if $phong is set to 1 --
"$phong" "1"
"$phong" "1"
"$ambientocclusiontexture" "models/alyx/alyx_occlusion"
// "$phongexponent" 33
// "$phongexponent" 33
"$phongexponenttexture" "models/Alyx/alyx_head_exponent"
"$phongexponenttexture" "models/Alyx/alyx_head_exponent"
Line 69: Line 81:
</pre>
</pre>


Lets break this down into it's component parts:
==Phong components and parameters in detail==


[[Image:Specvsexponentinphong2os.jpg|right|150px|thumb|Examples of the relationship between Phong (Specular) intensity and exponent values.]]
[[Image:Specvsexponentinphong2os.jpg|right|150px|thumb|Examples of the relationship between Phong (Specular) intensity and exponent values.]]
Line 91: Line 103:
{{note|Exponent values generally fall within the range 0 to 150. If you think of a texture channel has having a value from 0 to 255 or even just 0.0 to 1.0, the minimum value will map to an exponent of 1 while the maximum value will map to an exponent of 150.  Thus, it is possible to have texel values which map to floating point values between the integer values in the range of 0 to 150.  This number 150 is an arbitrary number Valve chose to correspond to a range found useful in practice. Choosing larger numbers can result in unwanted aliasing and this mapping was chosen to avoid it.}}
{{note|Exponent values generally fall within the range 0 to 150. If you think of a texture channel has having a value from 0 to 255 or even just 0.0 to 1.0, the minimum value will map to an exponent of 1 while the maximum value will map to an exponent of 150.  Thus, it is possible to have texel values which map to floating point values between the integer values in the range of 0 to 150.  This number 150 is an arbitrary number Valve chose to correspond to a range found useful in practice. Choosing larger numbers can result in unwanted aliasing and this mapping was chosen to avoid it.}}


==TODO==
===Phong boost===
 
The phong boost value is an overbrightening factor applied to the phong mask channel. The phong mask channel should be authored to take the phong boost value into account for this. Values are unbound and can even be negative although this would probably provide worthless results.
 
===Phong Frensel ranges===
 
==Unsupported and experimental parameters==
 
There are a number of other shader parameters which can be seen in some shipped VMT files or mentioned within the sample shader code  included in the Source SDK. These appeared around the time of Episode 1 and it's unclear if they are included as part of the phong pass or the improved shaders in general.
 
Consider the the following undocumented and unsupported by Valve as exact details of how they work and there effects are unavailable at time of writing:
 
*<code>$lightwarptexture</code> - 1D ramp texture for tinting scalar diffuse term. Mentioned in the SDK samples.
*<code>$phongalbedotint</code> - Allow the base/albedo texture to affect the colour tint of the phong hightlight? Possibly related to the green channel of the phong exponent mask. Seen in some [[Day of Defeat: Source|DoD:S]] player model VMTs.
*<code>$ambientocclusiontexture</code> - Ambient occlusion texture or "dirtmap". Mentioned in the SDK samples and seen in Episode 1 VMT for Alyx's face. Appears non functional?
 
==See Also==


Like, loads :D
==External Links==

Revision as of 15:55, 10 December 2006

Template:WIP

Warning.pngWarning:This is work in progress and will take more that 24 hours to complete. Please don't move it!
Alyx as rendered with the new Episode One lighting enhancements.

With the release of Half-Life 2: Episode One a number enhancments were made to the way lighting works within the Source engine. The emphasis was on global illumination in order to ground characters in the game worlds and make them seem to be truly present in their environment.

One of these enhancements was the addtion of Phong shading for players with graphic cards using ps_2_b or later pixel shaders - around 40% at the time of release. This new feature gives texture artists the the ability to include Phong terms which can be driven by specular masks and exponent textures. These integrate naturally with the existing lighting and provides greater definition, particularly to key characters such as Alyx Vance.

The Phong shading can also include a Fresnel term in order to heavily favor rim lighting cases as opposed to specular highlights. Under very bright lights, the specular rim highlights are often bright enough to bloom out in a dramatic fashion as a result of HDR post-processing.

A brief introduction to Phong shading

The following short introduction is not necessary knowledge to use the Source Phong shader, but does provide some technical insights as to how the technique works and may be of interest to some readers.

In simple terms, Phong shading is a technique used in 3D graphics to get better resolution of specular reflections. It was developed by Dr. Bui Tuong Phong at the University of Utah in 1973. His original publications combined the interpolation part of technique with his reflection model, the term Phong shading is commonly used to refer to either just the reflection model or to the combination of the reflection model and the interpolation method.

The Phong reflection equation expressed graphically.

The Phong reflection model

The Phong reflection model is basically a simplified method of deciding the shade of a specific point on a 3D surface.

  • It doesn't take into account second-order reflections often found in raytraced or diffuse rendering. To compensate an extra ambient lighting term is added to the scene that is rendered.
  • It divides the reflection from a surface into three subcomponents - specular reflection, diffuse reflection and ambient reflection.

Phong reflection is an empirical model based on informal observation. Dr. Phong observed that for very shiny surfaces the specular highlight was small and that the intensity fell off rapidly, while for duller surfaces it was larger and fell off more slowly.

Phong interpolation example.

Phong interpolation

Phong shading provides a better approximation to a per-pixel application of an underlying reflection model by assuming a smoothly varying surface normal vector. The Phong interpolation method works particularly well when applied to the Phong reflection model or to any reflection model that has small specular highlights.

In some modern hardware, variants of the interpolation algorithm are called "pixel shading" (this should not be confused with "pixel shaders"). Usually this means that the lighting calculations can be done per-pixel and include other lighting variables such as surface normals from a normap map which are interpolated across the polygon.

Phong in the Source engine

The episodic shader tree.

While the above gives a fairly basic explaination of Phong shading as a concept, the effect you seen in Episode One is in fact the result of a number of combined lighting effects working together. An overview of these effects and how they are combined can be seen in the diagram of the episodic shader tree.

With model lighting, Source uses methods which combine spatially varying directional irradiance samples from the radiosity solution with local light sources and environment mapping. On graphics hardware that supports 2.0 pixel shaders and lower, Source computes diffuse illumination from up to two local light sources, either per pixel or per vertex. On newer graphics chips with longer pixel shaders, Source includes specular contributions with Fresnel terms as well as more custom effects.

Phong shading is part of these extended effects and can be seen in the path starting bottom right of the shader tree. Phong exponent, mask and Fresnel terms are combined to give a specular term which is combined with the diffuse solution in the final output.

The rest of this document will focus on the Phong part of the shading tree explaining how the components work and how to create them.

Using the Phong shader

To use phong shading with your models, you need to add the directive "$phong" "1" into your material's VMT file. This tells the shader to include a phong pass when executing the shader code. You then need to define a phong mask in your normal maps alpha channel, a phong exponent either as a texture or constant and finally, parameters for remapping the fresnel output.

Phong shader parameters

The following is a list of confirmed VMT parameters that are needed to enable the phong effect.

  • "$phong" "0/1" - Disable/enabled a phong pass for this material.
  • "$phongexponenttexture" "path/to/vtf" - Filename of texture which defines phong exponent per texel.
  • "$phongexponent" "0..255" - Phong exponent for local specular lights. Overides $phongexponenttexture applying a defined constant exponent value over the whole texture. Default 5.0.
  • "$phongboost" "0..n" - Phong overbrightening factor. The phong mask channel should be authored to account for this. Default 1.0.
  • "$phongfresnelranges" "[n n n]" - Parameters for remapping fresnel output, Default [0 0.5 1].
Warning.pngWarning:You must include all of these parameters, even if you only intend to use the default values, and also include an alpha channel in your normal map texture (as defined in $bumpmap). Ommiting one or more can result in the phong effect not being rendered.

Example VMT for Phong

The following simplified example is taken from Half-Life 2: Episode One and comes from the file materials/models/Alyx/alyx_faceandhair.vmt which controls the texture on Alyx's face:

"vertexlitgeneric"
{
	"$basetexture" "models/Alyx/alyx_faceandhair"
	"$bumpmap" "models/alyx/alyx_head_normal"
	"$halflambert" 1
	"$nodecal" "1"
	"$model" "1"

	"$phong" "1"
//	"$phongexponent" 33
	"$phongexponenttexture" "models/Alyx/alyx_head_exponent"
	"$phongboost"	"6"
	"$phongfresnelranges"	"[0.05 0.5 1]"
}

Phong components and parameters in detail

Examples of the relationship between Phong (Specular) intensity and exponent values.

Phong mask and exponent texture

The phong mask is a greyscale image stored in the alpha channel of the models normal map (defined by $bumpmap). This mask defines on a per texel basis the intensity, or strengh, of the the phong highlight for that texel. Black represents the lowest intensity and shows no phong highlight at all (literally knocking it out), whereas white represents the brightest, or full intensity for that texel.

Alyx's Phong Mask texture.

The phong exponent defines the "tightness" of the highlight. A higher exponent results in a smaller, tighter highlight while a lower exponent results in a broader flatter one.

Different materials will exhibit highlights (tighter or broader) based upon their physical properties. A harder, smoother material such as a pool ball may have a very tight highlight while a softer, rougher material like a rubber tire may have a very broad specular highlight. In the Phong lighting equation, there is an exponent which mathematically controls the shape of the resulting highlight (tight or broad), hence the naming.

Alyx's Phong exponent texture.

The phong exponent texture can be defined in one of two ways:

  • $phongexponenttexture defines a texture which on a per texel bases defines the exponent value for a surface.
  • $phongexponent overrides the exponent texture and is useful during development to get a quick overall specular term without painting a channel. It is then usually just commented out when a given texture map gets made and added to the mix for a given material.

The phong exponent texture uses the red and green channels of the image for different purposes. The red channel defines the phong exponent value and the green for albedo tinting. However, albedo tinting is a "work in progress" feature and currently un-supported in the current shader. For this reason, and the sake of simplicity, you should use greyscale for exponent textures.

Note.pngNote:Exponent values generally fall within the range 0 to 150. If you think of a texture channel has having a value from 0 to 255 or even just 0.0 to 1.0, the minimum value will map to an exponent of 1 while the maximum value will map to an exponent of 150. Thus, it is possible to have texel values which map to floating point values between the integer values in the range of 0 to 150. This number 150 is an arbitrary number Valve chose to correspond to a range found useful in practice. Choosing larger numbers can result in unwanted aliasing and this mapping was chosen to avoid it.

Phong boost

The phong boost value is an overbrightening factor applied to the phong mask channel. The phong mask channel should be authored to take the phong boost value into account for this. Values are unbound and can even be negative although this would probably provide worthless results.

Phong Frensel ranges

Unsupported and experimental parameters

There are a number of other shader parameters which can be seen in some shipped VMT files or mentioned within the sample shader code included in the Source SDK. These appeared around the time of Episode 1 and it's unclear if they are included as part of the phong pass or the improved shaders in general.

Consider the the following undocumented and unsupported by Valve as exact details of how they work and there effects are unavailable at time of writing:

  • $lightwarptexture - 1D ramp texture for tinting scalar diffuse term. Mentioned in the SDK samples.
  • $phongalbedotint - Allow the base/albedo texture to affect the colour tint of the phong hightlight? Possibly related to the green channel of the phong exponent mask. Seen in some DoD:S player model VMTs.
  • $ambientocclusiontexture - Ambient occlusion texture or "dirtmap". Mentioned in the SDK samples and seen in Episode 1 VMT for Alyx's face. Appears non functional?

See Also

External Links