1# High-level Programs {#High-level-Programs}
2
3Support for high level vertex and fragment programs is provided through plugins; this is to make sure that an application using OGRE can use as little or as much of the high-level program functionality as they like. OGRE currently supports 3 high-level program types, Cg ([Cg](#Cg)) (an API- and card-independent, high-level language which lets you write programs for both OpenGL and DirectX for lots of cards), DirectX 9 High-Level Shader Language ([HLSL](#HLSL)), and OpenGL Shader Language ([GLSL](#GLSL)). HLSL can only be used with the DirectX rendersystem, and GLSL can only be used with the GL rendersystem. Cg can be used with both, although experience has shown that more advanced programs, particularly fragment programs which perform a lot of texture fetches, can produce better code in the rendersystem-specific shader language.
4
5One way to support both HLSL and GLSL is to include separate techniques in the material script, each one referencing separate programs. However, if the programs are basically the same, with the same parameters, and the techniques are complex this can bloat your material scripts with duplication fairly quickly. Instead, if the only difference is the language of the vertex & fragment program you can use OGRE’s [Unified High-level Programs](#Unified-High_002dlevel-Programs) to automatically pick a program suitable for your rendersystem whilst using a single technique.
6
7@tableofcontents
8
9# Cg programs {#Cg}
10
11In order to define Cg programs, you have to have to load Plugin\_CgProgramManager.so/.dll at startup, either through plugins.cfg or through your own plugin loading code. They are very easy to define:
12
13```cpp
14fragment_program myCgFragmentProgram cg
15{
16    source myCgFragmentProgram.cg
17    entry_point main
18    profiles ps_2_0 arbfp1
19}
20```
21
22There are a few differences between this and the assembler program - to begin with, we declare that the fragment program is of type `cg` rather than `asm`, which indicates that it’s a high-level program using Cg. The `source` parameter is the same, except this time it’s referencing a Cg source file instead of a file of assembler.  Here is where things start to change. Firstly, we need to define an `entry_point`, which is the name of a function in the Cg program which will be the first one called as part of the fragment program. Unlike assembler programs, which just run top-to-bottom, Cg programs can include multiple functions and as such you must specify the one which start the ball rolling. Next, instead of a fixed `syntax` parameter, you specify one or more `profiles`; profiles are how Cg compiles a program down to the low-level assembler. The profiles have the same names as the assembler syntax codes mentioned above; the main difference is that you can list more than one, thus allowing the program to be compiled down to more low-level syntaxes so you can write a single high-level program which runs on both D3D and GL. You are advised to just enter the simplest profiles under which your programs can be compiled in order to give it the maximum compatibility. The ordering also matters; if a card supports more than one syntax then the one listed first will be used.
23
24Lastly, there is a final option called `compile_arguments`, where you can specify arguments exactly as you would to the cgc command-line compiler, should you wish to.
25
26# DirectX9 HLSL {#HLSL}
27
28DirectX9 HLSL has a very similar language syntax to Cg but is tied to the DirectX API. The only benefit over Cg is that it only requires the DirectX 9 render system plugin, not any additional plugins. Declaring a DirectX9 HLSL program is very similar to Cg. Here’s an example:
29
30```cpp
31vertex_program myHLSLVertexProgram hlsl
32{
33    source myHLSLVertexProgram.txt
34    entry_point main
35    target vs_2_0
36}
37```
38
39As you can see, the main syntax is almost identical, except that instead of `profiles` with a list of assembler formats, you have a `target` parameter which allows a single assembler target to be specified - obviously this has to be a DirectX assembler format syntax code.
40
41**Important Matrix Ordering Note:** One thing to bear in mind is that HLSL allows you to use 2 different ways to multiply a vector by a matrix - mul(v,m) or mul(m,v). The only difference between them is that the matrix is effectively transposed. You should use mul(m,v) with the matrices passed in from Ogre - this agrees with the shaders produced from tools like RenderMonkey, and is consistent with Cg too, but disagrees with the Dx9 SDK and FX Composer which use mul(v,m) - you will have to switch the parameters to mul() in those shaders.
42
43Note that if you use the float3x4 / matrix3x4 type in your shader, bound to an OGRE auto-definition (such as bone matrices) you should use the `column_major_matrices = false` option (discussed below) in your program definition. This is because OGRE passes float3x4 as row-major to save constant space (3 float4’s rather than 4 float4’s with only the top 3 values used) and this tells OGRE to pass all matrices like this, so that you can use mul(m,v) consistently for all calculations. OGRE will also to tell the shader to compile in row-major form (you don’t have to set the /Zpr compile option or \#pragma pack(row-major) option, OGRE does this for you). Note that passing bones in float4x3 form is not supported by OGRE, but you don’t need it given the above.
44
45**Advanced options**<br>
46
47<dl compact="compact">
48<dt>preprocessor\_defines &lt;defines&gt;</dt> <dd>
49
50This allows you to define symbols which can be used inside the HLSL shader code to alter the behaviour (through \#ifdef or \#if clauses). Definitions are separated by ’;’ or ’,’ and may optionally have a ’=’ operator within them to specify a definition value. Those without an ’=’ will implicitly have a definition of 1.
51
52</dd> <dt>column\_major\_matrices &lt;true|false&gt;</dt> <dd>
53
54The default for this option is ’true’ so that OGRE passes matrices auto-bound matrices in a form where mul(m,v) works. Setting this option to false does 2 things - it transpose auto-bound 4x4 matrices and also sets the /Zpr (row-major) option on the shader compilation. This means you can still use mul(m,v), but the matrix layout is row-major instead. This is only useful if you need to use bone matrices (float3x4) in a shader since it saves a float4 constant for every bone involved.
55
56</dd> <dt>optimisation\_level &lt;opt&gt;</dt> <dd>
57
58Set the optimisation level, which can be one of ’default’, ’none’, ’0’, ’1’, ’2’, or ’3’. This corresponds to the /O parameter of fxc.exe, except that in ’default’ mode, optimisation is disabled in debug mode and set to 1 in release mode (fxc.exe uses 1 all the time). Unsurprisingly the default value is ’default’. You may want to change this if you want to tweak the optimisation, for example if your shader gets so complex that it will not longer compile without some minimum level of optimisation.
59
60</dd> </dl>
61
62
63# OpenGL GLSL {#GLSL}
64
65OpenGL GLSL has a similar language syntax to HLSL but is tied to the OpenGL API. The are a few benefits over Cg in that it only requires the OpenGL render system plugin, not any additional plugins. Declaring a OpenGL GLSL program is similar to Cg but simpler. Here’s an example:
66
67```cpp
68vertex_program myGLSLVertexProgram glsl
69{
70    source myGLSLVertexProgram.txt
71}
72```
73
74In GLSL, no entry point needs to be defined since it is always `main()` and there is no target definition since GLSL source is compiled into native GPU code and not intermediate assembly.
75
76GLSL supports the use of modular shaders. This means you can write GLSL external functions that can be used in multiple shaders.
77
78```cpp
79vertex_program myExternalGLSLFunction1 glsl
80{
81    source myExternalGLSLfunction1.txt
82}
83
84vertex_program myExternalGLSLFunction2 glsl
85{
86    source myExternalGLSLfunction2.txt
87}
88
89vertex_program myGLSLVertexProgram1 glsl
90{
91    source myGLSLfunction.txt
92    attach myExternalGLSLFunction1 myExternalGLSLFunction2
93}
94
95vertex_program myGLSLVertexProgram2 glsl
96{
97    source myGLSLfunction.txt
98    attach myExternalGLSLFunction1
99}
100```
101
102External GLSL functions are attached to the program that needs them by using `attach` and including the names of all external programs required on the same line separated by spaces. This can be done for both vertex and fragment programs.
103
104## GLSL Texture Samplers {#GLSL-Texture-Samplers}
105
106To pass texture unit index values from the material script to texture samplers in glsl use `int` type named parameters. See the example below:<br>
107
108excerpt from GLSL example.frag source:
109
110```cpp
111varying vec2 UV;
112uniform sampler2D diffuseMap;
113
114void main(void)
115{
116    gl_FragColor = texture2D(diffuseMap, UV);
117}
118```
119
120In material script:
121
122```cpp
123fragment_program myFragmentShader glsl
124{
125  source example.frag
126}
127
128material exampleGLSLTexturing
129{
130  technique
131  {
132    pass
133    {
134      fragment_program_ref myFragmentShader
135      {
136        param_named diffuseMap int 0
137      }
138
139      texture_unit
140      {
141        texture myTexture.jpg 2d
142      }
143    }
144  }
145}
146```
147
148An index value of 0 refers to the first texture unit in the pass, an index value of 1 refers to the second unit in the pass and so on.
149
150## Matrix parameters {#Matrix-parameters}
151
152Here are some examples of passing matrices to GLSL mat2, mat3, mat4 uniforms:
153
154```cpp
155material exampleGLSLmatrixUniforms
156{
157  technique matrix_passing
158  {
159    pass examples
160    {
161      vertex_program_ref myVertexShader
162      {
163        // mat4 uniform
164        param_named OcclusionMatrix matrix4x4 1 0 0 0  0 1 0 0  0 0 1 0  0 0 0 0
165        // or
166        param_named ViewMatrix float16 0 1 0 0  0 0 1 0  0 0 0 1  0 0 0 0
167
168        // mat3
169        param_named TextRotMatrix float9 1 0 0  0 1 0  0 0 1
170      }
171
172      fragment_program_ref myFragmentShader
173      {
174        // mat2 uniform
175        param_named skewMatrix float4 0.5 0 -0.5 1.0
176      }
177    }
178  }
179}
180```
181
182## Accessing OpenGL states in GLSL {#Accessing-OpenGL-states-in-GLSL}
183
184GLSL can access most of the GL states directly so you do not need to pass these states through [param\_named\_auto](#param_005fnamed_005fauto) in the material script. This includes lights, material state, and all the matrices used in the openGL state i.e. model view matrix, worldview projection matrix etc.
185
186@note this is only possible with OpenGL legacy profiles i.e. **not** with GL3+.
187
188## Binding vertex attributes {#Binding-vertex-attributes}
189
190GLSL natively supports automatic binding of the most common incoming per-vertex attributes (e.g. `gl_Vertex`, `gl_Normal`, `gl_MultiTexCoord0` etc). However, there are some which are not automatically bound, which must be declared in the shader using the `attribute &lt;type&gt; &lt;name&gt;` syntax, and the vertex data bound to it by Ogre.
191
192@note again this is only possible with OpenGL legacy profiles i.e. **not** with GL3+.
193
194In addition to the built in attributes described in section 7.3 of the GLSL manual, Ogre supports a number of automatically bound custom vertex attributes. There are some drivers that do not behave correctly when mixing built-in vertex attributes like `gl_Normal` and custom vertex attributes, so for maximum compatibility you should use all custom attributes
195
196<dl compact="compact">
197<dt>vertex</dt> <dd>
198
199Binds Ogre::VES\_POSITION, declare as ’attribute vec4 vertex;’.
200
201</dd> <dt>normal</dt> <dd>
202
203Binds Ogre::VES\_NORMAL, declare as ’attribute vec3 normal;’.
204
205</dd> <dt>colour</dt> <dd>
206
207Binds Ogre::VES\_DIFFUSE, declare as ’attribute vec4 colour;’.
208
209</dd> <dt>secondary\_colour</dt> <dd>
210
211Binds Ogre::VES\_SPECULAR, declare as ’attribute vec4 secondary\_colour;’.
212
213</dd> <dt>uv0 - uv7</dt> <dd>
214
215Binds Ogre::VES\_TEXTURE\_COORDINATES, declare as ’attribute vec4 uv0;’. Note that uv6 and uv7 share attributes with tangent and binormal respectively so cannot both be present.
216
217</dd> <dt>tangent</dt> <dd>
218
219Binds Ogre::VES\_TANGENT, declare as ’attribute vec3 tangent;’.
220
221</dd> <dt>binormal</dt> <dd>
222
223Binds Ogre::VES\_BINORMAL, declare as ’attribute vec3 binormal;’.
224
225</dd> <dt>blendIndices</dt> <dd>
226
227Binds Ogre::VES\_BLEND\_INDICES, declare as ’attribute vec4 blendIndices;’.
228
229</dd> <dt>blendWeights</dt> <dd>
230
231Binds Ogre::VES\_BLEND\_WEIGHTS, declare as ’attribute vec4 blendWeights;’.
232
233</dd> </dl>
234
235## Preprocessor definitions {#Preprocessor-definitions}
236
237GLSL supports using preprocessor definitions in your code - some are defined by the implementation, but you can also define your own, say in order to use the same source code for a few different variants of the same technique. In order to use this feature, include preprocessor conditions in your GLSL code, of the kind \#ifdef SYMBOL, \#if SYMBOL==2 etc. Then in your program definition, use the ’preprocessor\_defines’ option, following it with a string if definitions. Definitions are separated by ’;’ or ’,’ and may optionally have a ’=’ operator within them to specify a definition value. Those without an ’=’ will implicitly have a definition of 1. For example:
238
239```cpp
240// in your GLSL
241
242#ifdef CLEVERTECHNIQUE
243    // some clever stuff here
244#else
245    // normal technique
246#endif
247
248#if NUM_THINGS==2
249    // Some specific code
250#else
251    // something else
252#endif
253
254// in  your program definition
255preprocessor_defines CLEVERTECHNIQUE,NUMTHINGS=2
256```
257
258This way you can use the same source code but still include small variations, each one defined as a different Ogre program name but based on the same source code.
259
260## GLSL Geometry shader specification {#GLSL-Geometry-shader-specification}
261
262GLSL allows the same shader to run on different types of geometry primitives. In order to properly link the shaders together, you have to specify which primitives it will receive as input, which primitives it will emit and how many vertices a single run of the shader can generate. The GLSL geometry\_program definition requires three additional parameters :
263
264<dl compact="compact">
265<dt>input\_operation\_type</dt> <dd>
266
267The operation type of the geometry that the shader will receive. Can be ’point\_list’, ’line\_list’, ’line\_strip’, ’triangle\_list’, ’triangle\_strip’ or ’triangle\_fan’.
268
269</dd> <dt>output\_operation\_type</dt> <dd>
270
271The operation type of the geometry that the shader will emit. Can be ’point\_list’, ’line\_strip’ or ’triangle\_strip’.
272
273</dd> <dt>max\_output\_vertices</dt> <dd>
274
275The maximum number of vertices that the shader can emit. There is an upper limit for this value, it is exposed in the render system capabilities.
276
277</dd> </dl>
278
279For example:
280
281```cpp
282geometry_program Ogre/GPTest/Swizzle_GP_GLSL glsl
283{
284    source SwizzleGP.glsl
285    input_operation_type triangle_list
286    output_operation_type line_strip
287    max_output_vertices 6
288}
289```
290
291# Unified High-level Programs {#Unified-High_002dlevel-Programs}
292
293As mentioned above, it can often be useful to write both HLSL and GLSL programs to specifically target each platform, but if you do this via multiple material techniques this can cause a bloated material definition when the only difference is the program language. Well, there is another option. You can ’wrap’ multiple programs in a ’unified’ program definition, which will automatically choose one of a series of ’delegate’ programs depending on the rendersystem and hardware support.
294
295```cpp
296vertex_program myVertexProgram unified
297{
298    delegate realProgram1
299    delegate realProgram2
300    ... etc
301}
302```
303
304This works for both vertex and fragment programs, and you can list as many delegates as you like - the first one to be supported by the current rendersystem & hardware will be used as the real program. This is almost like a mini-technique system, but for a single program and with a much tighter purpose. You can only use this where the programs take all the same inputs, particularly textures and other pass / sampler state. Where the only difference between the programs is the language (or possibly the target in HLSL - you can include multiple HLSL programs with different targets in a single unified program too if you want, or indeed any number of other high-level programs), this can become a very powerful feature. For example, without this feature here’s how you’d have to define a programmable material which supported HLSL and GLSL:
305
306```cpp
307vertex_program myVertexProgramHLSL hlsl
308{
309    source prog.hlsl
310    entry_point main_vp
311    target vs_2_0
312}
313fragment_program myFragmentProgramHLSL hlsl
314{
315    source prog.hlsl
316    entry_point main_fp
317    target ps_2_0
318}
319vertex_program myVertexProgramGLSL glsl
320{
321    source prog.vert
322}
323fragment_program myFragmentProgramGLSL glsl
324{
325    source prog.frag
326    default_params
327    {
328        param_named tex int 0
329    }
330}
331material SupportHLSLandGLSLwithoutUnified
332{
333    // HLSL technique
334    technique
335    {
336        pass
337        {
338            vertex_program_ref myVertexProgramHLSL
339            {
340                param_named_auto worldViewProj world_view_proj_matrix
341                param_named_auto lightColour light_diffuse_colour 0
342                param_named_auto lightSpecular light_specular_colour 0
343                param_named_auto lightAtten light_attenuation 0
344            }
345            fragment_program_ref myFragmentProgramHLSL
346            {
347            }
348        }
349    }
350    // GLSL technique
351    technique
352    {
353        pass
354        {
355            vertex_program_ref myVertexProgramHLSL
356            {
357                param_named_auto worldViewProj world_view_proj_matrix
358                param_named_auto lightColour light_diffuse_colour 0
359                param_named_auto lightSpecular light_specular_colour 0
360                param_named_auto lightAtten light_attenuation 0
361            }
362            fragment_program_ref myFragmentProgramHLSL
363            {
364            }
365        }
366    }
367}
368```
369
370And that’s a really small example. Everything you added to the HLSL technique, you’d have to duplicate in the GLSL technique too. So instead, here’s how you’d do it with unified program definitions:
371
372```cpp
373vertex_program myVertexProgramHLSL hlsl
374{
375    source prog.hlsl
376    entry_point main_vp
377    target vs_2_0
378}
379fragment_program myFragmentProgramHLSL hlsl
380{
381    source prog.hlsl
382    entry_point main_fp
383    target ps_2_0
384}
385vertex_program myVertexProgramGLSL glsl
386{
387    source prog.vert
388}
389fragment_program myFragmentProgramGLSL glsl
390{
391    source prog.frag
392    default_params
393    {
394        param_named tex int 0
395    }
396}
397// Unified definition
398vertex_program myVertexProgram unified
399{
400    delegate myVertexProgramGLSL
401    delegate myVertexProgramHLSL
402}
403fragment_program myFragmentProgram unified
404{
405    delegate myFragmentProgramGLSL
406    delegate myFragmentProgramHLSL
407}
408material SupportHLSLandGLSLwithUnified
409{
410    // HLSL technique
411    technique
412    {
413        pass
414        {
415            vertex_program_ref myVertexProgram
416            {
417                param_named_auto worldViewProj world_view_proj_matrix
418                param_named_auto lightColour light_diffuse_colour 0
419                param_named_auto lightSpecular light_specular_colour 0
420                param_named_auto lightAtten light_attenuation 0
421            }
422            fragment_program_ref myFragmentProgram
423            {
424            }
425        }
426    }
427}
428```
429
430At runtime, when myVertexProgram or myFragmentProgram are used, OGRE automatically picks a real program to delegate to based on what’s supported on the current hardware / rendersystem. If none of the delegates are supported, the entire technique referencing the unified program is marked as unsupported and the next technique in the material is checked fro fallback, just like normal. As your materials get larger, and you find you need to support HLSL and GLSL specifically (or need to write multiple interface-compatible versions of a program for whatever other reason), unified programs can really help reduce duplication.
431
432# Using GPU Programs in a Pass {#Using-Vertex_002fGeometry_002fFragment-Programs-in-a-Pass}
433
434Within a pass section of a material script, you can reference a vertex, geometry and / or a fragment program which is been defined in a .program script (See @ref Declaring-Vertex_002fGeometry_002fFragment-Programs). The programs are defined separately from the usage of them in the pass, since the programs are very likely to be reused between many separate materials, probably across many different .material scripts, so this approach lets you define the program only once and use it many times.
435
436As well as naming the program in question, you can also provide parameters to it. Here’s a simple example:
437
438```cpp
439vertex_program_ref myVertexProgram
440{
441    param_indexed_auto 0 worldviewproj_matrix
442    param_indexed      4 float4  10.0 0 0 0
443}
444```
445
446In this example, we bind a vertex program called ’myVertexProgram’ (which will be defined elsewhere) to the pass, and give it 2 parameters, one is an ’auto’ parameter, meaning we do not have to supply a value as such, just a recognised code (in this case it’s the world/view/projection matrix which is kept up to date automatically by Ogre). The second parameter is a manually specified parameter, a 4-element float. The indexes are described later.
447
448The syntax of the link to a vertex program and a fragment or geometry program are identical, the only difference is that ’fragment\_program\_ref’ and ’geometry\_program\_ref’ are used respectively instead of ’vertex\_program\_ref’.
449
450For many situations vertex, geometry and fragment programs are associated with each other in a pass but this is not cast in stone. You could have a vertex program that can be used by several different fragment programs. Another situation that arises is that you can mix fixed pipeline and programmable pipeline (shaders) together. You could use the non-programmable vertex fixed function pipeline and then provide a fragment\_program\_ref in a pass i.e. there would be no vertex\_program\_ref section in the pass. The fragment program referenced in the pass must meet the requirements as defined in the related API in order to read from the outputs of the vertex fixed pipeline. You could also just have a vertex program that outputs to the fragment fixed function pipeline.
451
452The requirements to read from or write to the fixed function pipeline are similar between rendering API’s (DirectX and OpenGL) but how its actually done in each type of shader (vertex, geometry or fragment) depends on the shader language. For HLSL (DirectX API) and associated asm consult MSDN at <http://msdn.microsoft.com/library/>. For GLSL (OpenGL), consult section 7.6 of the GLSL spec 1.1 available at <http://www.opengl.org/registry/>. The built in varying variables provided in GLSL allow your program to read/write to the fixed function pipeline varyings. For Cg consult the Language Profiles section in CgUsersManual.pdf that comes with the Cg Toolkit available at <https://developer.nvidia.com/cg-toolkit>. For HLSL and Cg its the varying bindings that allow your shader programs to read/write to the fixed function pipeline varyings.
453
454## Parameter specification {#Program-Parameter-Specification}
455
456Parameters can be specified using one of 4 commands as shown below. The same syntax is used whether you are defining a parameter just for this particular use of the program, or when specifying the @ref Default-Program-Parameters. Parameters set in the specific use of the program override the defaults.
457
458-   [param\_indexed](#param_005findexed)
459-   [param\_indexed\_auto](#param_005findexed_005fauto)
460-   [param\_named](#param_005fnamed)
461-   [param\_named\_auto](#param_005fnamed_005fauto)
462-   [shared\_params\_ref](#shared_005fparams_005fref)
463
464<a name="param_005findexed"></a><a name="param_005findexed-1"></a>
465
466## param\_indexed
467
468This command sets the value of an indexed parameter.
469
470format: param\_indexed &lt;index&gt; &lt;type&gt; &lt;value&gt; example: param\_indexed 0 float4 10.0 0 0 0
471
472@param index
473simply a number representing the position in the parameter list which the value should be written, and you should derive this from your program definition. The index is relative to the way constants are stored on the card, which is in 4-element blocks. For example if you defined a float4 parameter at index 0, the next index would be 1. If you defined a matrix4x4 at index 0, the next usable index would be 4, since a 4x4 matrix takes up 4 indexes.
474
475@param type
476can be float4, matrix4x4, float&lt;n&gt;, int4, int&lt;n&gt;. Note that ’int’ parameters are only available on some more advanced program syntaxes, check the D3D or GL vertex / fragment program documentation for full details. Typically the most useful ones will be float4 and matrix4x4. Note that if you use a type which is not a multiple of 4, then the remaining values up to the multiple of 4 will be filled with zeroes for you (since GPUs always use banks of 4 floats per constant even if only one is used).
477
478@param value
479a space or tab-delimited list of values which can be converted into the type you have specified.
480
481<a name="param_005findexed_005fauto"></a><a name="param_005findexed_005fauto-1"></a>
482
483## param\_indexed\_auto
484
485This command tells Ogre to automatically update a given parameter with a derived value. This frees you from writing code to update program parameters every frame when they are always changing.
486
487format: param\_indexed\_auto &lt;index&gt; &lt;value\_code&gt; &lt;extra\_params&gt; example: param\_indexed\_auto 0 worldviewproj\_matrix
488
489@param index
490has the same meaning as [param\_indexed](#param_005findexed); note this time you do not have to specify the size of the parameter because the engine knows this already. In the example, the world/view/projection matrix is being used so this is implicitly a matrix4x4.
491
492@param value_code
493is one of Ogre::GpuProgramParameters::AutoConstantType without the `ACT_` prefix. E.g. `ACT_WORLD_MATRIX` becomes `world_matrix`.
494
495 <a name="param_005fnamed"></a><a name="param_005fnamed-1"></a>
496
497## param\_named
498
499This is the same as param\_indexed, but uses a named parameter instead of an index. This can only be used with high-level programs which include parameter names; if you’re using an assembler program then you have no choice but to use indexes. Note that you can use indexed parameters for high-level programs too, but it is less portable since if you reorder your parameters in the high-level program the indexes will change. format: param\_named &lt;name&gt; &lt;type&gt; &lt;value&gt; example: param\_named shininess float4 10.0 0 0 0 The type is required because the program is not compiled and loaded when the material script is parsed, so at this stage we have no idea what types the parameters are. Programs are only loaded and compiled when they are used, to save memory.
500
501<a name="param_005fnamed_005fauto"></a><a name="param_005fnamed_005fauto-1"></a>
502
503## param\_named\_auto
504
505This is the named equivalent of param\_indexed\_auto, for use with high-level programs. Format: param\_named\_auto &lt;name&gt; &lt;value\_code&gt; &lt;extra\_params&gt; Example: param\_named\_auto worldViewProj WORLDVIEWPROJ\_MATRIX
506
507The allowed value codes and the meaning of extra\_params are detailed in [param\_indexed\_auto](#param_005findexed_005fauto).
508
509<a name="shared_005fparams_005fref"></a><a name="shared_005fparams_005fref-1"></a>
510
511## shared\_params\_ref
512
513This option allows you to reference shared parameter sets as defined in @ref Declaring-Shared-Parameters.
514@par
515Format: shared\_params\_ref &lt;shared\_set\_name&gt;
516@par
517Example: shared\_params\_ref mySharedParams
518
519The only required parameter is a name, which must be the name of an already defined shared parameter set. All named parameters which are present in the program that are also present in the shared parameter set will be linked, and the shared parameters used as if you had defined them locally. This is dependent on the definitions (type and array size) matching between the shared set and the program.
520
521# Shadows and Vertex Programs {#Shadows-and-Vertex-Programs}
522
523When using shadows (See [Shadows](@ref Shadows)), the use of vertex programs can add some additional complexities, because Ogre can only automatically deal with everything when using the fixed-function pipeline. If you use vertex programs, and you are also using shadows, you may need to make some adjustments.
524
525If you use **stencil shadows**, then any vertex programs which do vertex deformation can be a problem, because stencil shadows are calculated on the CPU, which does not have access to the modified vertices. If the vertex program is doing standard skeletal animation, this is ok (see section above) because Ogre knows how to replicate the effect in software, but any other vertex deformation cannot be replicated, and you will either have to accept that the shadow will not reflect this deformation, or you should turn off shadows for that object.
526
527If you use **texture shadows**, then vertex deformation is acceptable; however, when rendering the object into the shadow texture (the shadow caster pass), the shadow has to be rendered in a solid colour (linked to the ambient colour). You must therefore provide an alternative vertex program, so Ogre provides you with a way of specifying one to use when rendering the caster. Basically you link an alternative vertex program, using exactly the same syntax as the original vertex program link:
528
529```cpp
530shadow_caster_vertex_program_ref myShadowCasterVertexProgram
531{
532    param_indexed_auto 0 worldviewproj_matrix
533    param_indexed_auto 4 ambient_light_colour
534}
535```
536
537When rendering a shadow caster, Ogre will automatically use the alternate program. You can bind the same or different parameters to the program - the most important thing is that you bind **ambient\_light\_colour**, since this determines the colour of the shadow in modulative texture shadows. If you don’t supply an alternate program, Ogre will fall back on a fixed-function material which will not reflect any vertex deformation you do in your vertex program.
538
539In addition, when rendering the shadow receivers with shadow textures, Ogre needs to project the shadow texture. It does this automatically in fixed function mode, but if the receivers use vertex programs, they need to have a shadow receiver program which does the usual vertex deformation, but also generates projective texture coordinates. The additional program linked into the pass like this:
540
541```cpp
542shadow_receiver_vertex_program_ref myShadowReceiverVertexProgram
543{
544    param_indexed_auto 0 worldviewproj_matrix
545    param_indexed_auto 4 texture_viewproj_matrix
546}
547```
548
549For the purposes of writing this alternate program, there is an automatic parameter binding of ’texture\_viewproj\_matrix’ which provides the program with texture projection parameters. The vertex program should do it’s normal vertex processing, and generate texture coordinates using this matrix and place them in texture coord sets 0 and 1, since some shadow techniques use 2 texture units. The colour of the vertices output by this vertex program must always be white, so as not to affect the final colour of the rendered shadow.
550
551When using additive texture shadows, the shadow pass render is actually the lighting render, so if you perform any fragment program lighting you also need to pull in a custom fragment program. You use the shadow\_receiver\_fragment\_program\_ref for this:
552
553```cpp
554shadow_receiver_fragment_program_ref myShadowReceiverFragmentProgram
555{
556    param_named_auto lightDiffuse light_diffuse_colour 0
557}
558```
559
560You should pass the projected shadow coordinates from the custom vertex program. As for textures, texture unit 0 will always be the shadow texture. Any other textures which you bind in your pass will be carried across too, but will be moved up by 1 unit to make room for the shadow texture. Therefore your shadow receiver fragment program is likely to be the same as the bare lighting pass of your normal material, except that you insert an extra texture sampler at index 0, which you will use to adjust the result by (modulating diffuse and specular components).
561
562# Skeletal Animation in Vertex Programs {#Skeletal-Animation-in-Vertex-Programs}
563
564You can implement skeletal animation in hardware by writing a vertex program which uses the per-vertex blending indices and blending weights, together with an array of world matrices (which will be provided for you by Ogre if you bind the automatic parameter ’world\_matrix\_array\_3x4’). However, you need to communicate this support to Ogre so it does not perform skeletal animation in software for you. You do this by adding the following attribute to your vertex\_program definition:
565
566```cpp
567   includes_skeletal_animation true
568```
569
570When you do this, any skeletally animated entity which uses this material will forgo the usual animation blend and will expect the vertex program to do it, for both vertex positions and normals. Note that ALL submeshes must be assigned a material which implements this, and that if you combine skeletal animation with vertex animation (See [Animation](@ref Animation)) then all techniques must be hardware accelerated for any to be.
571
572
573# Morph Animation in Vertex Programs {#Morph-Animation-in-Vertex-Programs}
574
575You can implement morph animation in hardware by writing a vertex program which linearly blends between the first and second position keyframes passed as positions and the first free texture coordinate set, and by binding the animation\_parametric value to a parameter (which tells you how far to interpolate between the two). However, you need to communicate this support to Ogre so it does not perform morph animation in software for you. You do this by adding the following attribute to your vertex\_program definition:
576
577```cpp
578   includes_morph_animation true
579```
580
581When you do this, any skeletally animated entity which uses this material will forgo the usual software morph and will expect the vertex program to do it. Note that if your model includes both skeletal animation and morph animation, they must both be implemented in the vertex program if either is to be hardware acceleration. Note that ALL submeshes must be assigned a material which implements this, and that if you combine skeletal animation with vertex animation (See [Animation](#Animation)) then all techniques must be hardware accelerated for any to be.
582
583# Pose Animation in Vertex Programs {#Pose-Animation-in-Vertex-Programs}
584
585You can implement pose animation (blending between multiple poses based on weight) in a vertex program by pulling in the original vertex data (bound to position), and as many pose offset buffers as you’ve defined in your ’includes\_pose\_animation’ declaration, which will be in the first free texture unit upwards. You must also use the animation\_parametric parameter to define the starting point of the constants which will contain the pose weights; they will start at the parameter you define and fill ’n’ constants, where ’n’ is the max number of poses this shader can blend, i.e. the parameter to includes\_pose\_animation.
586
587```cpp
588   includes_pose_animation 4
589```
590
591Note that ALL submeshes must be assigned a material which implements this, and that if you combine skeletal animation with vertex animation (See [Animation](#Animation)) then all techniques must be hardware accelerated for any to be.
592
593# Vertex texture fetching in vertex programs {#Vertex-texture-fetching-in-vertex-programs}
594
595If your vertex program makes use of [Vertex Texture Fetch](#Vertex-Texture-Fetch), you should declare that with the ’uses\_vertex\_texture\_fetch’ directive. This is enough to tell Ogre that your program uses this feature and that hardware support for it should be checked.
596
597```cpp
598   uses_vertex_texture_fetch true
599```
600
601# Vertex Texture Fetch {#Vertex-Texture-Fetch}
602
603More recent generations of video card allow you to perform a read from a texture in the vertex program rather than just the fragment program, as is traditional. This allows you to, for example, read the contents of a texture and displace vertices based on the intensity of the colour contained within.
604
605<a name="Declaring-the-use-of-vertex-texture-fetching"></a>
606
607## Declaring the use of vertex texture fetching
608
609Since hardware support for vertex texture fetching is not ubiquitous, you should use the uses\_vertex\_texture\_fetch (See [Vertex texture fetching in vertex programs](#Vertex-texture-fetching-in-vertex-programs)) directive when declaring your vertex programs which use vertex textures, so that if it is not supported, technique fallback can be enabled. This is not strictly necessary for DirectX-targeted shaders, since vertex texture fetching is only supported in vs\_3\_0, which can be stated as a required syntax in your shader definition, but for OpenGL (GLSL), there are cards which support GLSL but not vertex textures, so you should be explicit about your need for them.
610
611<a name="Render-system-texture-binding-differences"></a>
612
613## Render system texture binding differences
614
615Unfortunately the method for binding textures so that they are available to a vertex program is not well standardised. As at the time of writing, Shader Model 3.0 (SM3.0) hardware under DirectX9 include 4 separate sampler bindings for the purposes of vertex textures. OpenGL, on the other hand, is able to access vertex textures in GLSL (and in assembler through NV\_vertex\_program\_3, although this is less popular), but the textures are shared with the fragment pipeline. I expect DirectX to move to the GL model with the advent of DirectX10, since a unified shader architecture implies sharing of texture resources between the two stages. As it is right now though, we’re stuck with an inconsistent situation.
616
617To reflect this, you should use the [binding\_type](#binding_005ftype) attribute in a texture unit to indicate which unit you are targeting with your texture - ’fragment’ (the default) or ’vertex’. For render systems that don’t have separate bindings, this actually does nothing. But for those that do, it will ensure your texture gets bound to the right processing unit.
618
619Note that whilst DirectX9 has separate bindings for the vertex and fragment pipelines, binding a texture to the vertex processing unit still uses up a ’slot’ which is then not available for use in the fragment pipeline. I didn’t manage to find this documented anywhere, but the nVidia samples certainly avoid binding a texture to the same index on both vertex and fragment units, and when I tried to do it, the texture did not appear correctly in the fragment unit, whilst it did as soon as I moved it into the next unit.
620
621<a name="Texture-format-limitations"></a>
622
623## Texture format limitations
624
625Again as at the time of writing, the types of texture you can use in a vertex program are limited to 1- or 4-component, full precision floating point formats. In code that equates to PF\_FLOAT32\_R or PF\_FLOAT32\_RGBA. No other formats are supported. In addition, the textures must be regular 2D textures (no cube or volume maps) and mipmapping and filtering is not supported, although you can perform filtering in your vertex program if you wish by sampling multiple times.
626
627<a name="Hardware-limitations"></a>
628
629## Hardware limitations
630
631As at the time of writing (early Q3 2006), ATI do not support texture fetch in their current crop of cards (Radeon X1n00). nVidia do support it in both their 6n00 and 7n00 range. ATI support an alternative called ’Render to Vertex Buffer’, but this is not standardised at this time and is very much different in its implementation, so cannot be considered to be a drop-in replacement. This is the case even though the Radeon X1n00 cards claim to support vs\_3\_0 (which requires vertex texture fetch).
632
633@page Runtime-Shader-Generation Runtime Shader Generation
634
635Writing shading programs is a common task when developing 3D based application. Most of the visual effects used by 3D based applications involve shader programs.
636Additionally with D3D11, support for fixed pipeline functionality was removed. Meaning you can only render objects using shaders.
637
638While @ref High-level-Programs offer you maximal control and flexibility over how your objects are rendered, writing and maintaining them is also a very time consuming task.
639
640Instead %Ogre can also automatically generate shaders on the fly, based on object material properties, scene setup and other user definitions. While the resulting shaders are less optimized, they offer the following advantages:
641
642* Save development time e.g. when your target scene has dynamic lights and the number changes, fog changes and the number of material attributes increases the total count of needed shaders dramatically. It can easily cross 100 and it becomes a time consuming development task.
643* Reusable code - once you've written the shader extension you can use it anywhere due to its independent nature.
644* Custom shaders extension library - enjoy the shared library of effects created by the community. Unlike hand written shader code, which may require many adjustments to be plugged into your own shader code, using the extensions library requires minimum changes.
645
646You have the choice between two different systems, which are implemented as components. You can select the one you need (or disable both) at compile time.
647
648* @subpage rtss <br />
649The RTSS is not another Uber shader with an exploding amount of @c \#ifdefs that make it increasingly difficult to add new functionality.
650Instead, it manages a set of opaque isolated components (SubRenderStates) where each implements a specific effect.
651These "effects" notable include full Fixed Function emulation. At the core these components are plain shader files providing a set of functions. The shaders are based on properties defined in @ref Material-Scripts.
652* @subpage hlms <br />
653This component allows you to manage shader variations of a specific shader template.
654This is a different take to the Uber shader management, but instead of using plain
655@c \#ifdefs it uses a custom, more powerful preprocessor language.
656Currently the HLMS can be only configured via a custom API and does not respect classical @ref Ogre::Material properties.
657
658# Historical background
659
660When the early graphic cards came into the market they contained a fixed but large set of functions with which you could influence how 3D object were rendered. These included influencing object positions using matrices, calculating the effect of textures on a pixel, calculating the effect of lights on vertices and so on. These set of functions and their implementation in hardware became later known as the graphic card fixed pipeline (or Fixed Function Pipeline).
661
662As graphic cards became more powerful and graphic application became more complex, a need for new ways to manipulate the rendering of 3D models became apparent. This need saw the introduction of shaders.
663
664Shaders are small custom made programs that run directly on the graphics card. Using these programs, one could replace the calculations that were made by the fixed pipeline and add new functionality. However there was a catch: If shaders are used on an object, the object can no longer use any of the functionality of the fixed pipeline. Any calculation that was used in the fixed pipeline needed to be recreated in the shaders. With early graphics applications this was not problematic. Shaders were simple and their numbers were kept low. However as applications grew in complexity this meant that the need for shaders grew as well. As a programmer you were left with 2 choices, both bad. Either create an exuberant amount of small shaders that soon became too many to effectively maintain. Or create an uber shader, a huge complex shader, that soon became too complex to effectively maintain as well.
665
666The RTSS seeks to fix those problems by automatically generating shaders based on the operations previously required from the fixed pipeline and new capabilities required by the user.
667
668With the introduction of the version 11 of Direct3D, a new reason for having an RTSS like system became apparent. With D3D11 support for fixed pipeline functionality was removed. Meaning, you can only render objects using shaders. The RTSS is an excellent tool for this purpose.