Extensible 3D (X3D)
Part 1: Architecture and base components

Programmable Shaders Component (Proposed)

--- X3D separator bar ---

cube 1. Introduction

1.1 Name

The name of this component is "Shaders". This name shall be used when referring to this component in the COMPONENT statement (see ISO FDIS 19775-1:200x 7.2.5.4 Component statement).

1.2 Overview

This clause describes the Shaders component of this part of ISO/IEC 19775. This includes how programmable shaders are specified and how they effect the visual appearance of geometry. Table 1 provides links to the major topics in this clause.

Table 1 — Topics

cube 2 Concepts

2.1 Overview

Programmable shading provides a method for end users to directly effect how an object is rendered, by providing a method of programmatically modifying sections of the rendering hardware. This allows for the replacement of the traditional fixed function pipeline of the graphics API. This allows a variety of visual effects that cannot be implemented using other node components in this specification.

Shaders are defined by two separate program pieces. One piece is used to modify the vertex values. They may also generate values that can be interpolated between vertex values. These are known as Vertex Shaders. The other piece is used to modify individual pixels as they are drawn to screen. These are known as fragment or pixel shaders. Although not currently defined, future extensions may include other types of shaders that fit into other places in the graphics pipeline

2.2 Shading Languages

2.2.1 Shader Language Options

Shader programs can be written in several languages. Each language is specific to the underlying rendering API. Typically a language for one API (eg Microsoft DirectX) is not usable in another rendering API (eg OpenGL) and therefore there shall be no requirement to implement a specific language. A browser implementing this component shall be required to support at least one shading language

Shaders are typically defined in a file that can be externally loaded, or internally described. Typically this means a separate file for each type of shader (fragment, vertex), though this is not required. Some formats are being developed that allow all shaders to be collected together into a single file and used directly by the rendering API. For these file types, a separate shader node is used called PackagedShader. This node is independent of the underlying rendering API, though the specific file format may be rendering API specific.

2.2.2 Node Representation

Each shading language option has a node that implements its functionality. Since each language is so different, it is not possible to define a single group of nodes that can group the entire capabilities offered. Each language has it's own set of nodes that pertain to that shading language only.

For each set of nodes for a given shading language, there are some language- specific behaviours. Mappings for each of the languages are defined in their own annex to this specification. Table 2 defines the nodes and which annex shall be used to define language-specific behaviours:

Table 2 — Mapping of Shader Languages to Definition Annex

Shading Language Nodes Annex
OpenGL GLSLang GLSLShader
GLSLShaderObject
Annex H, GLSLang
Direct3D HLSL HLSLShader Annex I, Microsoft HLSL
nVidia Cg CgShader Annex J, nVidia Cg

2.2.3 Selecting an appropriate Shader

Browsers are not expected to be able to handle all the different forms of shading languages. In fact, most are incompatible with any rendering API apart from the one they are defined with. A user that wishes to provide cross-platform support is therefore faced with a challenge of writing the same visual functionality in a number of different languages. On the implementation side, a browser has to select the shader that it can support.

To provide for both the user to specify a collection of options for the browser to select, and the browser the ability to choose the version it can run, a fallback mechanism is defined for the shader field of the Appearance node.

The shader field is an MFNode that defines the collection of shaders of various languages in the order of preference. The first node declared is the highest preference. If the browser does not support the language defined for the current preference level, the browser shall set the node's isSelected field output to FALSE, and move to the next preference. A browser implementation is required to support all nodes, but not required to be able to execute the contained script node. Ignored nodes shall remain a functional part of the scene graph, continuing to interact with the event model as required by the field access types.

When a shader is found that can be executed by the browser, it shall set the isSelected field output to TRUE.

A browser may select an appropriate shader on grounds other than just the shading language used. For example, if the hardware does not support some of the features requested, or the shader would run in software rather than hardware, are considered valid reasons for not selecting a shader to run.

2.2.4 Per-Vertex Attributes

Advanced vertex shaders will typically need to provide extra information on a per vertex basis. For example temperature information in an analysis system, or weighting values for a skin and bones system. Per-vertex attributes may be supplied for any geometry that extends X3DComposedGeometryNode (See 11.3.2 Rendering Component, X3DComposedGeometryNode). Both matrix and vector values may be supplied on a per-vertex basis through nodes that are extended from X3DVertexAttributeNode.

Each shading language uses a different method of mapping per-vertex attributes through to the user-provided shading language code. The definition of how to interpret the name field value to the individual shading language file is defined in the language-specific annex (see Table 2 for more information).

Per vertex attributes are mapped 1:1 to each vertex value. When used in a X3DComposedGeometryNode, the number of values defined in the node containing the attribute values shall be identical to the number of coordinate values specified for the geometry node. If the number of values do not match, the visual result is implementation-specific

2.2.5 Per-Object Attributes

Shaders will almost always need to provide some specific per-object values, for example, the colour of the light. The most common name for these are uniform variables These are defined using custom field definitions that allow for objects to be set as required. The placement of these fields depends on the shading language itself, as the amount of customisablity is dependent on the shading language.

Field names shall be mapped to the shading API as the uniform variable name of the identical name in the shader file. Note that some shading languages cannot handle the full UTF-8 character set required by this International Standard.

For fields of type SFNode or MFNode the mapping to the shading language is dependent on the individual shading language. Consult the appropriate language binding annex for further specification of the required behaviour.

2.2.6 Handling Errors

Sometimes shader programs are not valid syntax, or the environment does not contain enough information for the shader to render. It is recommended that implementations track errors during all stages of the shader process and display them to the browser's console.

A shader that fails during runtime or during the compilation or validation stages shall not run. A browser shall use the rendering API's default behaviour for this situation. If a user requires some fallback behaviour, such as the browser not supporting the shader capabilities requested, then they should make use of other nodes such as LoadSensors, Scripts and Switch to select the required visual output

2.3 Interaction with Other Nodes and Components

2.3.1 Overview

Programmable shaders typically replace large amounts of functionality that would be traditionally implemented by the browser. The effect each language has varies on the amount of processing that the user will be required to perform. For example, some languages will completely disable anything that would be automatically generated (eg texture coordinates, normals) while others may not. A reasonable assumption is that everything is disabled for any geometry that has a shader associated with it. Each language shading definition annex will refine exactly the semantics that can be expected of the underlying rendering API, and by implication, the browser.

2.3.2 Lighting

If the user provides a fragment shader then the shader shall be responsible for all lighting. The lighting definitions in 17 Lighting Component shall be ignored. Where possible, all of the lighting information such as the currently set lights, material colours and textures shall be made available to the shader. Some rendering APIs may not be able to make available all of this information. In this case, it is acceptable to provide alternative mapping hints as part of the node definition. See the individual shading language annexes for more information.

2.3.3 Geometry

As a vertex shader may move the vertex from it's original location in the local coordinate system, it can have many large-scale side effects. One of the most severe problems will be that the browser implementation may have no idea where the final geometry is placed. Any action that relies on knowing the exact position of vertices may fail to act properly. In particular, terrain following, collision detection and sensors can be adversely effected.

Because of this ability to shift a vertex in world space, it is recommended that if a user requires this ability, that they provide a means of giving a rough approximation of the geometry to the browser. This may be through either setting an explicit bounding box on the containing Shape node or by providing the source geometry as close to the final output shape as possible. For example, a fuzzy rabbit shape would start with the source vertices in the shape of the base rabbit geometry.

2.3.4 LoadSensor

A shader is considered loaded when the source for the shader program has been downloaded successfully. A shader is considered valid when the downloaded file has been compiled and registered with the rendering API, which considers it a valid object.

2.4 Conformance

2.4.1 Component Support

An implementation shall indicate support for this component if and only if the user's particular hardware is capable of supporting this component, either through direct hardware support or software emulation. If the user's machine is not capable of supporting this component then it shall indicate a failure by stopping at the appropriate PROFILE or COMPONENT statement of the file, in accordance with 7.2.5.3 PROFILE Statement or 7.2.5.4 COMPONENT Statement.

2.4.2 Node Support

A conformant browser for this component shall support all the nodes at a given level. However, they are not required to support the corresponding shading language for that node. If a browser is not supporting the language, then the nodes that provide access to that language shall be read and ignored. These ignored nodes shall still exist as part of the X3D scene graph, and shall still honour the X3D event model. For example, any inputOutput fields shall still be required to implement output events if a value is written to the input.

2.4.3 Language Support

A browser conformant to this component shall support at least one shading language. See Table 2 for the definition of each language and it's requirements.

2.4.4 Scene Graph Interaction

A shader containing a vertex shader shall be required to be conformant only to either the explicit bounding boxes or the original source goemetry definition. It is not required to obtain the output vertex information for use within the scene graph.

cube 3 Abstract Types

3.1 X3DProgrammableShaderObject

X3DProgrammableShaderObject {
}

This abstract node type is the base type for all node types which specify arbitrary fields for interfacing with per-object attribute values.

A concrete X3DProgrammableShaderObject node instance is used to program behaviour for a shader in a scene. The shader is able to receive and process events that are sent to it. Each event that can be received shall be declared in the shader node using the same syntax as is used in a prototype definition:

inputOnly type name
The type can be any of the standard X3D fields (as defined in 5 Field type reference). Name shall be an identifier that is unique for this shader node and is used to map the value to the shader program's uniform variable of the same name. If a shader program does not have a matching uniform variable, then the field value is ignored.

OutputOnly fields are not required to generate output events from a shader. Current hardware shader technology does not support this capability, though future versions may.

It is recommended that user-defined field or event names defined in shader nodes follow the naming conventions described in 2.[I19775-2]

3.2 X3DShaderNode

X3DShaderNode : X3DAppearanceChildNode {
  SFNode   [in,out] metadata  NULL [X3DMetadataObject]
  SFBool   [out]    isSelected
  SFBool   [out]    isValid
  SFBool   [in]     activate
  SFString []       language  ""   ["CG"|"GLSL"|"HLSL"|"FX"...]
}

This abstract node type is the base type for all node types which specify a programmable shader.

The isSelected output field is used to indicate that this shader instance is the one selected for use by the browser. A TRUE value indicates that this instance is in use. A FALSE value indicates it is not in use. For the rules on when a browser decides to select a particular node instance, see 2.3.5

The isValid field is used to indicate whether the current shader objects can be run as a shader program. For example, there are no syntax errors and the hardware can support all the required features. The definition of this field may also add additional semantics on a per-language basis.

The language field is used to indicate to the browser what shading language is used for the source file(s). This field may be used as a hint for the browser if the shading language is not immediately determinable from the source - for example a generic MIME type of text/plain is returned. A browser may use this field for determining which node instance will be selected and to ignore lanugages that it is not capable of supporting. Five basic types are defined for this specification, though more may be made available in future revisions of this specification. Browser implementors may also provide additional extension types by following the naming convention rules defined in ????

3.3 X3DVertexAttributeNode

X3DVertexAttributeNode : X3DGeometricPropertyNode {
  SFNode   [in,out] metadata NULL [X3DMetadataObject]
  SFString []       name "" 
}

This abstract node type is the base type for all node types which specify per-vertex attribute information to the shader.

The name field describes a name that is mapped to the shading language-specific name for describing per-vertex data. See the appropriate annex for language-specific binding information.

cube 4 Node reference

4.1 FloatVertexAttribute

FloatVertexAttribute : X3DVertexAttributeNode {
  SFNode   [in,out] metadata      NULL [X3DMetadataObject]
  MFFloat  [in,out] value  		  []   (-∞,∞)
  SFString []       name          ""
  SFInt32  []       numComponents 4    [1..4]
}

Defines a set of per-vertex single precision floating point attributes.

The numComponents field defines how many consective floating point values should be grouped together per vertex. The length of the value field shall be a multiple of numComponents.

The value field defines an arbitrary collection of floating point values that will be passed to the shader as per-vertex information. The specific type mapping to the individual shading language data types shall be found in the appropriate language-specific annex. See Table 2 for the appropriate annex to use.

4.2 ComposedShader

ComposedShader : X3DShaderNode, X3DProgrammableShaderObject {
  SFNode   [in,out] metadata NULL [X3DMetadataObject]
  MFNode   [in,out] parts  []     [ShaderPart]
  SFBool   [out]    isSelected
  SFBool   [out]    isValid
  SFBool   [in]     activate
  SFString []       language  ""  

  # And any number of:
  fieldType []       fieldName
  fieldType [in]     fieldName
  fieldType [out]    fieldName
  fieldType [in,out] fieldName
}

The ComposedShader node defines a shader where the individual source files are not individually programmable. All access to the shading capabilities is defined through a single interface, which applies to all parts. An example of this is the OpenGL Shading Language.

The isValid field adds an additional semantic of indicating whether the current shader parts can be linked together to form a complete valid shader program.

The activate field is used to force the shader to activate the contained objects. The conditions under which a activate may be required are described in X.5 Event Model.

4.3 ShaderPart

ShaderPart : X3DNode, X3DUrlObject {
  SFNode   [in,out] metadata NULL       [X3DMetadataObject]
  MFString [in,out] url      []
  SFString []       type     "VERTEX"   ["VERTEX","FRAGMENT"]
}

The ShaderPart node defines the source for a single object to be used by a ComposedShader node. The source is not required to be a complete shader for all of the vertex/fragment processing.

The type field indicates whether this object shall be compiled as a vertex or fragment shader, or other future-defined type.

The shader source is read from the URL specified by the url field. When the url field contains no values ([]), this object instance is ignored. Details on the url field can be found in 19775-1:200x 9.2.1 URLs. Shader source files shall be plain text ASCII encoded (MIME type text/plain) and interpreted according to the type field.

4.4 ProgramShader

ProgramShader : X3DShaderNode {
  SFNode   [in,out] metadata  NULL [X3DMetadataObject]
  MFNode   [in,out] programs  []   [ShaderProgram]
  SFBool   [out]    isSelected
  SFBool   [out]    isValid
  SFBool   [in]     activate
  SFString []       language  ""   ["CG"|"GLSL"|"HLSL"]
}

The ProgramShader node defines a shader that can consist of one or more individually programmable, self contained pieces. Each piece, represented by a ShaderProgram node, shall contain a self-contained source that does not rely on any other source file and can manage one part of the programmable pipeline (eg vertex or fragment processing).

The programs field consists of zer or more ShaderProgram node instances. In general, only two ShaderProgram instances will be needed - one each for vertex and fragment processing. Each language binding shall refine the required behaviour for processing this field

The isValid field may add an additional semantic to indicate whether all parts are available. For example, Microsoft's HLSL requires that you shall provide both vertex and fragment programs and that it is an error to provide one and not the other.

4.5 ShaderProgram

ShaderProgram : X3DNode, X3DUrlObject, X3DProgrammableShaderObject {
  SFNode   [in,out] metadata NULL       [X3DMetadataObject]
  MFString [in,out] url      []
  SFString []       type     "VERTEX"   ["VERTEX","FRAGMENT"]

  # And any number of:
  fieldType []       fieldName
  fieldType [in]     fieldName
  fieldType [out]    fieldName
  fieldType [in,out] fieldName
}

The ShaderProgram node provides the source and interface to a self contained program that occupies one part of the rendering process: either a vertex or fragment shader.

The shader source is read from the URL specified by the url field. When the url field contains no values ([]), this object instance is ignored. Details on the url field can be found in 19775-1:200x 9.2.1 URLs. Shader source files shall be plain text ASCII encoded (MIME type text/plain) and interpreted according to the containing node's language definition.

4.6 Matrix3VertexAttribute

Matrix3VertexAttribute : X3DVertexAttributeNode {
  SFNode     [in,out] metadata NULL [X3DMetadataObject]
  MFMatrix3f [in,out] value    []   (-∞,∞)
  SFString   []       name     ""
}

Defines a set of per-vertex 3x3 matrix attributes.

The value field defines an arbitrary collection of matrix values that will be passed to the shader as per-vertex information. The specific type mapping to the individual shading language data types shall be found in the appropriate language-specific annex. See Table 2 for the appropriate annex to use.

4.7 Matrix4VertexAttribute

Matrix4VertexAttribute : X3DVertexAttributeNode {
  SFNode     [in,out] metadata NULL [X3DMetadataObject]
  MFMatrix4f [in,out] value    []   (-∞,∞)
  SFString   []       name     ""
}

Defines a set of per-vertex 4x4 matrix attributes.

The value field defines an arbitrary collection of matrix values that will be passed to the shader as per-vertex information. The specific type mapping to the individual shading language data types shall be found in the appropriate language-specific annex. See Table 2 for the appropriate annex to use.

4.8 PackagedShader

PackagedShader : X3DShaderNode, X3DUrlObject, X3DProgrammableShaderObject {
  SFNode   [in,out] metadata NULL [X3DMetadataObject]
  MFString [in,out] url      []
  SFBool   [out]    isSelected
  SFBool   [out]    isValid
  SFBool   [in]     activate
  SFString []       language ""

  # And any number of:
  fieldType []       fieldName
  fieldType [in]     fieldName
  fieldType [out]    fieldName
  fieldType [in,out] fieldName
}

A PackagedShader node describes a single file that may contain a number of shaders and combined effects. An example of this type of shader is the the Microsoft .fx file format.

The shader source is read from the URL specified by the url field. When the url field contains no values ([]), this object instance is ignored. Details on the url field can be found in 19775-1:200x 9.2.1 URLs. No file formats are required to be supported for this node.

The language field may be used to optionally determine the language type if no MIME-type information is available.

cube 5 Support Levels

The Shaders component defines a single level of support as specified in Table 3.

Table 3 — Shader component support levels

LevelPrequisitesNodes/FeaturesSupport
Level 1 Core 1
Grouping 1
Shape 1
Rendering 1
X3DProgrammableShaderObject n/a
X3DShaderNode n/a
X3DVertexAttributeNode n/a
FloatVertexAttribute All fields fully supported
ComposedShader All fields fully supported
ShaderPart All fields fully supported
ProgramShader All fields fully supported
ShaderProgram All fields fully supported
Matrix3VertexAttribute All fields fully supported
Matrix4VertexAttribute All fields fully supported
PackagedShader All fields fully supported
--- X3D separator bar ---
[ Xj3D Homepage | Xj3D @ Web3d | Screenshots | Dev docs | Dev Releases | Contributors | Getting Started ]
Last updated: $Date: 2004-09-16 19:52:10 $