# Custom Shaders

X3D WebGL shaders are small programs written in a specialized language called GLSL similar to C. It is strongly typed and includes basic data types such as float, int, and bool, and additional vector data types, which are useful for graphics programming: vec2, vec3, and vec4. A »vector« in this context is essentially a fixed-length array. GLSL vectors contain floats by default, but you can specify int vectors as ivec2 and bool vectors as bvec2, for example.

There are two kinds of shaders: vertex shaders and fragment shaders.

- Vertex shaders manipulate the vertices of polygons (aka the points that define their shape). This gives you control over the shape and position of things in your rendering. At render time, your vertex shader is run on every vertex.
- Fragment shaders are also known as pixel shaders, and they determine how the pixels between your vertices look. This is useful for things like lighting or gradients.

You can pass variables into shaders, either as uniforms or as attributes. Uniforms are constant across all vertices. Attributes can vary from vertex to vertex. These values are supplied by X3D. When referenced in shaders, they are constants - you can't reassign uniform or attributes in GLSL.

Let's write some simple shaders.

# Example

Download »Water Quality« example from GitHub.

# Shaders and Shader Definition

WebGL uses the GLSL language to write shaders that can be run across all browsers. With Cobweb you create your own shader using ComposedShader and ShaderPart nodes and than attach the ComposedShader to the shader field of an Appearance node and that is a child's play with Titania.

## X3D

#X3D V3.3 utf8

Transform {

children Shape {

appearance Appearance {

material ImageTexture {

url "image.png"

}

shaders DEF Shader ComposedShader {

inputOnly SFFloat set_time

language "GLSL"

parts [

ShaderPart {

url "data:text/plain,

// Vertex Shader

uniform float set_time

...

"

}

ShaderPart {

type "FRAGMENT"

url "data:text/plain,

// Fragment Shader

...

"

}

]

}

}

geometry ElevationGrid { }

}

}

Once the X3D is defined we can now write the vertex and the fragment shader source. This is a simple example where a texture is applied to the geometry.

## Vertex Shader

uniform mat4 x3d_TextureMatrix [x3d_MaxTextures];

uniform mat4 x3d_ModelViewMatrix;

uniform mat4 x3d_ProjectionMatrix;

attribute vec4 x3d_TexCoord;

attribute vec4 x3d_Vertex;

varying vec4 texCoord;

void

main()

{

texCoord = x3d_TextureMatrix [0] * x3d_TexCoord;

gl_Position = x3d_ProjectionMatrix * x3d_ModelViewMatrix * x3d_Vertex;

}

## Fragment Shader

uniform sampler2D x3d_Texture2D;

varying vec4 texCoord;

void

main ()

{

gl_FragColor = texture2D (x3d_Texture2D, vec2 (texCoord));

}

# Lighting and Transparency

Lighting is enabled if a Material node is available. If a transparent Material node is attached to the Appearance of the Shape node, the Shape is treated as transparent and thus the shader.

# Data type mapping

A ComposedShader node provides the capability to define custom fields like the Script node it does, these fields are then mapped to GLSL uniform variables. They are automatically updated and can be of any access type (initializeOnly, inputOnly, outputOnly or inputOutput).

## Node fields

X3D texture type | GLSL variable type |
---|---|

X3DTexture2DNode | sampler2D |

X3DEnvironmentTextureNode | samplerCube |

## X3D Field types to GLSL data types

X3D field type | GLSL variable type | Comment |
---|---|---|

SFBool | bool | |

SFColor | vec3 | |

SFColorRGBA | vec4 | |

SFDouble | float | |

SFFloat | float | |

SFImage | int [ ] | (width, height, comp, array) |

SFInt32 | int | |

SFMatrix3d | mat3 | |

SFMatrix3f | mat3 | |

SFMatrix4d | mat4 | |

SFMatrix4f | mat4 | |

SFNode | see node fields table | |

SFRotation | mat3 | 3x3 matrix representation |

SFString | not supported | |

SFTime | float | |

SFVec2d | vec2 | |

SFVec2f | vec2 | |

SFVec3d | vec3 | |

SFVec3f | vec3 | |

SFVec4d | vec4 | |

SFVec4f | vec4 | |

MFBool | bool [ ] | |

MFColor | vec3 [ ] | |

MFColorRGBA | vec4 [ ] | |

MFDouble | float [ ] | |

MFFloat | float [ ] | |

MFImage | int [ ] | (width, height, comp, array, width ...) |

MFInt32 | int [ ] | |

MFMatrix3d | mat3 [ ] | |

MFMatrix3f | mat3 [ ] | |

MFMatrix4d | mat4 [ ] | |

MFMatrix4f | mat4 [ ] | |

MFNode | see node fields table | |

MFRotation | mat3 [ ] | 3x3 matrix representation |

MFString | not supported | |

MFTime | float [ ] | |

MFVec2d | vec2 [ ] | |

MFVec2f | vec2 [ ] | |

MFVec3d | vec3 [ ] | |

MFVec3f | vec3 [ ] | |

MFVec4d | vec4 [ ] | |

MFVec4f | vec4 [ ] |

# Built-in Variables

A ComposedShader defines a number of special variables for the various shader stages. These built-in variables have special properties. They are usually for communicating with certain fixed-functionality. By convention, all predefined variables start with "x3d_"; no user-defined variables may start with this.

Type | Name | Comment |
---|---|---|

uniform int | x3d_GeometryType | POINTS, LINES, 2D, 3D |

uniform vec4 | x3d_ClipPlane [6] | |

uniform int | x3d_FogType | NO, LINEAR, EXPONENTIAL |

uniform vec3 | x3d_FogColor | |

uniform float | x3d_FogVisibilityRange | |

uniform float | x3d_LinewidthScaleFactor | |

uniform bool | x3d_ColorMaterial | true if X3DColorNode attached |

uniform bool | x3d_Lighting | true if X3DMaterialNode attached |

uniform int | x3d_LightType [8] | NO, DIRECTIONAL, POINT, SPOT |

uniform vec3 | x3d_LightColor [8] | |

uniform float | x3d_LightAmbientIntensity [8] | |

uniform float | x3d_LightIntensity [8] | |

uniform vec3 | x3d_LightAttenuation [8] | |

uniform vec3 | x3d_LightLocation [8] | |

uniform vec3 | x3d_LightDirection [8] | |

uniform float | x3d_LightBeamWidth [8] | |

uniform float | x3d_LightCutOffAngle [8] | |

uniform float | x3d_LightRadius [8] | |

uniform bool | x3d_SeparateBackColor | true if back colors are available |

uniform float | x3d_AmbientIntensity | |

uniform vec3 | x3d_DiffuseColor | |

uniform vec3 | x3d_SpecularColor | |

uniform vec3 | x3d_EmissiveColor | |

uniform float | x3d_Shininess | |

uniform float | x3d_Transparency | |

uniform float | x3d_BackAmbientIntensity | set if x3d_SeparateBackColor is true |

uniform vec3 | x3d_BackDiffuseColor | set if x3d_SeparateBackColor is true |

uniform vec3 | x3d_BackSpecularColor | set if x3d_SeparateBackColor is true |

uniform vec3 | x3d_BackEmissiveColor | set if x3d_SeparateBackColor is true |

uniform float | x3d_BackShininess | set if x3d_SeparateBackColor is true |

uniform float | x3d_BackTransparency | set if x3d_SeparateBackColor is true |

uniform int | x3d_TextureType [1] | NO, TEXTURE_2D, CUBE_MAP_TEXTURE |

uniform sampler2D | x3d_Texture2D [1] | texture from Appearance texture field |

uniform samplerCube | x3d_CubeMapTexture [1] | texture from Appearance texture field |

uniform ivec4 | x3d_Viewport | |

uniform mat4 | x3d_ProjectionMatrix | |

uniform mat4 | x3d_ModelViewMatrix | |

uniform mat3 | x3d_NormalMatrix | |

uniform mat4 | x3d_TextureMatrix [1] | |

attribute vec4 | x3d_Color | available if X3DColorNode attached |

attribute vec4 | x3d_TexCoord | |

attribute vec3 | x3d_Normal | |

attribute vec4 | x3d_Vertex | required |

# Built-in Constants

Some built-in variables are enumerated and have special values and meanings. The following table list all of them and their corresponding values. Note: as of version 1.27 these constant are buit-in.

Variable | Type | Name | Value | Comment |
---|---|---|---|---|

x3d_GeometryType | int | x3d_GeometryPoints | 0 | appears on PointSet and Polypoint2D |

int | x3d_GeometryLines | 1 | appears on IndexedLineSet, LineSet and Polyline2D | |

int | x3d_Geometry2D | 2 | appears on Geometry2D nodes | |

int | x3d_Geometry3D | 3 | appears on Geometry3D nodes and other 3D nodes | |

x3d_ClipPlane | int | x3d_MaxClipPlanes | 6 | if any clip plane is x3d_NoneClipPlane it follows no other clip plane |

vec4 | x3d_NoneClipPlane | implementation dependend | ||

x3d_FogType | int | x3d_NoneFog | 0 | |

int | x3d_LinearFog | 1 | ||

int | x3d_ExponentialFog | 2 | ||

int | x3d_MaxLights | 8 | if x3d_LightType[i] is x3d_NoneLight it follows no other light | |

x3d_LightType | int | x3d_NoneLight | 0 | |

int | x3d_DirectionalLight | 1 | ||

int | x3d_PointLight | 2 | ||

int | x3d_SpotLight | 3 | ||

int | x3d_MaxTextures | 1 | if x3d_TextureType[i] is x3d_NoneTexture it follows no other texture | |

x3d_TextureType | int | x3d_NoneTexture | 0 | |

int | x3d_TextureType2D | 2 | ||

int | x3d_TextureType3D | 3 | ||

int | x3d_TextureTypeCubeMapTexture | 4 | ||

int | x3d_ShadowSamples | 8 |