Notes
Slide Show
Outline
1
Cg: C for Graphics
  • Jon Moon


  • Based on slides by Eugene Lee
2
Overview
  • Cg Basics
  • Vertex Shaders
  • Fragment Shaders
  • Using Cg in OpenGL
3
What is Cg?
  • Cg is a high level shader language
    • Made by NVIDIA, but supports other GPUs
    • Programmer writes in a language similar to C
    • Cg compiler produces hardware-specific optimized assembly code
4
Halflife 1 vs. Halflife 2
5
http://www.daionet.gr.jp/~masa/rthdribl/index.html
6
Overview
  • Motivation
  • Vertex Shaders
  • Fragment Shaders
  • Using Cg in OpenGL


  • Questions?
7
The Vertex Shader
  • Program executed once per vertex
  • Takes per-vertex input such as position, normal, color, light position, etc.
  • Determines per-vertex data such as position, color, depth, etc.
    • But can do more!
8
The Vertex Shader
9
A Vertex Program
  • struct VertexInput {
  • float4 position : POSITION;
  • float3 normal   : NORMAL;
  • }


  • void NormalShade(  VertexInput input,
  • out float4 outPosition  : POSITION,
  • out float3 outColor     : COLOR,
  •     const uniform float4x4 modelViewProjMatrix)
  • {
  • outPosition = mul(modelViewProjMatrix, input.position);
  • outColor = abs(input.normal);
  • }


10
Binding Semantics
  • Predefined “names”
  • POSITION, NORMAL, etc.


11
Vertex Shader: Input
  • Varying parameters
    • Color, normal, texture coordinates, etc.
    • Data specified for each element


12
Vertex Shader: Input
  • Uniform Parameters
    • Data that remains constant over each element
    • Parameter shadowing


13
Vertex Shader: Output
  • Output serves as varying input to fragments
  • “Custom data” usually output as texcoords



14
Types in Cg
  • Syntax similar to C
  • Basic types
    • int, float, half, fixed, bool
  • Vector/Matrix types
    • int4, float3, bool2, float4x4
  • Arrays
    • int a[3], float4x4 matrices[4][4]
15
Playing with types
  • Vector initialization and swizzling
    • float4 vec4 = float4(1, 1, 1, 0);
    • float3 vec3 = vec4.yzw;
    • float3 color = vec3.rgb;
    • float3 position = 1.xxx;
16
Overview
  • Motivation
  • Vertex Shaders
  • Fragment Shaders
  • Using Cg in OpenGL


  • Questions?
17
The Fragment Shader
  • Program executed once per rasterized pixel.
  • Takes varying output from vertex program.
    • Certain outputs, like TEXCOORD0 interpolated.
  • Determines final color, depth for pixel.


18
The Fragment Shader
19
A Fragment Program


20
A Fragment Program
21
Performance
  • Fragment Programs are Expensive!
    • Try to do as much as possible in vertex programs.
    • Try to keep fragment programs small.
  • Note: not all hardware supports fragments
    • Rhodes 453 has Quadro FX GPU’s, which DO support fragment programs
22
Overview
  • Motivation
  • Vertex Shaders
  • Fragment Shaders
  • Using Cg in OpenGL


  • Questions?
23
Initializing Cg
  • Create a context
    • CGcontext cgContext = CgGL.cgCreateContext();
  • Select and enable Profile
    • int cgVertexProfile = CgGL.CG_PROFILE_VP20;
    • CgGL.cgGLEnableProfile(cgVertexProfile);
  • Create & Load program
    • CGprogram cgVertexProgram  = CgGL.cgCreateProgramFromFile(cgContext, CgGL.CG_SOURCE, "Normal.cg", cgVertexProfile, "Normal", null);
    • CgGL.cgGLLoadProgram(cgVertexProgram1);
24
Executing Cg
  • Get handles for parameters
    • CGparameter mvpMatrix = CgGL.cgGetNamedParameter(cgVertexProgram, “ModelViewProjMatrix”);
  • Set parameters
    • CgGL.cgGLSetStateMatrixParameter( mvpMatrix, CgGL.CG_GL_MODELVIEW_PROJECTION_MATRIX, CgGL.CG_GL_MATRIX_IDENTITY)
  • Bind program
    • CgGL.CgGLBindProgram(cgVertexProgram);
  • Rendering
    • glBegin()…
25
Cg in Action: Normal Shader
  • First demo: using 1 vertex shader to shade a cube based on its normal
  • Based on OpenGLDemo02 from last week
  • First look at Normal.cg, then at the Java code to actually use it
26
Normal.cg
  • struct VertexInput {
  •     float4 position : POSITION;
  •     float3 normal : NORMAL;
  • };


  • struct VertexOutput {
  •     float4 position : POSITION;
  •     float3 color : COLOR0;
  • };


  • VertexOutput Normal(const VertexInput input,
  •     const uniform float4x4 ModelViewProjMatrix) {
  •     VertexOutput output;


  •     output.position = mul(ModelViewProjMatrix, input.position);
  •     output.color = (input.normal+1)/2;
  •     return output;
  • }
27
Vertex.java: declarations
  • protected CGcontext cgContext;
  • protected int cgVertexProfile;


  • protected static CGprogram cgVertexProgram;


  • protected static CGparameter cgModelViewProjMatrix;
28
Vertex.java: initializations
  •  cgContext = CgGL.cgCreateContext();


  •  cgVertexProfile = CgGL.CG_PROFILE_VP20;


  •  CgGL.cgGLEnableProfile( cgVertexProfile);


  •  cgVertexProgram  = CgGL.cgCreateProgramFromFile( cgContext, CgGL.CG_SOURCE, "Normal.cg", cgVertexProfile, "Normal", null);


  •  CgGL.cgGLLoadProgram(cgVertexProgram);


  •  cgModelViewProjMatrix = CgGL.cgGetNamedParameter( cgVertexProgram, "ModelViewProjMatrix");


29
Vertex.java: Display loop
  • CgGL.cgGLBindProgram(cgVertexProgram);


  • CgGL.cgGLSetStateMatrixParameter( cgModelViewProjMatrix, CgGL.CG_GL_MODELVIEW_PROJECTION_MATRIX, CgGL.CG_GL_MATRIX_IDENTITY);
30
More than 1 Vertex Program
  • Can use different vertex (fragment) programs for different geometry!
  • Initialize programs as you would normally
    • 1 context, 1 vertex profile, many programs, many loads, etc.
  • In display loop, bind appropriate VP before gl_Begin() … gl_End().
  • To use another VP, simply bind to it before the next gl_Begin() … gl_End().
31
TwoVertex.java
  • Code very similar to Vertex.java
  • We load the pastel normal shader for the front and back faces, then load the bright normal shader for the rest of the cube
  • Note that we needed to gl_End() after the first 2 faces, then bind our next VP, then gl_Begin(GL_QUADS) again
32
SinWave.cg
  • float3 SinWave(float3 tex : TEXCOORD0) : COLOR {
  • return (sin(sin(23*tex.x*tex.y)-10*tex.y)+1)/2;
  • }


  • This shader is just using the texture coordinates, and some math.
  • Like position and normal, these are made available by OpenGL automatically
    • But if SinWave needed other parameters, we would obtain and modify them as usual.
33
Fragment.java: declaration, init
  • Very similar to Vertex, except with all “vertex”es replaced with “fragment”s
  • We make sure to specify the texture coordinates for the corners of each face
    • Texture coords are interpolated across polygons, so fragment programs can use them readily

34
Lambertian, a la PA1
  • Vertex program finds the normal and light vectors in world space, outputting those as COLOR0, COLOR1
  • Fragment program gets interpolated normal, light vector for each pixel and calculates lighting


35
Lambertian.java
  • Does standard declare, init:
    • 1 context, 2 profiles (create, enable),  2 programs (create, load)
    • Gets, sets all necessary variables for both programs
    • In display loop, bind both VP and FP
    • That’s it!



36
Some Tips
  • Check for errors!
    • CgErrorException.checkCgError();
    • Debug output in shaders
    • Normals, incident directions, different terms in BRDFs, etc.
  • Can compile .cg programs
    • cgc –profile vp20 –entry (function name) Program.cg
37
PA1: Cg Shaders portion
  • Write a couple of shading models
  • Must set the input parameters to cg programs.
  • Reference Lambertian shader code provided
38
Resources
  • NVIDIA Cg:
    • http://developer.nvidia.com/page/cg_main.html
  • Cg User Manual:
    • http://developer.nvidia.com/object/cg_users_manual.html
    • Also in Cg Toolkit folder
  • http://www.cgshaders.org