Shader: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (The MS HLSL page had moved)
mNo edit summary
 
(66 intermediate revisions by 35 users not shown)
Line 1: Line 1:
{{stub}}
{{LanguageBar}}
[[category:Programming]] [[category:Glossary]]
{{see also|[[:Category:Shaders]]}}


A [[shader]] is a piece of software that instead of executing on the CPU, it executes on the GPU.


[[Shader]]s provide great control over what is rendered, and can perform operations of vertices, pixels, and some others.
A '''shader''' is software which runs on a [[Wikipedia:Graphics processing unit|graphics card]] to  determine how an object should be drawn. Source uses shaders for everything in the 3D world.


The [[Source Engine]] uses [[HLSL]] for [[shader]]s. There is another language called '''[[Cg]]''' (Which stands for ''''C''' for '''G'''raphics'), which was developed alongside [[HLSL]] by [[Wikipedia:NVIDIA|NVIDIA]].
Shaders are manipulated with parameters stored in [[material]] files. While the most common are quite simple, very complex ones exist to handle effects like real-time shadowing, lighting and refraction.


[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/HLSL_Shaders.asp Microsoft HLSL website]
If a shader is missing, on a material or model, the surface will appear as a white wireframe. Pink and black squares are not the product of a missing shader, but instead are generated when a material itself is missing.
{{warning|Source's default [[VBSP]] doesn't recognize custom lightmapped shaders. Use {{slamminsrc|4.1}} or {{mapbase|4.1|addtext='s}} [[VBSP]]s, which were modified to allow [[Lightmap]] generation for custom shaders.}}
==Types==
There are two variations of shaders, Pixel shaders and Vertex shaders, each of which performs a different task in the rendering pipeline. Shaders form a replacement for the fixed function pipeline and allow developers greater control over rendering output by providing the ability to modify pixels and vertices dynamically. The SDK includes many [[:Category:Shaders|existing shaders]].


==Shader languages==
There are currently three main shader languages: [[HLSL|High Level Shader Language (HLSL)]], [[CG|C for Graphics (Cg)]] and [[Wikipedia:GLSL|OpenGL Shading Language (GLSL)]]. The Source engine uses [[HLSL]] based shaders. However Cg is so similar that most Cg shaders can be quickly and easily ported to HLSL.


There are typically 2 classes of shaders that you can think of. Postprocessing and per object shaders. Postprocessing shaders are effects computed on a 2D texture. This 2D texture is typically built at the end of the main render function out of all of the verts in the frame buffer. There are functions in D3D to create a render target (the offline buffer - or the texture you will use) and render to that render target (this functionality is hidden to all of us sdk mod makers in higher level functions, but know it's there). Once you have information in that texture, you can use a shader to do all kinds of effects like motion blur, light bloom, depth of field, shadows, sharpen and on and on. In the source SDK, they provide a good example of this type of shader in sdk_postprocess and give comments at the top of this file (the .cpp one) as to where you should add code into the engine to actually "activate" the effect. Make sure you look at all three files so you understand what's going on (sdk_postprocess.cpp, sdk_postprocess_vs.fxc, and sdk_postprocess_ps.fxc).
==Shader models==
A shader model defines how ''advanced'' shading techniques are allowed to get on a graphics card. This prevents older graphics cards from being physically able to recognize newer shading techniques.


Per object shaders are handled a bit differently in this engine, in that you need to specify the shader you want to use in a material file. So if you wanted to have a per pixel lit car, for example, you would need to specify that the car use your specific shader.  I'm currently working on material shaders to perform dynamic lighting and dynamic reflections and will update the page as I find out more info.
Modern versions of [[Source]] support Shader Model 2.0 (including Pixel Shader 2.0b) and Shader Model 3.0. Games that use DirectX 11 (usually third-party like {{titanfall|1}} and {{strata|1}}), support Shader Model 5.0.
{{Note|Shaders written for SM3 may not work properly on Mac and Linux systems due to lack of support in Valve's runtime graphics wrapper, <code>togl</code>. You should plan to make a SM2.0b version of your shaders if you plan on supporting these systems.
{{confirm|Is this still the case for games using the Vulkan wrapper?}}}}


There are two types of shaders. [[Pixel shader]] and [[Vertex shader]].
When creating shaders for newer graphics cards, it's important to remember to support those with older cards, or you will quickly limit the specs of your game to only a select few. Older cards can require so called "shader fallbacks" to be specified, where a backup shader (using an older shader model) will be used if the newer shader fails.


==See Also==
If you want to learn more about the detailed specs of different Shader Models, read the [[Wikipedia:High Level Shader Language|Wikipedia article]].
* [[Wikipedia:Shader]]
 
For information on authoring shaders for use in the Source engine, please see [[Shader Authoring]].
 
==Vertex shaders==
Vertex shaders are applied for each vertex run on a programmable pipeline. Its most basic goal is to transform geometry into screenspace coordinates so that the Pixel shader can rasterize an image. Vertex shaders can modify these position coordinates to perform mesh deformation. They can also receive additional information from the mesh, including normals, tangents, and texture coordinates. The vertex shader then writes to output registers; the written values are then interpolated across the vertices in the pixel shaders. Vertex shaders cannot create vertices.
 
A heavily commented example vertex shader, ready for use in Source is provided below.
 
===Example vertex shader===
This is a pass through shader - in so far as it makes no major modification to the vertex data, instead just passing the data through to the pixel shader stage.
 
{{CodeBlock|lines=31|<nowiki>// common vertex shader defines provided with this header
#include "common_vs_fxc.h"
 
// define an output structure
struct VS_OUTPUT
{
// position vector (float4)
float4 pos      : POSITION0;
 
// texture coordinates (uv - float2)
float2 texCoord  : TEXCOORD0;
};
 
// main function - note C style definition
// takes a position vector (float4)
// returns a VS_OUTPUT struct
VS_OUTPUT main( float4 inPos: POSITION )
{
// declare an empty VS_OUTPUT to fill
VS_OUTPUT o = (VS_OUTPUT) 0;
 
// compute the sign of the input position
inPos.xy = sign( inPos.xy);
 
// set the output position using the xy of the input
o.pos = float4( inPos.xy, 0.0f, 1.0f);
 
// get into range [0,1]
o.texCoord = (float2(o.pos.x, -o.pos.y) + 1.0f)/2.0f;
return o;
}</nowiki>}}
 
==Pixel shaders==
Pixel shaders are applied for each pixel rendered to the screen. A pixel shader expects input from interpolated vertex values, which it then uses to rasterize the image. Pixel shaders can produce a huge range of effects involving the color of individual pixels such as refraction, per-pixel lighting or reflection.
 
A heavily commented example pixel shader, ready for use in Source is provided below.
 
===Example pixel shader===
The pixel shader below is intended for use as a post-process shader and creates a grayscale effect.
 
{{CodeBlock|lines=15|<nowiki>// specify a texture sampler, the actual source of this is specified in a vmt
sampler2D Texture0 : register( s0 );<br>
// same function declaration style as vertex shaders
// pixel shaders return the colour value of the pixel (hence the float4)
float4 main( float2 texCoord  : TEXCOORD0 ) : COLOR
{
// sample the texture at the specified texture coordinates
float4 tex = tex2D( Texture0, texCoord );<br>   
// greyscale the pixel colour values
// - perform a dot product between the pixel colour and the specified vector
// - 0.222, 0.707, 0.071 is found throughout image processing for gray scale effects.
float4 grey = dot(float3(0.222, 0.707, 0.071), tex);<br> 
// return the pixel colour in the form of a float4.         
return grey;
}</nowiki>}}
 
==Applications of shaders in Source==
The Source engine provides for two separate forms of shaders, Postprocess and Per-Object, the majority of the effects and materials used within the Source engine rely heavily on their Pixel shader components.
 
===Postprocess===
A Postprocess shader is typically a Pixel shader that works on a quad rendered across the entire screen. The quad is textured with a copy of the frame buffer, the Pixel shader can then alter and modify the rendered output to create a variety of effects, such as basic color modification to more advanced processes such as motion blur and bloom.
 
{{Note| This information is out of date, and the files are no longer included in the SDK.  {{file|sdk_bloom|cpp}} and {{file|sdk_bloom.ps20|fxc}} define one possible shader that could be used as an alternative example}}
The Source SDK provides an example of this form of shader in the postprocess files ({{file|sdk_postprocess|cpp}}, {{file|sdk_postprocess_vs20|fxc}}, and {{file|sdk_postprocess_ps20|fxc}})
 
Advanced Postprocess shaders, such as the bloom and motion blur shaders included with source, may also need to use custom [[Render Targets]].  For more information on integrating a Postprocess shader with a mod, see [[Custom Postprocessing Effects]]
 
===Per-object===
A Per-Object shader in the Source engine is used on any object with the shader referenced in the relevant [[VMT|Valve Material (.vmt)]] file, such as a model or piece of brushwork. A Per-Object shader could be used to create a refractive material, modify a models vertices dynamically or other advanced rendering effects.
 
The Source SDK provides an example of a Per-Object shader in the lightmap files ({{file|sdk_lightmap|cpp}}, {{file|sdk_lightmap_vs20|fxc}}, and {{file|sdk_lightmap_ps20|fxc}})
 
==External links==
* [http://www.bit-tech.net/hardware/2005/07/25/guide_to_shaders/1 A bluffer's guide to Shader Models]
* [http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter01.html NVIDIA - The Cg tutorial]
* [https://developer.nvidia.com/gpugems/GPUGems/gpugems_part01.html NVIDIA - GPU Gems]
* [https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_part01.html NVIDIA - GPU Gems 2]
* [https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_part01.html NVIDIA - GPU Gems 3]
* {{wiki|Shader}} - a Wikipedia article on the subject.
* [http://www.moddb.com/games/half-life-2/tutorials/introduction-to-shaders Introduction to Shaders Tutorial from Wraiyth]
* [http://www.moddb.com/games/half-life-2/tutorials/post-process-shader Post-Process Shader Tutorial from Wraiyth]
 
 
[[Category:Glossary]]
[[Category:Programming]]
[[Category:Shaders|*]]
[[Category:Technical]]
 
[[Category:Material_System]]

Latest revision as of 03:19, 27 July 2025

English (en)Español (es)Русский (ru)Українська (uk)中文 (zh)Translate (Translate)
See also:  Category:Shaders


A shader is software which runs on a graphics card to determine how an object should be drawn. Source uses shaders for everything in the 3D world.

Shaders are manipulated with parameters stored in material files. While the most common are quite simple, very complex ones exist to handle effects like real-time shadowing, lighting and refraction.

If a shader is missing, on a material or model, the surface will appear as a white wireframe. Pink and black squares are not the product of a missing shader, but instead are generated when a material itself is missing.

Warning.pngWarning:Source's default VBSP doesn't recognize custom lightmapped shaders. Use Slammin' Source Map Tools Slammin' Source Map Tools or Mapbase Mapbase's VBSPs, which were modified to allow Lightmap generation for custom shaders.

Types

There are two variations of shaders, Pixel shaders and Vertex shaders, each of which performs a different task in the rendering pipeline. Shaders form a replacement for the fixed function pipeline and allow developers greater control over rendering output by providing the ability to modify pixels and vertices dynamically. The SDK includes many existing shaders.

Shader languages

There are currently three main shader languages: High Level Shader Language (HLSL), C for Graphics (Cg) and OpenGL Shading Language (GLSL). The Source engine uses HLSL based shaders. However Cg is so similar that most Cg shaders can be quickly and easily ported to HLSL.

Shader models

A shader model defines how advanced shading techniques are allowed to get on a graphics card. This prevents older graphics cards from being physically able to recognize newer shading techniques.

Modern versions of Source support Shader Model 2.0 (including Pixel Shader 2.0b) and Shader Model 3.0. Games that use DirectX 11 (usually third-party like Titanfall and Strata Source), support Shader Model 5.0.

Note.pngNote:Shaders written for SM3 may not work properly on Mac and Linux systems due to lack of support in Valve's runtime graphics wrapper, togl. You should plan to make a SM2.0b version of your shaders if you plan on supporting these systems.
Confirm:Is this still the case for games using the Vulkan wrapper?

When creating shaders for newer graphics cards, it's important to remember to support those with older cards, or you will quickly limit the specs of your game to only a select few. Older cards can require so called "shader fallbacks" to be specified, where a backup shader (using an older shader model) will be used if the newer shader fails.

If you want to learn more about the detailed specs of different Shader Models, read the Wikipedia article.

For information on authoring shaders for use in the Source engine, please see Shader Authoring.

Vertex shaders

Vertex shaders are applied for each vertex run on a programmable pipeline. Its most basic goal is to transform geometry into screenspace coordinates so that the Pixel shader can rasterize an image. Vertex shaders can modify these position coordinates to perform mesh deformation. They can also receive additional information from the mesh, including normals, tangents, and texture coordinates. The vertex shader then writes to output registers; the written values are then interpolated across the vertices in the pixel shaders. Vertex shaders cannot create vertices.

A heavily commented example vertex shader, ready for use in Source is provided below.

Example vertex shader

This is a pass through shader - in so far as it makes no major modification to the vertex data, instead just passing the data through to the pixel shader stage.

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
// common vertex shader defines provided with this header #include "common_vs_fxc.h" // define an output structure struct VS_OUTPUT { // position vector (float4) float4 pos  : POSITION0; // texture coordinates (uv - float2) float2 texCoord  : TEXCOORD0; }; // main function - note C style definition // takes a position vector (float4) // returns a VS_OUTPUT struct VS_OUTPUT main( float4 inPos: POSITION ) { // declare an empty VS_OUTPUT to fill VS_OUTPUT o = (VS_OUTPUT) 0; // compute the sign of the input position inPos.xy = sign( inPos.xy); // set the output position using the xy of the input o.pos = float4( inPos.xy, 0.0f, 1.0f); // get into range [0,1] o.texCoord = (float2(o.pos.x, -o.pos.y) + 1.0f)/2.0f; return o; }

Pixel shaders

Pixel shaders are applied for each pixel rendered to the screen. A pixel shader expects input from interpolated vertex values, which it then uses to rasterize the image. Pixel shaders can produce a huge range of effects involving the color of individual pixels such as refraction, per-pixel lighting or reflection.

A heavily commented example pixel shader, ready for use in Source is provided below.

Example pixel shader

The pixel shader below is intended for use as a post-process shader and creates a grayscale effect.

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
// specify a texture sampler, the actual source of this is specified in a vmt sampler2D Texture0 : register( s0 );<br> // same function declaration style as vertex shaders // pixel shaders return the colour value of the pixel (hence the float4) float4 main( float2 texCoord  : TEXCOORD0 ) : COLOR { // sample the texture at the specified texture coordinates float4 tex = tex2D( Texture0, texCoord );<br> // greyscale the pixel colour values // - perform a dot product between the pixel colour and the specified vector // - 0.222, 0.707, 0.071 is found throughout image processing for gray scale effects. float4 grey = dot(float3(0.222, 0.707, 0.071), tex);<br> // return the pixel colour in the form of a float4. return grey; }

Applications of shaders in Source

The Source engine provides for two separate forms of shaders, Postprocess and Per-Object, the majority of the effects and materials used within the Source engine rely heavily on their Pixel shader components.

Postprocess

A Postprocess shader is typically a Pixel shader that works on a quad rendered across the entire screen. The quad is textured with a copy of the frame buffer, the Pixel shader can then alter and modify the rendered output to create a variety of effects, such as basic color modification to more advanced processes such as motion blur and bloom.

Note.pngNote: This information is out of date, and the files are no longer included in the SDK. 🖿sdk_bloom.cpp and 🖿sdk_bloom.ps20.fxc define one possible shader that could be used as an alternative example

The Source SDK provides an example of this form of shader in the postprocess files (🖿sdk_postprocess.cpp, 🖿sdk_postprocess_vs20.fxc, and 🖿sdk_postprocess_ps20.fxc)

Advanced Postprocess shaders, such as the bloom and motion blur shaders included with source, may also need to use custom Render Targets. For more information on integrating a Postprocess shader with a mod, see Custom Postprocessing Effects

Per-object

A Per-Object shader in the Source engine is used on any object with the shader referenced in the relevant Valve Material (.vmt) file, such as a model or piece of brushwork. A Per-Object shader could be used to create a refractive material, modify a models vertices dynamically or other advanced rendering effects.

The Source SDK provides an example of a Per-Object shader in the lightmap files (🖿sdk_lightmap.cpp, 🖿sdk_lightmap_vs20.fxc, and 🖿sdk_lightmap_ps20.fxc)

External links