What is Cg?
So what is Cg and where does it fit in with things today? In functional terms, it sits in between the GPU and a graphics API and abstracts the GPU and its functions and features into a programming language for the GPU.
Today, DirectX 8.x and OpenGL 1.3 have the ability to command the shader hardware on today's DX8 class' GPU's. To show how it's done with DirectX 8, the shader hardware is exposed via a number of functions and interfaces. The program queries the capabilities of the hardware and if it detects full shader hardware, you can define your shader programs and then execute them using some more functions that DirectX 8 exposes. The program passes them to the DX8 driver for the card which then executes them on the hardware as part of the render process.
Here's an example of an extremely simple shader program in DirectX 8.
Now in this extremely simple shader program, the shader announces that it's Vertex Shader 1.0 compatible with "vs.1.0", does a 4x4 matrix transformation using the "m4x4" instruction and sets up a constant colour, c8 by moving it into oDO. In the example above, oPos and oD0 are registers on the card, slightly abstracted by DX8 but which all DX8 hardware supports and m4x4 and mov are instructions that all DX8 shader hardware supports."vs.1.0" \ "m4x4 oPos , v0 , c4" \ "mov oD0 , c8";
Now in that very simple shader program, you might think that things look easy but that's because the shader program isn't doing much. Now consider the following snippet from the NVIDIA presentation we were given that implements a very simple Phong shader, which makes a surface look a bit like plastic. In terms of shader complexity, a Phong shader is pretty simple, but look at the number of instructions needed to do it.
So you can see that to do even pretty simple things requires a bit of work and it isn't readily observable that it's even a Phong shader being implemented.
Added to that is the fact that not every developer in the world enjoys writing assembly style code and you can see that while shader hardware is a good thing, giving developers easy access to the hardware and the rendering pipeline, it's not incredibly easy to use and this is what Cg is for.
It's basically a compiler and a set of tools that you can download that outputs shader programs that DX8 or OpenGL 1.3 can understand. The compiler is loaded at runtime while your 3D program executes and your 3D program passes Cg shaders to the runtime compiler which compiles and optimises in realtime, often with hardware specific optimisations and then passes them to the driver like before.
So it's a layer between the 3D program and the render API that outputs shader programs but doesn't require the developer to write complex assembly like code. To illustrate this, here's the same Phong shader in the new language, Cg.
So you have identical functionality to the Phong shader above, in two lines of easy to read code (maybe not by you or me!) for the developer. This has the knock on effect of code being easier to maintain. Imaging writing a shader in the old format and coming back to it 2 months later to fix a clamping error or something similar? Even well documented assembly style code is hard to maintain so you can see where Cg helps things.
The runtime compiler (think Java, only just for graphics and a whole lot faster) takes care of the translation for the developer who can get on with writing more complex effects, more effects in total and basically doing more with the hardware. The language is like regular C by design, for ease of use and to make it easy to learn.
I'll leave you with a look at something possible today and how Cg helps things. While it's not totally clear from the screengrab, each point on the face uses a different shader program. Extrapolate to using many shader programs for effects all over your rendered scene and think about the complexity of writing shader programs as we saw above and you can see again why the level of abstraction provided by Cg is needed.
Lets take a look at what Cg means for the industry and you the consumer.