- Shader (realtime, logical)
A shader is essentially a computer programAccording to [http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_program.txt ARB_vertex_program] a shader (specifically to vertex shaders, which are called "programs" in this context) is "a sequence of floating-point 4-component vector operations that determines how a set of program parameters ... and an input set of per-vertex parameters are transformed to a set of per-vertex result parameters".] executed on a special environment] Direct3D10 shaders do target a [http://msdn2.microsoft.com/en-us/library/bb205137.aspx common shader core] .] . This article specifically covers realtime shaders which are shaders meant to execute on consumer GPUs.Although shaders were introduced for graphics related tasks which still hold a major part of their applications, shaders can also be used for more generic computation, just as generic programs can be used to compute arbitrary data. As the computational power of GPUs continue to raise faster than conventional CPUs, the interest in shader programming catalizes more and more attention. This actually requires to rethink algorithms or problems to fit the
stream processing paradigm.
The goal of this article is to provide a look at the most important concepts concerning shaders in most importantAPI s such asOpenGL andDirect3D . The reader is assumed to be proficient with 3D graphics, a graphics API and fourth generation shading pipelines.
Shaders alone control a large part of the working of a programmable graphics pipeline and thus the final appearance of an object. However, they are not the only entities involved in defining an accurate behaviour. The resources being used, as well as settings of other pipeline stages, still has a great influence upon the final result.Generic shader
A "generic shader" replaces a specific stage of the shading pipelineOpenGL does employ a flexible way to select the unit to be replaced. The method is introduced in the OpenGL 2.1 specification, section 2.15 (Vertex Shaders) and then specialized in section 3.11 (Fragment Shaders). Additionally, [http://developer.download.nvidia.com/opengl/specs/GL_EXT_geometry_shader4.txt EXT_geometry_shader4] introduces a new target for Geometry Shaders.] Direct3D9 builds vertex and pixel shaders using two specific functions ( [http://msdn2.microsoft.com/en-us/library/bb174366.aspx CreateVertexShader] , [http://msdn2.microsoft.com/en-us/library/bb174359.aspx CreatePixelShader] ). Both functions build shaders according to a precompiled token array. This token array must be built previously using ad hoc tools or using [http://msdn2.microsoft.com/en-us/library/bb172731.aspx D3DXCompileShader] .] Direct3D10 is essentially the same as Direct3D9 augmented with a new shader type ( [http://msdn2.microsoft.com/en-us/library/bb173562.aspx CreateVertexShader] , [http://msdn2.microsoft.com/en-us/library/bb173548.aspx CreateGeometryShader] , [http://msdn2.microsoft.com/en-us/library/bb173551.aspx CreatePixelShader] ). Also note the shader compiler is now a first class citizen ( [http://msdn2.microsoft.com/en-us/library/bb205084.aspx D3D10CompileShader] ). Only HLSL is supported.] with a user-defined program to be executed on need - thereafter, kernel. Shaders generally run in parallel with limited inter-communication between different executions - thereafter instances - usually limited to simplified first-derivative computation and cache optimizations.Being simply a sequence of operations, kernels are defined using special
programming language s tailored to match the needs for explicit parallelization and efficiency. Various shading languages have been designed for this purpose.Depending on the stage being replaced, a shader fetches specific data while its output is handed to successive stages. Input data is typically read-only and can be categorized in two main types:
*uniform input does hold constant between different kernel instances of the same draw call. The application can set these uniform values with ease between different draw calls, but there is no way to change a uniform value on a per-instance basis. Uniform values can be loaded by calling specific API functions [http://oss.sgi.com/projects/ogl-sample/registry/ARB/shader_objects.txt ARB_shader_objects] which was integrated in OpenGL2.0 introduced a family of "Uniform*" calls for this purpose. The same calls were previously introduced with ARB_vertex_program and similar "ProgramParameter*" calls were available for [http://oss.sgi.com/projects/ogl-sample/registry/NV/vertex_program.txt NV_vertex_program] . Note that uniform values are a per-program (or per-shader) property as can be read in [http://oss.sgi.com/projects/ogl-sample/registry/ARB/shader_objects.txt ARB_shader_objects] issue (9) : "Should values loaded for uniforms be kept in a program object, so that they are retained across program object switches? ... YES".] Direct3D9 does have a low-level approach to shader parameters. Shader themselves do not allow uniform values to be set, instead, a pool of [http://msdn2.microsoft.com/en-us/library/bb174336.aspx device] registers is used. Furthermore, since the API considers pixels and vertex resources as distinct, there are specific calls such as [http://msdn2.microsoft.com/en-us/library/bb174452.aspx SetPixelShaderConstantF] and [http://msdn2.microsoft.com/en-us/library/bb174467.aspx SetVertexShaderConstantF] . For high-level shaders instead, a [http://msdn2.microsoft.com/en-us/library/bb205762.aspx ID3DXConstantTable] can be used.] Direct3D10 uses a method which is similar to D3D9's but considerably more efficient and powerful. Different pools of Vertex, Pixel and Geometry resources are provided but constant values are now packed in [http://msdn2.microsoft.com/en-us/library/bb173510.aspx constant buffers] . In a certain sense, the previous concept of "uniform value register" is replaced by a "constant buffer reference register". Changing the value of a specific program parameter then involves mapping the constant buffer and modifying its content or - more realistically - changing the constant buffer to use.] .
**samplers are special uniforms meant to be used to access textures. Typically, sampler identifiers themselves specify a texture sampling unit in the pipeline (to be used for texture-lookups operations) which is then bound to a texture. Samplers are usually employed by kernels similarly to objectsA sampler is essentially an integer number in GLSL with special semantics provided by the compiler which is used as an 'opaque' object. According to OpenGL2.1 specification (subsection 2.14.4 "Samplers"): "Samplers are special uniforms used in the OpenGL Shading Language to identify the texture object used for each texture lookup. The value of a sampler indicates the texture image unit being accessed. Setting a sampler's value to i selects texture image unit number i. ... The type of the sampler identifies the target on the texture image unit. ... The location of a sampler needs to be queried with GetUniformLocationARB, just like any uniform variable."] A sampler in Direct3D9 is a special pseudo-register ( [http://msdn2.microsoft.com/en-us/library/bb172922.aspx sampler] ) to be used with texture-lookups operations. Given a handle to a sampler identifier, [http://msdn2.microsoft.com/en-us/library/bb205770.aspx ID3DXConstantTable::GetSamplerIndex] can be used to identify the sampler unit being used.] In D3D10 HLSL, the concept of "sampler" is superseded by [http://msdn2.microsoft.com/en-us/library/bb205306.aspx texture object] . Using a texture object involves a syntax similar to "real" objects in C++/Java.] . The intended usage model presents some differences depending on the shading language being used.
*varying input is typically the result of a previous computational stage, sometimes bound to some special, context-dependentsemantic s. For example, vertex positions are typical varying inputs for vertex shaders (named "attributes" in this context), pixel texture coordinates are typical varying inputs to pixel shaders.The output is ideologically always varying (although two instances may actually output the same value). Fourth generation shading pipelines allow to control how output interpolation is performedGDC 2007) is likely the easiest document to read on interpolation methods for
OpenGL . Comes with a few screenshots.MSDN features a D3D10 specific [http://msdn2.microsoft.com/en-us/library/bb205140.aspx page] .] when primitives are rasterized and pixel shader's varying input is generated.Vertex shader
A "vertex shader" replaces part of the geometry stage [http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_shader.txt ARB_vertex_shader] reads: "A vertex shader replaces the transformation, texture coordinate generation and lighting parts of OpenGL, and it also adds texture access at the vertex level."] of a graphics pipeline. Vertex shaders consume vertices filled by the Input Assembly stage by applying the specified kernel "for each vertex". The result, which usually include an
affine transform , is then fetched by the next state - the Primitive Assembly stage. A vertex shader always produces a single transformed "vertex" [http://msdn2.microsoft.com/en-us/library/bb205146.aspx D3D10, the Vertex Stage] .] and runs on a "vertex processor"GLSL 1.20 specification, section 2.1.] .
Wikimedia Foundation. 2010.