Title: Vertex and Pixel Programs
1Vertex and Pixel Programs
2Remember the Graphics Pipeline?
Geometric Operations
Transform vertices and normals by modelview matrix
Per-Vertex Operations
Automatic Texture Coordinates ? Lighting
Primitive Assembly
Special Clipping ? Projection ? Frustum Clipping
? Rasterize
Vertex ? Fragments
Per-Fragment Operations
Texture-mapping ? Fog ? Stencil test ? Depth test
? Blending
Display
3The Standard Graphics Pipeline
- What we have done so far is called a
fixed-function pipeline. - The per-vertex operations are fixed. The lighting
functions are fixed to the Phong lighting model. - Similarly, the per-fragment operations are fixed.
The Gouroud shading model is used if smooth
shading is requested. - However, with the new generation of graphics
processors, the vertex processor and fragment
processor are now both programmable.
Phong Lighting Model Vertex color
Coloremission,material Colorglobal_ambient_l
ight x Colorambient,material S
(1/(k0k1dk2d))i x (v.d)ni x (Colorambient,refle
ction Colordiffuse,reflection
Colorspecular,reflection)i
where Colorambient,reflection
Colorambient,light x Colorambient,material Colord
iffuse,reflection L.N x Colordiffuse,light
x Colordiffuse,material Colorspecular,reflection
N.Hshininess x Colorspecular,light x
Colorspecular,material
4Programmable Shaders
- We now have
- Programmable Vertex Shaders (or Vertex Programs),
and - Programmable Fragment Shaders (or Fragment
Programs) - These are written in high-level language,
compiled, and loaded to the GPU. - At the time each vertex undergoes per-vertex
operations, the vertex program is run on the
vertex. - Similarly for the fragment program.
- Some high-level shading languages include
- Microsofts High-Level Shading Language (HLSL),
- Cg (C for Graphics), and
- GLSL (OpenGL Shading Language)
- We introduce Cg
- Cg works with both OpenGL and Microsofts DirectX
- Download Cg from http//developer.nvidia.com/objec
t/cg_toolkit.html
5Cg
- Cg is a high-level language for the GPU.
- Syntactically, it is similar to C.
- Write your Cg code in its own file, for example
myvertexshader.cg - In your C/C main source code, include the Cg
header files, so that you can link your C/C
code to your Cg code - include ltCg/cg.hgt
- include ltCg/cgGL.hgt
- Then, in your C/C code, call the following two
functions to create and load your Cg program - cgCreateProgramFromFile( )
- cgGLLoadProgram( )
- You can create and load multiple Cg programs. To
use a particular Cg program that you have loaded,
call - cgGLBindProgram( )
- cgGLEnableProfile( )
6Cg Program Inputs
- Varying inputs are used for data that is
specified with each element of the stream of
input data. - For example, the varying inputs to a vertex
program are the per-vertex values that are
specified in vertex arrays. - For a fragment program, the varying inputs are
the interpolants, such as texture coordinates. - Uniform inputs are used for values that are
specified separately from the main stream of
input data, and dont change with each stream
element. - For example, a vertex program typically requires
a transformation matrix as a uniform input. - Often, uniform inputs are thought of as graphics
state.
7Vertex Program outputs
- The following binding semantics are available in
all Cg vertex profiles for output from vertex
programs POSITION, PSIZE, FOG, COLOR0COLOR1,
and TEXCOORD0TEXCOORD7. - In OpenGL, these predefined names implicitly
specify the mapping of the inputs to particular
hardware registers. - All vertex programs must declare and set a vector
output that uses the POSITION binding semantic.
This value is required for rasterization. - Note that values associated with some vertex
output semantics, in particular POSITION, are
intended for and are used by the rasterizer.
These values cannot actually be used in the
fragment program, even though they appear in the
input.
8Cg Example Vertex Lighting
Vertex program C5E1v_basiclight.cg
void C5E1v_basicLight(float4 position
POSITION, float3 normal
NORMAL, out float4 oPosition
POSITION, out float4 color
COLOR, uniform float4x4
modelViewProj, uniform float3
globalAmbient, uniform float3
lightColor, uniform float3
lightPosition, uniform float3
eyePosition, uniform float3 Ke,
uniform float3 Ka,
uniform float3 Kd, uniform float3
Ks, uniform float shininess)
oPosition mul(modelViewProj, position)
float3 P position.xyz float3 N normal
// Compute emissive term float3 emissive Ke
// Compute ambient term float3 ambient Ka
globalAmbient // Compute the diffuse term
float3 L normalize(lightPosition - P) float
diffuseLight max(dot(N, L), 0) float3
diffuse Kd lightColor diffuseLight //
Compute the specular term float3 V
normalize(eyePosition - P) float3 H
normalize(L V) float specularLight
pow(max(dot(N, H), 0), shininess) if
(diffuseLight lt 0) specularLight 0 float3
specular Ks lightColor specularLight
color.xyz emissive ambient diffuse
specular color.w 1
9Passing uniform inputs from C program to Cg
program
define GET_PARAM(name) \ myCgVertexParam_name
\ cgGetNamedParameter(myCgVertexProgram,
name) \ checkForCgError("could not get "
name " parameter") myCgVertexParam_modelVie
wProj cgGetNamedParameter(myCgVertexProgram,
"modelViewProj") checkForCgError("could not
get modelViewProj parameter")
GET_PARAM(globalAmbient) GET_PARAM(lightColor)
GET_PARAM(lightPosition) GET_PARAM(eyePositi
on) GET_PARAM(Ke) GET_PARAM(Ka)
GET_PARAM(Kd) GET_PARAM(Ks)
GET_PARAM(shininess)
static void setBrassMaterial(void) const
float brassEmissive3 0.0, 0.0, 0.0,
brassAmbient3 0.33, 0.22, 0.03,
brassDiffuse3 0.78, 0.57,
0.11, brassSpecular3 0.99,
0.91, 0.81, brassShininess
27.8 cgSetParameter3fv(myCgVertexParam_Ke,
brassEmissive) cgSetParameter3fv(myCgVertexPara
m_Ka, brassAmbient) cgSetParameter3fv(myCgVerte
xParam_Kd, brassDiffuse) cgSetParameter3fv(myCg
VertexParam_Ks, brassSpecular)
cgSetParameter1f(myCgVertexParam_shininess,
brassShininess)
10Passing Normal and Position
- To perform fragment (Phong) rendering, the
fragment shader needs to know the position and
normal of the fragment. - Since the fragment program cannot read the
POSITION input, we need to use another parameter
to pass position. - So, we pass the position and normal in the
TEX_COORD0 and TEX_COORD1 parameters
respectively. - Note that these texture coordinates parameters
are automatically bi-linearly interpolated when
passed from vertex to fragment programs.
11Cg Example Fragment Lighting
Vertex program C5E2v_fragmentLighting.cg
Fragment program C5E3f_basicLight.cg
void C5E2v_fragmentLighting(float4 position
POSITION, float3
normal NORMAL, out
float4 oPosition POSITION,
out float3 objectPos TEXCOORD0,
out float3 oNormal TEXCOORD1,
uniform float4x4
modelViewProj) oPosition mul(modelViewProj,
position) objectPos position.xyz oNormal
normal
void C5E3f_basicLight(float4 position
TEXCOORD0,
float3 normal TEXCOORD1,
out float4 bcolor COLOR,
uniform float3 globalAmbient,
uniform float3 lightColor, uniform
float3 lightPosition, uniform
float3 eyePosition, uniform float3
Ke, uniform float3 Ka,
uniform float3 Kd, uniform float3
Ks, uniform float shininess)
float3 P position.xyz float3 N
normalize(normal) float3 emissive Ke
float3 ambient Ka globalAmbient float3 L
normalize(lightPosition - P) float
diffuseLight max(dot(L, N), 0) float3
diffuse Kd lightColor diffuseLight
float3 V normalize(eyePosition - P) float3 H
normalize(L V) float specularLight
pow(max(dot(H, N), 0), shininess) if
(diffuseLight lt 0) specularLight 0 float3
specular Ks lightColor specularLight
bcolor.xyz emissive ambient diffuse
specular bcolor.w 1
12Passing Matrix Information from OpenGL to Cg
- In the examples provided by the Cg download, the
matrix calculations are all manually programmed. - But, suppose we want to use the OpenGL projection
and modelview matrices and pass them to the Cg
shaders. - From http//nehe.gamedev.net/data/lessons/lesson.a
sp?lesson47
In the vertex program
OUT.HPos mul(ModelViewProj, IN.position)
In the C program
modelViewMatrix cgGetNamedParameter(cgProgram,
"ModelViewProj")
cgGLSetStateMatrixParameter(modelViewMatrix,
CG_GL_MODELVIEW_PROJECTION_MATRIX,
CG_GL_MATRIX_IDENTITY)