Sign in with
Sign up | Sign in

Shader Model 5

OpenGL 3 & DirectX 11: The War Is Over

With Shader Model 5, Microsoft applies certain concepts of object-oriented programming to its shader language, HLSL. Unlike preceding versions, which introduced new capabilities (Dynamic Branching, integer support, etc.), the purpose here is to facilitate programmers’ work by solving a common problem in current game engines: namely the upsurge in the number of shaders due to the large number of permutations. We’ll take a concrete example: Suppose that an engine manages two types of materials, plastic and metal, and two types of light: spot and omni. A programmer has to write four shaders in order to handle all cases:

renderPlasticSpot () … // rendering plastic using spot light …

renderPlasticOmni () … // rendering plastic using omni light …

renderMetalSpot() … //rendering metal using spot light ...

renderMetalOmni() … //rendering metal using omni light …

This example is very simple since there are only two materials and two types of light, but in practice there can be several dozen. Obviously doing it this way can quickly become unmanageable. There’s a tremendous amount of code duplication and each time a bug is corrected somewhere it has to be corrected in all the other shaders. To solve this problem, programmers use what’s commonly called an über–shader, which brings together all the combinations:

Render() #ifdef METAL // code specific to metal material #elif PLASTIC // code specific to plastic material #endif #ifdef SPOT // code specific to spot light #elif OMNI // code specific to omni light #endif

This solution solves the problem by generating shaders on the fly from common code fragments. The downside is that it makes reading the shaders difficult and requires additional effort to be sure that all the fragments are inserted where they need to be. But with Direct3D 11, it’s now possible to make your code much more legible by using a derived interface and classes:

Light myLight; Material myMaterial; Render() myMaterial.render (); myLight.shade ();

Light and Material are interfaces, and the code is contained in the derived classes OmniLight and SpotLight, PlasticMaterial and MetalMaterial. So the code is all in a single place, which makes bug correction easier. At the same time, legibility doesn’t suffer thanks to the organization of the code, which resembles the concept of virtual functions in object-oriented languages. This feature will be welcomed by programmers, but won’t have any real impact for gamers.


As you can imagine, we’ve only skimmed the surface of Direct3D 11’s new features and Microsoft hasn’t even released all the details yet. Among the topics we haven’t mentioned are the increase in maximum texture size from 4K x 4K to 16K x 16K and the possibility of limiting the number of mipmaps loaded in VRAM. There’s also the possibility of changing the depth value of a pixel without disabling functionality like early Z checking, support for double-precision floating-point types, scatter memory writes, etc.

React To This Article