Cg
NVIDIA's "C for Graphics": a C-like shading language, co-designed with Microsoft alongside HLSL, that compiled one source program to many GPU generations and to both OpenGL and Direct3D through hardware profiles.
Created by NVIDIA (language effort led by Bill Mark, in collaboration with Microsoft)
Cg (“C for Graphics”) is a high-level shading language created by NVIDIA for writing programs that run on the programmable vertex and fragment processors of graphics cards. Announced in June 2002 and shipped as version 1.0 in December 2002, it arrived at the moment GPUs stopped being fixed-function pipelines and became programmable - and when the main way to program them was hand-written GPU assembly. Cg gave graphics programmers a C-like language instead, and one source program could be compiled for many generations of hardware and for both OpenGL and Direct3D.
Cg was designed in close collaboration with Microsoft, whose implementation of the same language shipped as the High-Level Shading Language (HLSL) in DirectX 9.0. NVIDIA’s own tutorial describes Cg and HLSL as “the same language” under two company names. The two later drifted apart. HLSL became the standard shading language of Direct3D, while Cg reached its final release, 3.1, in 2012 and is now a legacy toolkit. Its syntax still lives on in HLSL, in the PlayStation 3 library of games, and in the CGPROGRAM keyword that Unity developers still type.
History & Origins
The assembly-language problem
In 2001 and 2002, GPUs such as NVIDIA’s GeForce 3 and GeForce 4 Ti exposed programmable vertex and pixel stages. Programming them meant writing short assembly-language programs against vendor- and API-specific instruction sets: vs_1_1 and ps_1_x in Direct3D, and extensions such as NV_vertex_program and NV_register_combiners in OpenGL. The programs were hard to read, hard to reuse and tied to one hardware generation.
From Stanford to NVIDIA
The Cg Tutorial traces Cg’s heritage to three sources:
- C, for its syntax and semantics;
- Shading languages - Pixar’s offline RenderMan Shading Language, and earlier academic hardware shading languages;
- The OpenGL and Direct3D APIs, for its graphics functionality.
The most direct ancestor was the Stanford Real-Time Shading Language (RTSL), built by Kekoa Proudfoot, Bill Mark, Svetoslav Tzvetkov and Pat Hanrahan. It compiled shaders into one or more OpenGL rendering passes. According to the tutorial, that research “inspired NVIDIA’s own effort to develop a commercial-quality hardware-amenable shading language”. Bill Mark joined NVIDIA in 2001 to lead the definition and implementation of Cg. During that period NVIDIA and Microsoft agreed on a common syntax and feature set.
Launch
NVIDIA announced the Cg language specification on 13 June 2002, alongside a Cg Toolkit made available to developers at The Gathering 2 conference in London. The toolkit contained:
- the Cg compiler;
- the Cg Browser;
- the CgFX effect file format;
- a Cg standard library;
- a collection of pre-written shaders.
The compiler was described as cross-platform, covering Windows, Mac OS X, Linux and Xbox.
Cg Compiler 1.0 followed on 20 December 2002. NVIDIA’s announcement said it was compatible with Microsoft DirectX 9.0, released the same day. NVIDIA said it generated code for both DirectX and OpenGL. It worked with any GPU compliant with OpenGL 1.4 or DirectX 8.0 or later, not only NVIDIA hardware. It was released free, “including the open source code”, and NVIDIA positioned it as a companion to the new GeForce FX family.
The formal design was published the following summer. “Cg: A system for programming graphics hardware in a C-like language” by William R. Mark, R. Steven Glanville, Kurt Akeley and Mark J. Kilgard appeared at SIGGRAPH 2003 (ACM Transactions on Graphics 22(3), July 2003). In the same year Addison-Wesley published The Cg Tutorial by Randima Fernando and Mark J. Kilgard, which became the standard introduction to the language.
Design Philosophy
The SIGGRAPH paper states the central design decision directly: Cg follows the philosophy of C. It is a hardware-oriented, general-purpose language for programmable GPUs, not an application-specific shading language like RenderMan’s with built-in notions of lights and surfaces. Cg does not model the graphics pipeline; it lets programmers write programs for the pipeline’s programmable stages.
Three ideas follow from that:
- Cg is an auxiliary language. A Cg program does not stand alone. An application written in C, C++ or another CPU language uses the Cg runtime to load, compile, configure and bind Cg programs, which the GPU then runs for every vertex or fragment.
- Profiles instead of one fixed feature set. GPUs were changing too quickly for one language subset to fit them all. Each Cg profile corresponds to a particular combination of GPU architecture and graphics API. A program is compiled against a profile and must stay within that profile’s limits. For example, The Cg Tutorial notes that an early fragment profile might allow no more than four texture accesses per fragment.
- Portability across APIs. One Cg program could be compiled for OpenGL or for Direct3D. That made the language attractive to engines and tools that had to support both.
Key Features
C syntax with GPU types
Cg looks like C, with changes where GPU hardware or performance required them. The language adds:
- Vector and matrix types such as
float4,half3andfloat4x4; - Reduced-precision types
halfandfixed; - Swizzling and write masks (
v.xyz,color.rgb); - Built-in sampler types for texture access.
Semantics
Inputs and outputs are bound to hardware registers by semantics such as POSITION, COLOR and TEXCOORD0. Values that stay constant across a draw call are marked uniform; values that vary per vertex or fragment flow through in/out parameters and structures.
A first Cg program
The first example in The Cg Tutorial is a vertex program that passes a 2D position through and paints every vertex green:
| |
The same source could be compiled with the command-line compiler cgc for any vertex profile, choosing the entry function and the target:
| |
The runtime and CgFX
Besides the compiler, the toolkit shipped runtime libraries: a core runtime for managing parameters and loading programs, and API-specific layers (CgGL for OpenGL and, over time, CgD3D8, CgD3D9, CgD3D10 and CgD3D11). CgFX was an effect-file format that packaged multiple shaders together with render states, techniques and passes, similar to Microsoft’s .fx effects.
Evolution
NVIDIA extended Cg with each new GPU generation, mostly by adding profiles:
| Release | Date | Highlights |
|---|---|---|
| 1.0 | December 2002 | First release; DirectX and OpenGL code generation |
| 1.5 | September 2006 | OpenGL GLSL and Direct3D 9 SM 3.0 profiles, multithread-safe runtime, API for programmatic effect generation, CgFX API for Direct3D, Mac OS X universal binaries, Solaris 10 x86 support |
| 2.0 | December 2007 | GPU Program4 profiles (gp4vp/gp4gp/gp4fp) for GeForce 8-class GPUs, geometry programs, constant buffers, texture arrays, true integer types |
| 2.1 | August 2008 (beta) | DirectX 10 Shader Model 4 translation profiles |
| 2.2 | February 2009 (beta) | DirectX 10 and GLSL geometry profiles, pack_matrix() pragma, 64-bit Solaris libraries |
| 3.0 | July 2010 | DirectX 11 Shader Model 5 and OpenGL GPU Program5 profiles, tessellation programs |
| 3.1 | February 2012; final build April 2012 | Uniform buffers, OpenGL UBO support, GLSL 1.10/1.20 translation |
By the final release, NVIDIA said the toolkit supported more than 30 DirectX and OpenGL profile targets. They ranged from DirectX 8-era vs_1_1/ps_1_1 and the GeForce 3-era fp20 profile up to DirectX 11 hull and domain shaders and OpenGL tessellation programs. The final 3.1 build was distributed for:
- Windows XP, Vista and 7 (x86 and x86-64);
- Mac OS X Leopard, Snow Leopard and Lion (PowerPC, i386 and x86_64);
- Linux x86 and x86-64, as tarballs and as RPM and Debian packages.
Some earlier 2.x releases also shipped Solaris builds.
Decline
Cg’s great strength was one language across both APIs and all vendors. Over the decade that advantage faded:
- HLSL became the native, Microsoft-maintained language of Direct3D.
- GLSL was standardised by the OpenGL ARB and built into drivers from every vendor.
- New GPU features appeared in those languages first, while Cg had to follow through new profiles.
Several Cg profiles simply translate Cg into HLSL or GLSL rather than into hardware assembly. That shows how far the centre of gravity had moved.
NVIDIA stopped development after 3.1. Its developer site now describes the Cg Toolkit as “a legacy NVIDIA toolkit no longer under active development or support”. It still offers the April 2012 release for download but does not recommend it for new projects, because future hardware features may not be supported. For new work it points developers to GLSL and HLSL.
Current Relevance
Cg is no longer a live language, but its traces are easy to find:
- HLSL, Cg’s twin, remains one of the most widely used real-time shading languages.
- Unity shader files still use
CGPROGRAMblocks and.cgincincludes. Unity’s manual explains these are names inherited from its original use of Cg, even though the engine now compiles HLSL. - PlayStation 3 games shipped shaders compiled from Cg for the RSX GPU, so anyone preserving or emulating that library still deals with Cg’s output.
- Older engines and tools, such as OGRE’s Cg plugin, still carry Cg support, now marked as deprecated.
- The Cg Tutorial remains a widely read introduction to programmable shading, and NVIDIA still hosts its chapters online.
Why It Matters
Cg was one of the first high-level languages for consumer programmable GPUs. It helped change shader development from register-level assembly into ordinary programming with functions, structures, types and a compiler. Its design choices - C syntax, vector types with swizzles, semantics for binding to the pipeline, and profiles to cope with fast-changing hardware - reached most real-time graphics programmers through its co-design with HLSL.
Cg also showed that a single shading language could target competing graphics APIs and hardware from several vendors. That idea is now back in the form of cross-compilation toolchains and SPIR-V. For a few years in the early 2000s, Cg was one of the main ways programmers learned to write code for the GPU.
Timeline
Notable Uses & Legacy
Sony PlayStation 3
Shaders for the PS3's NVIDIA-designed RSX GPU were written in Cg. Newcastle University's PS3 teaching material notes that, unlike OpenGL, the low-level GCM library offers only one shading language - Cg. The higher-level PSGL API, an OpenGL ES-based wrapper, also used Cg shaders
Unity
Unity's ShaderLab originally embedded Cg code, which is why Unity shaders still open with the CGPROGRAM keyword and share code through .cginc include files. Unity's own manual notes that the engine no longer uses Cg but keeps those names
OGRE 3D engine
The open-source OGRE rendering engine supports Cg vertex and fragment programs through its Plugin_CgProgramManager, letting one shader serve both its Direct3D and OpenGL render systems. OGRE's current documentation marks Cg as deprecated in favour of its own unified-shader macros