Cg Programming/Introduction
About Cg
editNvidia's programming language Cg (C for graphics) is one of several commonly used shading languages for real-time rendering (other examples are Direct3D's HLSL and OpenGL's GLSL). These shading languages are used to program shaders (i.e. more or less small programs) that are executed on a GPU (graphics processing unit), i.e. the processor of the graphics system of a computer – as opposed to the CPU (central processing unit) of a computer.
GPUs are massively parallel processors, which are extremely powerful. Most of today's real-time graphics in games and other interactive graphical applications would not be possible without GPUs. However, to take full advantage of the performance of GPUs, it is necessary to program them directly. This means that small programs (i.e. shaders) have to be written that can be executed by GPUs. The programming languages to write these shaders are shading languages. Cg is one of them. In fact, it was one of the first high-level shading languages for GPUs and has been implemented for several 3D graphics APIs (application programming interfaces), most importantly OpenGL and Direct3D. Today, the main reason for its popularity is its similarity to HLSL, which is the shading language of Microsoft's Direct3D.
About Learning Cg
editLearning Cg is beneficial for several reasons:
- It provides insight into modern real-time graphics, i.e. in the way GPUs work. Most high-performance real-time graphics applications (such as games) rely in some way or another on computations on GPUs, i.e. on shader programs.
- It enables you to program Cg and HLSL shaders (and thus highly efficient graphics applications) and understand other shading languages (such as GLSL) since the differences are not too big.
- It also enables you to better understand and use high-level graphics development tools since they are usually also based on shaders.
- It might help you to find a job as skills in shader programming are an advantage for game programmers, graphics developers, technical artists, etc.
Cg is not a particularly complicated programming language and typical programs (i.e. shaders) written in Cg are rather small. Nonetheless, learning Cg can be challenging for several reasons:
- Cg is only part of other graphics APIs (e.g. Nvidia's Cg Toolkit); thus, Cg is often learned together with a rather large graphics API, which is often necessary to set up the Cg code and the required graphics data (e.g. meshes and images) for a graphics application.
- Cg programming requires some knowledge about the programmable graphics pipeline that GPUs implement.
- Most Cg shaders require matrix and vector operations, which require some understanding of vector and matrix arithmetics.
Thus, if you like graphics but hate programming and mathematics, Cg can be quite challenging.
About this Wikibook
editThis wikibook was started with students in mind, who like neither programming nor mathematics. The basic motivation for this book is the observation that students are much more motivated to learn programming environments, programming languages and APIs if they are working on specific projects. Such projects are usually developed on specific platforms and therefore the approach of this book is to present Cg within specific platforms or frameworks, such as the game engine Unity, Nvidia's Cg Toolkit, etc. (As of now, only the part about vertex shaders and fragments shaders in Unity has been written.)
This wikibook tries to present specific versions of Cg that are used on specific platforms. There is, of course, a large overlap between these versions of Cg, but the differences are often subtle and can cause many problems. In fact, it is not a good idea to require a student to figure out how to adapt a textbook example of a Cg shader to the requirements of a certain platform. Instead, specific examples are presented for each platform.
The parts of this wikibook about Cg in Unity, Unity's Surface Shaders, Nvidia's Cg Toolkit, etc. are independent of each other. However, there is a certain progression:
- Unity requires hardly any set-up code; importing meshes and textures is usually a matter of drag&drop and some mouse clicks.
- Nvidia's Cg Toolkit requires several libraries, a compiler and a linker. And it requires quite a lot of set-up code.
Thus, even if you do not plan to use Cg within Unity, it might be a good idea to start programming Cg in Unity to quickly learn the basics without worrying about the annoying details of set-up code and import of meshes and images.
Each part of this wikibook is organized as a sequence of tutorials with working examples that produce certain effects. These examples determine which parts of the syntax of Cg is discussed. A comprehensive description of the syntax of Cg is provided in Nvidia's Cg Language Specification. A more accessible documentation is provided in Nvidia's Cg Tutorial.
Cg is designed for a GPU graphics pipeline as implemented in the OpenGL API and the Direct3D API. It is tempting to present this graphics pipeline stage by stage; however, this stage-by-stage approach tends to make it more difficult to understand how all the parts of the pipeline work together in various combinations to produce specific effects. Therefore, the discussion of each example also determines which parts of the graphics pipeline are discussed. Nonetheless, there are platform-independent sections to provide an overview of the graphics pipeline, an overview of the traditional matrix transformations, an overview of Cg-specific vector and matrix operations, a discussion of how to apply matrix transformations to points, vectors, and normals, and some other general topics.
What this Wikibook is not about
editObviously, this wikibook is not about GLSL or any other shading language than Cg and HLSL. (See the wikibook GLSL Programming for an introduction to GLSL.) Also, this wikibook is not about Cg for GLSL programmers. It's for everyone (including GLSL programmers). Furthermore, this wikibook is not about writing efficient Cg shaders. It's about enabling the reader to write working shaders. Optimizations add a whole layer of additional tasks (introducing appropriate approximations, choosing appropriate precisions, deciding whether to use look-up tables, avoiding branching by clever arithmetic expressions, etc.), which are beyond the scope of an introduction to Cg. Of course, real life is different; however, you don't learn to drive by participating in a Formula One race.
About Contributions to this Book
editContributions by everyone are of course welcome. When adding a new example, it should be made sure that no copyrights are violated and that all concepts are either explained in the example itself or in previous examples of the same part.
Unless stated otherwise, all example source code in this wikibook is granted to the public domain. Therefore, you may modify it and relicense it under any license you please. Source code should be embedded in <syntaxhighlight lang="..."> ... </syntaxhighlight>
in order to use syntax highlighting.
Other wikipages of the same part should be referenced by templates such as {{{{BOOKTEMPLATE}}/Unity SectionRef|X}}
, which should take the name of the wikipage, say X, as first parameter. The output should be something like Section “X”
.
When referencing a figure either try to use a reference that works for any placement of the figure (e.g. “the corresponding figure”) or use templates to generate different references for the online version and the printed book (e.g. the figure {{Hide in print|to the left}}{{Only in print|below}}
). Ignore problems with PDF versions since the online version is by far the most important one and many readers will have high expectations of the book version.
In order to make it easier to edit diagrams, the use of tables is encouraged. For example, use this:
{|cellpadding="5px" cellspacing="0" style="text-align:center; vertical-align:center;" |- |colspan="3" style="width:30%; background:#e0e0d0;"|'''first stage or input data''' |style="width:1%; font-size:200%;" |← |style="width:69%; background:#e0e0d0;"|additional input (optional, 1st style) |- |style="width:14%;"| |style="width:1%; text-align:right; padding:5px 0 5px 0; font-size:200%;" |↓ |colspan="3" style="width:85%; text-align:left;"|communicated data or operation |- |colspan="3" style="width:30%; background:#e0e0d0;"|'''second stage or processed data''' |style="width:1%;font-size:200%;" |← |style="width:69%; text-align:left;"|additional input (optional, 2nd style) |- |style="width:14%;"| |style="width:1%; text-align:right; padding:5px 0 5px 0; font-size:200%;" |↓ |colspan="3" style="width:85%; text-align:left; "|communicated data or operation |- |colspan="3" style="width:30%; background:#e0e0d0;"|'''third stage or processed data''' |style="width:1%;font-size:200%;" | |style="width:69%; text-align:left;"|description of stage or data (optional) |- |style="width:14%;"| |style="width:1%; text-align:right; padding:5px 0 5px 0; font-size:200%;" |↓ |colspan="3" style="width:85%; text-align:left; "|communicated data or operation |- |colspan="3" style="width:30%; background:#e0e0d0;"|'''fourth stage or processed data''' |style="width:1%;font-size:200%; " |→ |style="width:69%; background:#e0e0d0; "|additional output (optional, 1st style) |- |style="width:14%;"| |style="width:1%; text-align:right; padding:5px 0 5px 0; font-size:200%;" |↓ |colspan="3" style="width:85%; text-align:left; "|communicated data or operation |- |colspan="3" style="width:30%; background:#e0e0d0;"|'''final stage or output data''' |style="width:1%; font-size:200%;" |→ |style="width:69%; text-align:left; "|additional output (optional, 2nd style) |}
To get this:
first stage or input data | ← | additional input (optional, 1st style) | ||
↓ | communicated data or operation | |||
second stage or processed data | ← | additional input (optional, 2nd style) | ||
↓ | communicated data or operation | |||
third stage or processed data | description of stage or data (optional) | |||
↓ | communicated data or operation | |||
fourth stage or processed data | → | additional output (optional, 1st style) | ||
↓ | communicated data or operation | |||
final stage or output data | → | additional output (optional, 2nd style) |