Future to the fantasy ★ ★
Titania
X3D Editor
Version
3.0

Cobweb 3.1

WebGL X3D Browser

Something special, something more!

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 typeGLSL variable type
X3DTexture2DNodesampler2D
X3DEnvironmentTextureNodesamplerCube

X3D Field types to GLSL data types

X3D field typeGLSL variable typeComment
SFBoolbool
SFColorvec3
SFColorRGBAvec4
SFDoublefloat
SFFloatfloat
SFImageint [ ](width, height, comp, array)
SFInt32int
SFMatrix3dmat3
SFMatrix3fmat3
SFMatrix4dmat4
SFMatrix4fmat4
SFNodesee node fields table
SFRotationvec4quaternion representation
SFStringnot supported
SFTimefloat
SFVec2dvec2
SFVec2fvec2
SFVec3dvec3
SFVec3fvec3
SFVec4dvec4
SFVec4fvec4
MFBoolbool [ ]
MFColorvec3 [ ]
MFColorRGBAvec4 [ ]
MFDoublefloat [ ]
MFFloatfloat [ ]
MFImageint [ ](width, height, comp, array, width ...)
MFInt32int [ ]
MFMatrix3dmat3 [ ]
MFMatrix3fmat3 [ ]
MFMatrix4dmat4 [ ]
MFMatrix4fmat4 [ ]
MFNodesee node fields table
MFRotationvec4 [ ]quaternion representation
MFStringnot supported
MFTimefloat [ ]
MFVec2dvec2 [ ]
MFVec2fvec2 [ ]
MFVec3dvec3 [ ]
MFVec3fvec3 [ ]
MFVec4dvec4 [ ]
MFVec4fvec4 [ ]

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.

TypeNameComment
uniform intx3d_GeometryTypePOINTS, LINES, 2D, 3D
uniform vec4x3d_ClipPlane [6]
uniform intx3d_FogTypeNO, LINEAR, EXPONENTIAL
uniform vec3x3d_FogColor
uniform floatx3d_FogVisibilityRange
uniform floatx3d_LinewidthScaleFactor
uniform boolx3d_ColorMaterialtrue if X3DColorNode attached
uniform boolx3d_Lightingtrue if X3DMaterialNode attached
uniform intx3d_LightType [8]NO, DIRECTIONAL, POINT, SPOT
uniform vec3x3d_LightColor [8]
uniform floatx3d_LightAmbientIntensity [8]
uniform floatx3d_LightIntensity [8]
uniform vec3x3d_LightAttenuation [8]
uniform vec3x3d_LightLocation [8]
uniform vec3x3d_LightDirection [8]
uniform floatx3d_LightBeamWidth [8]
uniform floatx3d_LightCutOffAngle [8]
uniform floatx3d_LightRadius [8]
uniform boolx3d_SeparateBackColortrue if back colors are available
uniform floatx3d_AmbientIntensity
uniform vec3x3d_DiffuseColor
uniform vec3x3d_SpecularColor
uniform vec3x3d_EmissiveColor
uniform floatx3d_Shininess
uniform floatx3d_Transparency
uniform floatx3d_BackAmbientIntensityset if x3d_SeparateBackColor is true
uniform vec3x3d_BackDiffuseColorset if x3d_SeparateBackColor is true
uniform vec3x3d_BackSpecularColorset if x3d_SeparateBackColor is true
uniform vec3x3d_BackEmissiveColorset if x3d_SeparateBackColor is true
uniform floatx3d_BackShininessset if x3d_SeparateBackColor is true
uniform floatx3d_BackTransparencyset if x3d_SeparateBackColor is true
uniform intx3d_TextureType [1]NO, TEXTURE_2D, CUBE_MAP_TEXTURE
uniform sampler2Dx3d_Texture2D [1]texture from Appearance texture field
uniform samplerCubex3d_CubeMapTexture [1]texture from Appearance texture field
uniform ivec4x3d_Viewport
uniform mat4x3d_ProjectionMatrix
uniform mat4x3d_ModelViewMatrix
uniform mat3x3d_NormalMatrix
uniform mat4x3d_TextureMatrix [1]
attribute vec4x3d_Coloravailable if X3DColorNode attached
attribute vec4x3d_TexCoord
attribute vec3x3d_Normal
attribute vec4x3d_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.

VariableTypeNameValueComment
x3d_GeometryTypeintx3d_GeometryPoints0appears on PointSet and Polypoint2D
intx3d_GeometryLines1appears on IndexedLineSet, LineSet and Polyline2D
intx3d_Geometry2D2appears on Geometry2D nodes
intx3d_Geometry3D3appears on Geometry3D nodes and other 3D nodes
x3d_ClipPlaneintx3d_MaxClipPlanes6if any clip plane is x3d_NoneClipPlane
it follows no other clip plane
vec4x3d_NoneClipPlaneimplementation dependend
x3d_FogTypeintx3d_NoneFog0
intx3d_LinearFog1
intx3d_ExponentialFog2
intx3d_MaxLights8if x3d_LightType[i] is x3d_NoneLight it follows no other light
x3d_LightTypeintx3d_NoneLight0
intx3d_DirectionalLight1
intx3d_PointLight2
intx3d_SpotLight3
intx3d_MaxTextures1if x3d_TextureType[i] is x3d_NoneTexture it follows no other texture
x3d_TextureTypeintx3d_NoneTexture0
intx3d_TextureType2D2
intx3d_TextureType3D3
intx3d_TextureTypeCubeMapTexture4
intx3d_ShadowSamples8